@@ -15,21 +15,22 @@ import androidx.activity.result.contract.ActivityResultContracts
1515import androidx.compose.foundation.Image
1616import androidx.compose.foundation.layout.Row
1717import androidx.compose.foundation.layout.Spacer
18+ import androidx.compose.foundation.layout.WindowInsets
1819import androidx.compose.foundation.layout.fillMaxSize
1920import androidx.compose.foundation.layout.padding
2021import androidx.compose.foundation.layout.size
22+ import androidx.compose.foundation.layout.statusBars
2123import androidx.compose.foundation.layout.width
24+ import androidx.compose.foundation.layout.windowInsetsPadding
2225import androidx.compose.material.icons.rounded.HelpOutline
2326import androidx.compose.material3.ExperimentalMaterial3Api
2427import androidx.compose.material3.Icon
2528import androidx.compose.material3.IconButton
2629import androidx.compose.material3.IconButtonDefaults
27- import androidx.compose.material3.LargeTopAppBar
2830import androidx.compose.material3.MaterialTheme
2931import androidx.compose.material3.Scaffold
3032import androidx.compose.material3.Text
31- import androidx.compose.material3.TopAppBarDefaults
32- import androidx.compose.material3.rememberTopAppBarState
33+ import androidx.compose.material3.Surface
3334import androidx.compose.runtime.LaunchedEffect
3435import androidx.compose.runtime.collectAsState
3536import androidx.compose.runtime.getValue
@@ -51,6 +52,7 @@ import com.sameerasw.airsync.data.local.DataStoreManager
5152import com.sameerasw.airsync.presentation.ui.activities.QRScannerActivity
5253import com.sameerasw.airsync.presentation.ui.screens.AirSyncMainScreen
5354import com.sameerasw.airsync.ui.theme.AirSyncTheme
55+ import com.sameerasw.airsync.presentation.viewmodel.AirSyncViewModel
5456import com.sameerasw.airsync.utils.AdbMdnsDiscovery
5557import com.sameerasw.airsync.utils.ContentCaptureManager
5658import com.sameerasw.airsync.utils.DevicePreviewResolver
@@ -187,7 +189,11 @@ class MainActivity : ComponentActivity() {
187189 splashScreen.setOnExitAnimationListener { splashScreenViewProvider ->
188190 try {
189191 val splashScreenView = splashScreenViewProvider.view
190- val splashIcon = splashScreenViewProvider.iconView
192+ val splashIcon = try {
193+ splashScreenViewProvider.iconView
194+ } catch (e: Exception ) {
195+ null
196+ }
191197
192198 // Retrieve last connected device in background while showing splash
193199 var deviceIconRes: Int? = null
@@ -233,7 +239,7 @@ class MainActivity : ComponentActivity() {
233239 fadeInIcon.doOnEnd {
234240 // Hold on device icon for 0.5s, then start outro animation
235241 try {
236- splashIcon .postDelayed({
242+ splashScreenView .postDelayed({
237243 startOutroAnimation(
238244 splashScreenView,
239245 splashIcon,
@@ -274,47 +280,28 @@ class MainActivity : ComponentActivity() {
274280 fadeOutIcon.start()
275281 } else {
276282 // No device icon found, or splashIcon is null/not ImageView (OEM device compatibility)
277- when {
278- splashIcon == null -> {
279- Log .w(
280- " SplashScreen" ,
281- " iconView is null - OEM device detected, skipping crossfade"
282- )
283- }
284-
285- deviceIconRes == null -> {
286- Log .d(
283+ // Proceed directly to outro after a brief hold
284+ try {
285+ splashScreenView.postDelayed({
286+ startOutroAnimation(
287+ splashScreenView,
288+ splashIcon,
289+ splashScreenViewProvider
290+ )
291+ }, 500 )
292+ } catch (e: Exception ) {
293+ Log .e(
287294 " MainActivity" ,
288- " No device icon resource, proceeding with app icon"
289- )
290- }
291-
292- else -> {
293- Log .w(
294- " SplashScreen" ,
295- " iconView is not an ImageView - OEM device detected"
295+ " Error scheduling outro with no icon: ${e.message} " ,
296+ e
296297 )
297- }
298- }
299-
300- // Proceed directly to outro after a brief hold
301- try {
302- splashIcon?.postDelayed({
298+ // Fallback: start outro immediately
303299 startOutroAnimation(
304300 splashScreenView,
305301 splashIcon,
306302 splashScreenViewProvider
307303 )
308- }, 500 )
309- } catch (e: Exception ) {
310- Log .e(
311- " MainActivity" ,
312- " Error scheduling outro with no icon: ${e.message} " ,
313- e
314- )
315- // Fallback: start outro immediately
316- startOutroAnimation(splashScreenView, splashIcon, splashScreenViewProvider)
317- }
304+ }
318305 }
319306 } catch (e: Exception ) {
320307 // Fallback for any unexpected exceptions during animation
@@ -376,91 +363,25 @@ class MainActivity : ComponentActivity() {
376363 val isFromQrScan = data != null
377364
378365 setContent {
379- AirSyncTheme {
366+ val viewModel: com.sameerasw.airsync.presentation.viewmodel.AirSyncViewModel =
367+ androidx.lifecycle.viewmodel.compose.viewModel {
368+ com.sameerasw.airsync.presentation.viewmodel.AirSyncViewModel .create(this @MainActivity)
369+ }
370+ val uiState by viewModel.uiState.collectAsState()
371+
372+ AirSyncTheme (pitchBlackTheme = uiState.isPitchBlackThemeEnabled) {
380373 val navController = rememberNavController()
381- var showAboutDialog by remember { mutableStateOf(false ) }
382- var showHelpSheet by remember { mutableStateOf(false ) }
383- val scrollBehavior =
384- TopAppBarDefaults .exitUntilCollapsedScrollBehavior(rememberTopAppBarState())
385- var topBarTitle by remember { mutableStateOf(" AirSync" ) }
386374
387375 Scaffold (
388376 modifier = Modifier
389- .fillMaxSize()
390- .nestedScroll(scrollBehavior.nestedScrollConnection),
377+ .fillMaxSize(),
391378 containerColor = MaterialTheme .colorScheme.surfaceContainer,
392379 contentWindowInsets = androidx.compose.foundation.layout.WindowInsets (
393380 0 ,
394381 0 ,
395382 0 ,
396383 0
397384 ),
398- topBar = {
399- LargeTopAppBar (
400- colors = TopAppBarDefaults .largeTopAppBarColors(
401- containerColor = MaterialTheme .colorScheme.surfaceContainer,
402- scrolledContainerColor = MaterialTheme .colorScheme.surfaceContainer,
403- ),
404- modifier = Modifier .padding(horizontal = 8 .dp),
405- title = {
406- Row (verticalAlignment = androidx.compose.ui.Alignment .CenterVertically ) {
407- // Dynamic icon based on last connected device category
408- val ctx = androidx.compose.ui.platform.LocalContext .current
409- val ds = remember(ctx) { DataStoreManager (ctx) }
410- val lastDevice by ds.getLastConnectedDevice()
411- .collectAsState(initial = null )
412- val iconRes =
413- com.sameerasw.airsync.utils.DeviceIconResolver .getIconRes(
414- lastDevice
415- )
416- Image (
417- painter = painterResource(id = iconRes),
418- contentDescription = " AirSync Logo" ,
419- modifier = Modifier .size(32 .dp),
420- contentScale = ContentScale .Fit ,
421- colorFilter = ColorFilter .tint(MaterialTheme .colorScheme.primary)
422- )
423- Spacer (modifier = Modifier .width(8 .dp))
424- Text (
425- topBarTitle,
426- style = MaterialTheme .typography.titleLarge,
427- color = MaterialTheme .colorScheme.primary,
428- maxLines = 1 ,
429- )
430- }
431- },
432- actions = {
433- IconButton (
434- onClick = { showHelpSheet = true },
435- colors = IconButtonDefaults .iconButtonColors(
436- containerColor = MaterialTheme .colorScheme.surfaceBright
437- ),
438- modifier = Modifier .size(48 .dp)
439- ) {
440- Icon (
441- imageVector = androidx.compose.material.icons.Icons .Rounded .HelpOutline ,
442- contentDescription = " Help" ,
443- modifier = Modifier .size(32 .dp)
444- )
445- }
446- Spacer (modifier = Modifier .width(8 .dp))
447- IconButton (
448- onClick = { showAboutDialog = true },
449- colors = IconButtonDefaults .iconButtonColors(
450- containerColor = MaterialTheme .colorScheme.surfaceBright
451- ),
452- modifier = Modifier .size(48 .dp)
453- ) {
454- Icon (
455- painter = painterResource(id = R .drawable.rounded_info_24),
456- contentDescription = " About" ,
457- modifier = Modifier .size(32 .dp)
458- )
459- }
460- },
461- scrollBehavior = scrollBehavior
462- )
463- }
464385 ) { innerPadding ->
465386 NavHost (
466387 navController = navController,
@@ -474,12 +395,7 @@ class MainActivity : ComponentActivity() {
474395 showConnectionDialog = isFromQrScan,
475396 pcName = pcName,
476397 isPlus = isPlus,
477- symmetricKey = symmetricKey,
478- showAboutDialog = showAboutDialog,
479- onDismissAbout = { showAboutDialog = false },
480- showHelpSheet = showHelpSheet,
481- onDismissHelp = { showHelpSheet = false },
482- onTitleChange = { topBarTitle = it }
398+ symmetricKey = symmetricKey
483399 )
484400 }
485401 }
0 commit comments