11package com.sameerasw.airsync.presentation.ui.composables
22
3- import android.content.Context
43import android.content.Intent
54import android.content.res.Configuration
6- import android.hardware.Sensor
7- import android.hardware.SensorEvent
8- import android.hardware.SensorEventListener
9- import android.hardware.SensorManager
105import android.os.Build
116import androidx.compose.animation.*
127import androidx.compose.animation.core.*
@@ -16,10 +11,7 @@ import androidx.compose.foundation.layout.*
1611import androidx.compose.foundation.shape.RoundedCornerShape
1712import androidx.compose.material3.*
1813import androidx.compose.runtime.*
19- import androidx.compose.runtime.*
2014import androidx.compose.runtime.collectAsState
21- import androidx.compose.runtime.getValue
22- import androidx.compose.runtime.setValue
2315import androidx.compose.ui.Alignment
2416import androidx.compose.ui.Modifier
2517import androidx.compose.ui.draw.clip
@@ -33,9 +25,6 @@ import androidx.compose.ui.hapticfeedback.HapticFeedback
3325import androidx.compose.ui.platform.LocalConfiguration
3426import androidx.compose.ui.platform.LocalContext
3527import androidx.compose.ui.platform.LocalHapticFeedback
36- import androidx.compose.ui.platform.LocalLifecycleOwner
37- import androidx.lifecycle.Lifecycle
38- import androidx.lifecycle.LifecycleEventObserver
3928import androidx.compose.ui.res.painterResource
4029import androidx.compose.ui.res.stringResource
4130import androidx.compose.ui.text.font.FontWeight
@@ -52,6 +41,7 @@ import com.sameerasw.airsync.R
5241import com.sameerasw.airsync.presentation.ui.components.HelpAndGuidesContent
5342import com.sameerasw.airsync.presentation.ui.components.cards.IconToggleItem
5443import com.sameerasw.airsync.presentation.ui.components.pickers.CrashReportingPicker
44+ import com.sameerasw.airsync.presentation.ui.components.RotatingAppIcon
5545import com.sameerasw.airsync.presentation.ui.components.RoundedCardContainer
5646import com.sameerasw.airsync.presentation.viewmodel.AirSyncViewModel
5747import com.sameerasw.airsync.ui.theme.GoogleSansFlex
@@ -173,9 +163,6 @@ fun WelcomeStepContent(
173163 onNext : () -> Unit
174164) {
175165 val context = LocalContext .current
176- val scope = rememberCoroutineScope()
177- val rotationAnimatable = remember { Animatable (0f ) }
178-
179166 Column (
180167 modifier = Modifier .fillMaxSize()
181168 ) {
@@ -191,95 +178,11 @@ fun WelcomeStepContent(
191178
192179 Spacer (modifier = Modifier .weight(1f ))
193180
194- val sensorManager = remember { context.getSystemService(Context .SENSOR_SERVICE ) as SensorManager }
195- val gravitySensor = remember { sensorManager.getDefaultSensor(Sensor .TYPE_ACCELEROMETER ) }
196- var accumulatedRotation by remember { mutableFloatStateOf(0f ) }
197- var lastAngle by remember { mutableFloatStateOf(0f ) }
198- val minorStep = 10f // Increased step for less frequent ticks
199- var lastHapticRotation by remember { mutableFloatStateOf(0f ) }
200-
201- var smoothedAx by remember { mutableFloatStateOf(0f ) }
202- var smoothedAy by remember { mutableFloatStateOf(9.8f ) }
203- val alpha = 0.1f
204-
205- val lifecycleOwner = LocalLifecycleOwner .current
206-
207- DisposableEffect (lifecycleOwner) {
208- val listener = object : SensorEventListener {
209- override fun onSensorChanged (event : SensorEvent ) {
210- if (event.sensor.type == Sensor .TYPE_ACCELEROMETER ) {
211- val ax = event.values[0 ]
212- val ay = event.values[1 ]
213- val az = event.values[2 ]
214-
215- smoothedAx = smoothedAx + alpha * (ax - smoothedAx)
216- smoothedAy = smoothedAy + alpha * (ay - smoothedAy)
217-
218- val tiltMagnitudeSqr = smoothedAx * smoothedAx + smoothedAy * smoothedAy
219- if (tiltMagnitudeSqr < 2.0f ) return
220-
221- val targetAngle = (atan2(smoothedAx.toDouble(), smoothedAy.toDouble()) * 180 / PI ).toFloat()
222-
223- var delta = targetAngle - lastAngle
224- if (delta > 180 ) delta - = 360
225- if (delta < - 180 ) delta + = 360
226-
227- accumulatedRotation + = delta
228- lastAngle = targetAngle
229-
230- if (kotlin.math.abs(accumulatedRotation - lastHapticRotation) >= minorStep) {
231- HapticUtil .performLightTick(haptics)
232- lastHapticRotation = accumulatedRotation
233- }
234-
235- if (! hasTriggeredEasterEgg && kotlin.math.abs(accumulatedRotation) >= 3600f ) {
236- onEasterEggTriggered()
237- val rickRollUrl = " https://youtu.be/dQw4w9WgXcQ"
238- val intent = Intent (Intent .ACTION_VIEW , rickRollUrl.toUri())
239- context.startActivity(intent)
240- }
241-
242- scope.launch {
243- rotationAnimatable.animateTo(
244- accumulatedRotation,
245- animationSpec = spring(
246- dampingRatio = Spring .DampingRatioMediumBouncy ,
247- stiffness = Spring .StiffnessLow
248- )
249- )
250- }
251- }
252- }
253- override fun onAccuracyChanged (sensor : Sensor ? , accuracy : Int ) {}
254- }
255-
256- val observer = LifecycleEventObserver { _, event ->
257- when (event) {
258- Lifecycle .Event .ON_RESUME -> {
259- sensorManager.registerListener(listener, gravitySensor, SensorManager .SENSOR_DELAY_UI )
260- }
261- Lifecycle .Event .ON_PAUSE -> {
262- sensorManager.unregisterListener(listener)
263- }
264- else -> {}
265- }
266- }
267-
268- lifecycleOwner.lifecycle.addObserver(observer)
269- onDispose {
270- lifecycleOwner.lifecycle.removeObserver(observer)
271- sensorManager.unregisterListener(listener)
272- }
273- }
274-
275- Image (
276- painter = painterResource(id = R .drawable.ic_launcher_foreground),
277- contentDescription = null ,
278- modifier = Modifier
279- .size(240 .dp)
280- .graphicsLayer {
281- rotationZ = rotationAnimatable.value
282- }
181+ RotatingAppIcon (
182+ haptics = haptics,
183+ hasTriggeredEasterEgg = hasTriggeredEasterEgg,
184+ onEasterEggTriggered = onEasterEggTriggered,
185+ modifier = Modifier .size(240 .dp)
283186 )
284187
285188 Spacer (modifier = Modifier .height(18 .dp))
0 commit comments