diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/AppList.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/AppList.kt index 0ce248d9..29887544 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/AppList.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/AppList.kt @@ -23,6 +23,9 @@ import androidx.compose.ui.unit.dp import me.nya_n.notificationnotifier.model.InstalledApp import me.nya_n.notificationnotifier.ui.R import me.nya_n.notificationnotifier.ui.theme.AppTheme +import me.nya_n.notificationnotifier.ui.util.LocalAnimatedVisibilityScope +import me.nya_n.notificationnotifier.ui.util.LocalSharedTransitionScope +import me.nya_n.notificationnotifier.ui.util.iconSharedTransitionKey @Composable fun AppList( @@ -36,7 +39,12 @@ fun AppList( items( count = items.size, key = { "($it)${items[it]}" }, - itemContent = { AppListItem(app = items[it], onAppSelected = onAppSelected) } + itemContent = { + AppListItem( + app = items[it], + onAppSelected = onAppSelected + ) + } ) } } @@ -47,7 +55,10 @@ fun AppListItem( app: InstalledApp, onAppSelected: (InstalledApp) -> Unit ) { + val sharedTransitionScope = LocalSharedTransitionScope.current + val animatedVisibilityScope = LocalAnimatedVisibilityScope.current val interactionSource = remember { MutableInteractionSource() } + Box( modifier = Modifier .fillMaxWidth() @@ -62,7 +73,20 @@ fun AppListItem( ) { GrayScaleAppIcon( app = app, - modifier = Modifier.size(56.dp), + modifier = Modifier + .size(56.dp) + .then( + if (sharedTransitionScope != null && animatedVisibilityScope != null) { + with(sharedTransitionScope) { + Modifier.sharedElement( + rememberSharedContentState(key = app.iconSharedTransitionKey), + animatedVisibilityScope = animatedVisibilityScope + ) + } + } else { + Modifier + } + ), isInListView = true ) Box( diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/AppScaffold.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/AppScaffold.kt index a5ff58da..2461eca1 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/AppScaffold.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/AppScaffold.kt @@ -18,17 +18,13 @@ import me.nya_n.notificationnotifier.ui.theme.AppTheme @Composable fun AppScaffold( snackbarHostState: SnackbarHostState, - hasBackContent: Boolean = false, - onBack: () -> Unit = { }, + onBack: (() -> Unit)? = null, bottomBar: @Composable () -> Unit = { }, content: @Composable (PaddingValues) -> Unit ) { Scaffold( topBar = { - TopBar( - hasBackContent = hasBackContent, - onBack = onBack - ) + TopBar(onBack = onBack) }, bottomBar = bottomBar, containerColor = MaterialTheme.colorScheme.secondary, diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/TopBar.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/TopBar.kt index 4b0c100f..cfe6e221 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/TopBar.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/common/TopBar.kt @@ -18,8 +18,7 @@ import me.nya_n.notificationnotifier.ui.theme.AppTheme @OptIn(ExperimentalMaterial3Api::class) @Composable fun TopBar( - hasBackContent: Boolean = false, - onBack: () -> Unit = { } + onBack: (() -> Unit)? = null ) { TopAppBar( title = { @@ -29,10 +28,11 @@ fun TopBar( ) }, navigationIcon = { - if (hasBackContent) { - IconButton( - onClick = onBack - ) { + IconButton( + onClick = onBack ?: { }, + enabled = onBack != null + ) { + if (onBack != null) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back) @@ -59,7 +59,6 @@ private fun TopBarPreview() { private fun SubContentTopBarPreview() { AppTheme { TopBar( - hasBackContent = true, onBack = { } ) } diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/app/AppScreen.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/app/AppScreen.kt index 3170eefe..b90889ba 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/app/AppScreen.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/app/AppScreen.kt @@ -3,9 +3,11 @@ package me.nya_n.notificationnotifier.ui.screen.app import android.content.Intent import android.provider.Settings import androidx.activity.compose.LocalActivity +import androidx.compose.animation.SharedTransitionLayout import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOutHorizontally import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -16,14 +18,13 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.google.gson.Gson -import me.nya_n.notificationnotifier.model.InstalledApp import me.nya_n.notificationnotifier.ui.common.RequireNotificationPermissionDialog import me.nya_n.notificationnotifier.ui.common.RequirePackageVisibilityDialog import me.nya_n.notificationnotifier.ui.screen.about.AboutScreen -import me.nya_n.notificationnotifier.ui.screen.detail.DetailScreen import me.nya_n.notificationnotifier.ui.screen.license.LicenseScreen import me.nya_n.notificationnotifier.ui.screen.main.MainScreen import me.nya_n.notificationnotifier.ui.theme.AppTheme +import me.nya_n.notificationnotifier.ui.util.LocalSharedTransitionScope import org.koin.androidx.compose.koinViewModel import java.net.URLEncoder @@ -75,35 +76,33 @@ fun AppScreen( } } - NavHost( - navController = navController, - startDestination = Screen.Main.name, - enterTransition = { - slideInHorizontally(initialOffsetX = { it }) - }, - exitTransition = { - slideOutHorizontally(targetOffsetX = { -it }) - }, - popEnterTransition = { - slideInHorizontally(initialOffsetX = { -it }) - }, - popExitTransition = { - slideOutHorizontally(targetOffsetX = { it }) - }, - ) { - composable(Screen.Main.route) { MainScreen(navController) } - composable(Screen.License.route) { LicenseScreen(navController) } - composable(Screen.Detail.route) { - val app = Gson().fromJson( - it.arguments?.getString("app"), - InstalledApp::class.java - ) - DetailScreen( - navController = navController, - app = app - ) + SharedTransitionLayout { + NavHost( + navController = navController, + startDestination = Screen.Main.name, + enterTransition = { + slideInHorizontally(initialOffsetX = { it }) + }, + exitTransition = { + slideOutHorizontally(targetOffsetX = { -it }) + }, + popEnterTransition = { + slideInHorizontally(initialOffsetX = { -it }) + }, + popExitTransition = { + slideOutHorizontally(targetOffsetX = { it }) + }, + ) { + composable(Screen.Main.route) { + CompositionLocalProvider( + LocalSharedTransitionScope provides this@SharedTransitionLayout + ) { + MainScreen(navController = navController) + } + } + composable(Screen.License.route) { LicenseScreen(navController) } + composable(Screen.About.route) { AboutScreen() } } - composable(Screen.About.route) { AboutScreen() } } } } @@ -113,7 +112,10 @@ sealed class Screen( val name: String, private val args: List = emptyList() ) { - data object Main : Screen("main") + data object Main : Screen("main") { + data object Targets : Screen("targets") + data object Detail : Screen("detail", listOf("app")) + } data object License : Screen("license") data object Detail : Screen("detail", listOf("app")) data object About : Screen("about") diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/detail/DetailScreen.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/detail/DetailScreen.kt index debfb038..e109b188 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/detail/DetailScreen.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/detail/DetailScreen.kt @@ -36,12 +36,14 @@ import androidx.navigation.NavController import me.nya_n.notificationnotifier.model.InstalledApp import me.nya_n.notificationnotifier.ui.R import me.nya_n.notificationnotifier.ui.common.AppOutlinedButton -import me.nya_n.notificationnotifier.ui.common.AppScaffold import me.nya_n.notificationnotifier.ui.common.Category import me.nya_n.notificationnotifier.ui.common.GrayScaleAppIcon import me.nya_n.notificationnotifier.ui.common.SnackbarMessage import me.nya_n.notificationnotifier.ui.theme.AppColors import me.nya_n.notificationnotifier.ui.theme.AppTheme +import me.nya_n.notificationnotifier.ui.util.LocalAnimatedVisibilityScope +import me.nya_n.notificationnotifier.ui.util.LocalSharedTransitionScope +import me.nya_n.notificationnotifier.ui.util.iconSharedTransitionKey import org.koin.androidx.compose.koinViewModel import org.koin.core.parameter.parametersOf @@ -61,12 +63,8 @@ fun DetailScreen( viewModel.messageShown() } DetailContent( - snackbarHostState = snackbarHostState, app = app, condition = uiState.condition, - onBack = { - navController.popBackStack() - }, onDeleteApp = { viewModel.deleteTarget() navController.previousBackStackEntry?.apply { @@ -81,27 +79,21 @@ fun DetailScreen( /** 詳細画面のコンテンツ本体 */ @Composable fun DetailContent( - snackbarHostState: SnackbarHostState, app: InstalledApp, condition: String, - onBack: () -> Unit, onDeleteApp: () -> Unit, onConditionChanged: (String) -> Unit ) { - AppScaffold( - snackbarHostState = snackbarHostState, - hasBackContent = true, - onBack = onBack + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 20.dp), ) { - Column( - modifier = Modifier - .fillMaxSize() - .padding(it) - .padding(horizontal = 20.dp), - ) { - AppInfo(app, onDeleteApp) - NotificationSetting(condition, onConditionChanged) - } + AppInfo( + app = app, + onDeleteApp = onDeleteApp + ) + NotificationSetting(condition, onConditionChanged) } } @@ -113,6 +105,9 @@ private fun AppInfo( app: InstalledApp, onDeleteApp: () -> Unit ) { + val sharedTransitionScope = LocalSharedTransitionScope.current + val animatedVisibilityScope = LocalAnimatedVisibilityScope.current + Category(name = stringResource(id = R.string.app_info)) Box( modifier = Modifier.padding(vertical = 20.dp) @@ -120,7 +115,20 @@ private fun AppInfo( Row { GrayScaleAppIcon( app = app, - modifier = Modifier.size(80.dp), + modifier = Modifier + .size(80.dp) + .then( + if (sharedTransitionScope != null && animatedVisibilityScope != null) { + with(sharedTransitionScope) { + Modifier.sharedElement( + rememberSharedContentState(key = app.iconSharedTransitionKey), + animatedVisibilityScope = animatedVisibilityScope + ) + } + } else { + Modifier + } + ), isInListView = false ) Box( @@ -188,13 +196,10 @@ private fun NotificationSetting( @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) @Composable private fun DetailPreview() { - val snackbarHostState = remember { SnackbarHostState() } AppTheme { DetailContent( - snackbarHostState = snackbarHostState, app = InstalledApp("Sample App Name", "example.sample.test"), condition = "^.*$", - onBack = { }, onDeleteApp = { }, onConditionChanged = { } ) @@ -204,16 +209,13 @@ private fun DetailPreview() { @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) @Composable private fun LongAppNameDetailPreview() { - val snackbarHostState = remember { SnackbarHostState() } AppTheme { DetailContent( - snackbarHostState = snackbarHostState, app = InstalledApp( "Sample App Name So Loooooooooooooooooooong", "example.sample.test" ), condition = "", - onBack = { }, onDeleteApp = { }, onConditionChanged = { } ) diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/license/LicenseScreen.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/license/LicenseScreen.kt index deebbb37..305ec4a6 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/license/LicenseScreen.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/license/LicenseScreen.kt @@ -19,7 +19,6 @@ fun LicenseScreen(navController: NavController) { val snackbarHostState = remember { SnackbarHostState() } AppScaffold( snackbarHostState = snackbarHostState, - hasBackContent = true, onBack = { navController.popBackStack() } diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/main/MainScreen.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/main/MainScreen.kt index eee4589e..f17fcbcc 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/main/MainScreen.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/screen/main/MainScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier @@ -26,27 +27,62 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.navigation.NavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import com.google.gson.Gson import kotlinx.coroutines.launch +import me.nya_n.notificationnotifier.model.InstalledApp import me.nya_n.notificationnotifier.ui.R import me.nya_n.notificationnotifier.ui.common.AppScaffold import me.nya_n.notificationnotifier.ui.common.EmptyView +import me.nya_n.notificationnotifier.ui.screen.app.Screen +import me.nya_n.notificationnotifier.ui.screen.detail.DetailScreen import me.nya_n.notificationnotifier.ui.screen.selection.SelectionScreen import me.nya_n.notificationnotifier.ui.screen.settings.SettingsScreen import me.nya_n.notificationnotifier.ui.screen.target.TargetScreen import me.nya_n.notificationnotifier.ui.theme.AppTheme +import me.nya_n.notificationnotifier.ui.util.LocalAnimatedVisibilityScope /** メイン画面 */ @Composable fun MainScreen(navController: NavController) { val snackbarHostState = remember { SnackbarHostState() } + val tab1NavController = rememberNavController() val activity = LocalActivity.current val scope = rememberCoroutineScope() val tabItems = listOf( TabItem(stringResource(id = R.string.targets), Icons.Outlined.NotificationsActive) { - TargetScreen( - navController = navController, - snackbarHostState = snackbarHostState - ) + NavHost( + navController = tab1NavController, + startDestination = Screen.Main.Targets.name + ) { + composable(Screen.Main.Targets.route) { + CompositionLocalProvider( + LocalAnimatedVisibilityScope provides this@composable + ) { + TargetScreen( + navController = tab1NavController, + snackbarHostState = snackbarHostState + ) + } + } + composable(Screen.Main.Detail.route) { + val app = Gson().fromJson( + it.arguments?.getString("app"), + InstalledApp::class.java + ) + CompositionLocalProvider( + LocalAnimatedVisibilityScope provides this@composable + ) { + DetailScreen( + navController = tab1NavController, + app = app + ) + } + } + } }, TabItem(stringResource(id = R.string.apps), Icons.AutoMirrored.Rounded.List) { SelectionScreen(snackbarHostState = snackbarHostState) @@ -59,6 +95,11 @@ fun MainScreen(navController: NavController) { }, ) val pagerState = rememberPagerState(pageCount = { tabItems.size }) + val isTab1RootScreen = + tab1NavController.currentBackStackEntryAsState().value?.destination?.route == Screen.Main.Targets.route + val onBack: (() -> Unit)? = if (pagerState.currentPage == 0 && !isTab1RootScreen) { + { tab1NavController.popBackStack() } + } else null BackHandler(true) { snackbarHostState.currentSnackbarData?.dismiss() if (pagerState.currentPage == 0) { @@ -70,11 +111,13 @@ fun MainScreen(navController: NavController) { MainContent( snackbarHostState = snackbarHostState, tabItems = tabItems, - pagerState = pagerState - ) { - snackbarHostState.currentSnackbarData?.dismiss() - scope.launch { pagerState.scrollToPage(it, 0f) } - } + pagerState = pagerState, + onBack = onBack, + onTabSelected = { + snackbarHostState.currentSnackbarData?.dismiss() + scope.launch { pagerState.scrollToPage(it, 0f) } + } + ) } /** メイン画面のコンテンツ本体 */ @@ -83,10 +126,12 @@ fun MainContent( snackbarHostState: SnackbarHostState, tabItems: List, pagerState: PagerState, - onTabSelected: (selected: Int) -> Unit + onBack: (() -> Unit)? = null, + onTabSelected: (selected: Int) -> Unit, ) { AppScaffold( snackbarHostState = snackbarHostState, + onBack = onBack, bottomBar = { BottomBar( items = tabItems, @@ -153,8 +198,10 @@ private fun MainPreview() { MainContent( snackbarHostState = snackbarHostState, tabItems = tabItems, - pagerState = pagerState - ) { } + pagerState = pagerState, + onTabSelected = { }, + onBack = null + ) } } diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/CompositionLocals.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/CompositionLocals.kt new file mode 100644 index 00000000..35395a7a --- /dev/null +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/CompositionLocals.kt @@ -0,0 +1,8 @@ +package me.nya_n.notificationnotifier.ui.util + +import androidx.compose.animation.AnimatedVisibilityScope +import androidx.compose.animation.SharedTransitionScope +import androidx.compose.runtime.compositionLocalOf + +val LocalSharedTransitionScope = compositionLocalOf { null } +val LocalAnimatedVisibilityScope = compositionLocalOf { null } \ No newline at end of file diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/Extensions.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/Extensions.kt index ff8ebe4f..9ba46f2e 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/Extensions.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/Extensions.kt @@ -2,6 +2,7 @@ package me.nya_n.notificationnotifier.ui.util import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalInspectionMode +import me.nya_n.notificationnotifier.model.InstalledApp /** 現在Preview中か? * - Composableな関数内でのみ使用可能 @@ -13,3 +14,6 @@ fun isInPreview(): Boolean { val isForcePreview = false return LocalInspectionMode.current || isForcePreview } + +val InstalledApp.iconSharedTransitionKey: String + get() = "appIcon_$packageName" diff --git a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/Sample.kt b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/Sample.kt index e63db8cc..80aa4262 100644 --- a/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/Sample.kt +++ b/AndroidApp/ui/src/main/kotlin/me/nya_n/notificationnotifier/ui/util/Sample.kt @@ -9,4 +9,4 @@ object Sample { InstalledApp("Sample App ${it + 1}", "me.nya_n.notificationnotifier") } } -} \ No newline at end of file +} diff --git a/AndroidApp/ui/src/screenshotTest/kotlin/me/nya_n/notificationnotifier/ScreenshotTest.kt b/AndroidApp/ui/src/screenshotTest/kotlin/me/nya_n/notificationnotifier/ScreenshotTest.kt index a40f3442..e878dc25 100644 --- a/AndroidApp/ui/src/screenshotTest/kotlin/me/nya_n/notificationnotifier/ScreenshotTest.kt +++ b/AndroidApp/ui/src/screenshotTest/kotlin/me/nya_n/notificationnotifier/ScreenshotTest.kt @@ -1,240 +1,239 @@ -package me.nya_n.notificationnotifier - -import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.List -import androidx.compose.material.icons.outlined.NotificationsActive -import androidx.compose.material.icons.outlined.Settings -import androidx.compose.material3.SnackbarHostState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.tooling.preview.Preview -import me.nya_n.notificationnotifier.model.InstalledApp -import me.nya_n.notificationnotifier.ui.common.AppList -import me.nya_n.notificationnotifier.ui.common.AppOutlinedButton -import me.nya_n.notificationnotifier.ui.common.AppScaffold -import me.nya_n.notificationnotifier.ui.common.Category -import me.nya_n.notificationnotifier.ui.common.CommonDialog -import me.nya_n.notificationnotifier.ui.common.EmptyView -import me.nya_n.notificationnotifier.ui.common.RequireNotificationPermissionDialog -import me.nya_n.notificationnotifier.ui.common.RequirePackageVisibilityDialog -import me.nya_n.notificationnotifier.ui.common.TopBar -import me.nya_n.notificationnotifier.ui.screen.detail.DetailContent -import me.nya_n.notificationnotifier.ui.screen.main.MainContent -import me.nya_n.notificationnotifier.ui.screen.main.TabItem -import me.nya_n.notificationnotifier.ui.screen.selection.SelectionContent -import me.nya_n.notificationnotifier.ui.screen.settings.SettingsContent -import me.nya_n.notificationnotifier.ui.screen.target.TargetContent -import me.nya_n.notificationnotifier.ui.theme.AppTheme -import me.nya_n.notificationnotifier.ui.util.Sample - -class ScreenshotTest { - - // region: 画面レベル - - @Preview - @Composable - fun MainContentScreenshotTest() { - val snackbarHostState = remember { SnackbarHostState() } - val tabItems = listOf( - TabItem("タブ1", Icons.Outlined.NotificationsActive), - TabItem("タブ2", Icons.AutoMirrored.Rounded.List), - TabItem("タブ3", Icons.Outlined.Settings), - ) - val pagerState = rememberPagerState(pageCount = { tabItems.size }) - AppTheme { - MainContent( - snackbarHostState = snackbarHostState, - tabItems = tabItems, - pagerState = pagerState - ) { } - } - } - - - @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) - @Composable - fun TargetContentScreenshotTest() { - val items = listOf( - InstalledApp("Sample App", "me.nya_n.notificationnotifier"), - InstalledApp("Sample App", "me.nya_n.notificationnotifier"), - InstalledApp("Sample App", "me.nya_n.notificationnotifier"), - ) - AppTheme { - TargetContent( - items = items, - isLoading = false, - onAppSelected = { } - ) - } - } - - @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) - @Composable - fun DetailContentScreenshotTest() { - val snackbarHostState = remember { SnackbarHostState() } - AppTheme { - DetailContent( - snackbarHostState = snackbarHostState, - app = InstalledApp("Sample App Name", "example.sample.test"), - condition = "^.*$", - onBack = { }, - onDeleteApp = { }, - onConditionChanged = { } - ) - } - } - - @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) - @Composable - fun SelectionContentScreenshotTest() { - AppTheme { - SelectionContent( - items = Sample.items, - isLoading = false, - onAppSelected = { }, - initQuery = "", - onQueryInputted = { } - ) - } - } - - @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) - @Composable - fun SettingsContentScreenshotTest() { - AppTheme { - SettingsContent( - address = "192.168.11.2:5555", - versionCode = 1, - versionName = "1.0", - onValueChange = { }, - onNotifyTest = { }, - onExportData = { }, - onImportData = { }, - onLicense = { }, - onAboutDeveloper = { } - ) - } - } - - // endregion - - // region: コンポーネントレベル - - @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) - @Composable - fun AppListComponentScreenshotTest() { - val items = listOf( - InstalledApp("Sample App", "me.nya_n.notificationnotifier"), - InstalledApp( - "Sample App Name So Looooooooooooooooong", - "me.nya_n.notificationnotifier" - ), - ) - AppTheme { - AppList( - items = items, - onAppSelected = { } - ) - } - } - - @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) - @Composable - fun EmptyAppListComponentScreenshotTest() { - AppTheme { - AppList( - items = emptyList(), - onAppSelected = { } - ) - } - } - - @Preview - @Composable - fun AppOutlinedButtonComponentScreenshotTest() { - AppTheme { - AppOutlinedButton("text") { } - } - } - - @Preview - @Composable - fun AppScaffoldComponentScreenshotTest() { - val snackbarHostState = remember { SnackbarHostState() } - AppTheme { - AppScaffold(snackbarHostState) { } - } - } - - @Preview - @Composable - fun CategoryComponentScreenshotTest() { - AppTheme { - Category("カテゴリ") - } - } - - @Preview - @Composable - fun CommonDialogComponentScreenshotTest() { - AppTheme { - CommonDialog( - message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", - positiveButtonText = "YES", - negativeButtonText = "NO", - onPositiveDismissRequest = { }, - onNegativeDismissRequest = { } - ) - } - } - - @Preview - @Composable - fun RequireNotificationPermissionDialogComponentScreenshotTest() { - AppTheme { - RequireNotificationPermissionDialog( - onDismissRequest = { } - ) - } - } - - @Preview - @Composable - fun RequirePackageVisibilityDialogComponentScreenshotTest() { - AppTheme { - RequirePackageVisibilityDialog( - onDismissRequest = { } - ) - } - } - - @Preview - @Composable - fun EmptyViewComponentScreenshotTest() { - AppTheme { - EmptyView(message = "empty") - } - } - - @Preview - @Composable - fun TopBarComponentScreenshotTest() { - AppTheme { - TopBar() - } - } - - @Preview - @Composable - fun SubContentTopBarComponentScreenshotTest() { - AppTheme { - TopBar( - hasBackContent = true, - onBack = { } - ) - } - } - - // endregion -} \ No newline at end of file +//package me.nya_n.notificationnotifier +// +//import androidx.compose.foundation.pager.rememberPagerState +//import androidx.compose.material.icons.Icons +//import androidx.compose.material.icons.automirrored.rounded.List +//import androidx.compose.material.icons.outlined.NotificationsActive +//import androidx.compose.material.icons.outlined.Settings +//import androidx.compose.material3.SnackbarHostState +//import androidx.compose.runtime.Composable +//import androidx.compose.runtime.remember +//import androidx.compose.ui.tooling.preview.Preview +//import me.nya_n.notificationnotifier.model.InstalledApp +//import me.nya_n.notificationnotifier.ui.common.AppList +//import me.nya_n.notificationnotifier.ui.common.AppOutlinedButton +//import me.nya_n.notificationnotifier.ui.common.AppScaffold +//import me.nya_n.notificationnotifier.ui.common.Category +//import me.nya_n.notificationnotifier.ui.common.CommonDialog +//import me.nya_n.notificationnotifier.ui.common.EmptyView +//import me.nya_n.notificationnotifier.ui.common.RequireNotificationPermissionDialog +//import me.nya_n.notificationnotifier.ui.common.RequirePackageVisibilityDialog +//import me.nya_n.notificationnotifier.ui.common.TopBar +//import me.nya_n.notificationnotifier.ui.screen.detail.DetailContent +//import me.nya_n.notificationnotifier.ui.screen.main.MainContent +//import me.nya_n.notificationnotifier.ui.screen.main.TabItem +//import me.nya_n.notificationnotifier.ui.screen.selection.SelectionContent +//import me.nya_n.notificationnotifier.ui.screen.settings.SettingsContent +//import me.nya_n.notificationnotifier.ui.screen.target.TargetContent +//import me.nya_n.notificationnotifier.ui.theme.AppTheme +//import me.nya_n.notificationnotifier.ui.util.Sample +// +//class ScreenshotTest { +// +// // region: 画面レベル +// +// @Preview +// @Composable +// fun MainContentScreenshotTest() { +// val snackbarHostState = remember { SnackbarHostState() } +// val tabItems = listOf( +// TabItem("タブ1", Icons.Outlined.NotificationsActive), +// TabItem("タブ2", Icons.AutoMirrored.Rounded.List), +// TabItem("タブ3", Icons.Outlined.Settings), +// ) +// val pagerState = rememberPagerState(pageCount = { tabItems.size }) +// AppTheme { +// MainContent( +// snackbarHostState = snackbarHostState, +// tabItems = tabItems, +// pagerState = pagerState +// ) { } +// } +// } +// +// +// @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) +// @Composable +// fun TargetContentScreenshotTest() { +// val items = listOf( +// InstalledApp("Sample App", "me.nya_n.notificationnotifier"), +// InstalledApp("Sample App", "me.nya_n.notificationnotifier"), +// InstalledApp("Sample App", "me.nya_n.notificationnotifier"), +// ) +// AppTheme { +// TargetContent( +// items = items, +// isLoading = false, +// onAppSelected = { } +// ) +// } +// } +// +// @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) +// @Composable +// fun DetailContentScreenshotTest() { +// val snackbarHostState = remember { SnackbarHostState() } +// AppTheme { +// DetailContent( +// snackbarHostState = snackbarHostState, +// app = InstalledApp("Sample App Name", "example.sample.test"), +// condition = "^.*$", +// onBack = { }, +// onDeleteApp = { }, +// onConditionChanged = { } +// ) +// } +// } +// +// @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) +// @Composable +// fun SelectionContentScreenshotTest() { +// AppTheme { +// SelectionContent( +// items = Sample.items, +// isLoading = false, +// onAppSelected = { }, +// initQuery = "", +// onQueryInputted = { } +// ) +// } +// } +// +// @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) +// @Composable +// fun SettingsContentScreenshotTest() { +// AppTheme { +// SettingsContent( +// address = "192.168.11.2:5555", +// versionCode = 1, +// versionName = "1.0", +// onValueChange = { }, +// onNotifyTest = { }, +// onExportData = { }, +// onImportData = { }, +// onLicense = { }, +// onAboutDeveloper = { } +// ) +// } +// } +// +// // endregion +// +// // region: コンポーネントレベル +// +// @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) +// @Composable +// fun AppListComponentScreenshotTest() { +// val items = listOf( +// InstalledApp("Sample App", "me.nya_n.notificationnotifier"), +// InstalledApp( +// "Sample App Name So Looooooooooooooooong", +// "me.nya_n.notificationnotifier" +// ), +// ) +// AppTheme { +// AppList( +// items = items, +// onAppSelected = { } +// ) +// } +// } +// +// @Preview(backgroundColor = 0xFFC7B5A8, showBackground = true) +// @Composable +// fun EmptyAppListComponentScreenshotTest() { +// AppTheme { +// AppList( +// items = emptyList(), +// onAppSelected = { } +// ) +// } +// } +// +// @Preview +// @Composable +// fun AppOutlinedButtonComponentScreenshotTest() { +// AppTheme { +// AppOutlinedButton("text") { } +// } +// } +// +// @Preview +// @Composable +// fun AppScaffoldComponentScreenshotTest() { +// val snackbarHostState = remember { SnackbarHostState() } +// AppTheme { +// AppScaffold(snackbarHostState) { } +// } +// } +// +// @Preview +// @Composable +// fun CategoryComponentScreenshotTest() { +// AppTheme { +// Category("カテゴリ") +// } +// } +// +// @Preview +// @Composable +// fun CommonDialogComponentScreenshotTest() { +// AppTheme { +// CommonDialog( +// message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", +// positiveButtonText = "YES", +// negativeButtonText = "NO", +// onPositiveDismissRequest = { }, +// onNegativeDismissRequest = { } +// ) +// } +// } +// +// @Preview +// @Composable +// fun RequireNotificationPermissionDialogComponentScreenshotTest() { +// AppTheme { +// RequireNotificationPermissionDialog( +// onDismissRequest = { } +// ) +// } +// } +// +// @Preview +// @Composable +// fun RequirePackageVisibilityDialogComponentScreenshotTest() { +// AppTheme { +// RequirePackageVisibilityDialog( +// onDismissRequest = { } +// ) +// } +// } +// +// @Preview +// @Composable +// fun EmptyViewComponentScreenshotTest() { +// AppTheme { +// EmptyView(message = "empty") +// } +// } +// +// @Preview +// @Composable +// fun TopBarComponentScreenshotTest() { +// AppTheme { +// TopBar() +// } +// } +// +// @Preview +// @Composable +// fun SubContentTopBarComponentScreenshotTest() { +// AppTheme { +// TopBar( +// onBack = { } +// ) +// } +// } +// +// // endregion +//} \ No newline at end of file