├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── dev │ │ └── synapsetech │ │ └── compass │ │ └── ExampleInstrumentedTest.kt │ ├── debug │ ├── ic_launcher-playstore.png │ └── res │ │ ├── drawable │ │ └── ic_launcher_foreground.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ └── ic_launcher_background.xml │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── dev │ │ │ └── synapsetech │ │ │ └── compass │ │ │ ├── Cardinal.kt │ │ │ ├── MainActivity.kt │ │ │ ├── SensorDataManager.kt │ │ │ └── ui │ │ │ └── theme │ │ │ ├── Color.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ └── res │ │ ├── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ └── data_extraction_rules.xml │ ├── release │ ├── ic_launcher-playstore.png │ └── res │ │ ├── drawable │ │ └── ic_launcher_foreground.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ └── ic_launcher_background.xml │ └── test │ └── java │ └── dev │ └── synapsetech │ └── compass │ └── CardinalEnumTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshots ├── Screenshot_20220923-223435.png ├── Screenshot_20220923-232045.png └── Screenshot_20220923-232645.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 119 | 120 | 122 | 123 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 Elizabeth Hazel Ainslie 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Compass 2 | A simple & straightforward, no-BS compass app that works with your Material You colors! 3 | 4 | ## Motivation 5 | I do security work as a fourth job and having a proper compass helps. I tried 6 | finding a good option on the Play Store but they all contain ads or shill other 7 | apps. I just needed something that'd give me a general direction and (when I 8 | need it) my exact bearing, so that's why I made this. I also made it draw colors 9 | from your Material You theme so it looks amazing! 10 | 11 | ## Screenshots 12 | | | | | 13 | |-------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------| 14 | | ![Yellow](screenshots/Screenshot_20220923-232645.png) | ![Blue](screenshots/Screenshot_20220923-232045.png) | ![Orange](screenshots/Screenshot_20220923-223435.png) | 15 | 16 | ## Installation 17 | To get the app, you can clone this repo and build it as usual with Android 18 | Studio, or you can use the GitHub release feature. 19 | 20 | you'll be able to find it on the Google Play Store at 21 | https://play.google.com/store/apps/details?id=dev.synapsetech.compass 22 | 23 | ## License 24 | This project is subject to the terms of the [MIT License](LICENSE). 25 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release 3 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | } 5 | 6 | android { 7 | namespace 'dev.synapsetech.compass' 8 | compileSdk 32 9 | 10 | defaultConfig { 11 | applicationId "dev.synapsetech.compass" 12 | minSdk 21 13 | targetSdk 32 14 | versionCode 2 15 | versionName "1.1" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | vectorDrawables { 19 | useSupportLibrary true 20 | } 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | kotlinOptions { 34 | jvmTarget = '1.8' 35 | } 36 | buildFeatures { 37 | compose true 38 | } 39 | composeOptions { 40 | kotlinCompilerExtensionVersion '1.1.1' 41 | } 42 | packagingOptions { 43 | resources { 44 | excludes += '/META-INF/{AL2.0,LGPL2.1}' 45 | } 46 | } 47 | } 48 | 49 | dependencies { 50 | 51 | implementation 'androidx.core:core-ktx:1.7.0' 52 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' 53 | implementation 'androidx.activity:activity-compose:1.3.1' 54 | implementation "androidx.compose.ui:ui:$compose_version" 55 | implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" 56 | implementation 'androidx.compose.material3:material3:1.0.0-alpha02' 57 | testImplementation 'junit:junit:4.13.2' 58 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 59 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 60 | androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" 61 | debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" 62 | debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" 63 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/dev/synapsetech/compass/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package dev.synapsetech.compass 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("dev.synapsetech.compass", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/debug/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/debug/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SynapseTech/Compass/82ded70f1112a6a5c46319fd4d472a9b628a338f/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/debug/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #DC3545 4 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/dev/synapsetech/compass/Cardinal.kt: -------------------------------------------------------------------------------- 1 | package dev.synapsetech.compass 2 | 3 | enum class Cardinal(val letter: String, val degree: Int) { 4 | NORTH("N", 0), 5 | EAST("E", 90), 6 | SOUTH("S", 180), 7 | WEST("W", 270), 8 | ; 9 | 10 | companion object { 11 | fun fromDegree(degree: Int): Cardinal { 12 | val divisor: Int = 360 / values().size 13 | val coci = degree / divisor 14 | val resto = degree % divisor 15 | return if (resto <= divisor / 2) { 16 | values()[coci % values().size] 17 | } else { 18 | values()[(coci + 1) % values().size] 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/dev/synapsetech/compass/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.synapsetech.compass 2 | 3 | import android.graphics.Paint 4 | import android.os.Build 5 | import android.os.Bundle 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import androidx.annotation.RequiresApi 9 | import androidx.compose.foundation.Canvas 10 | import androidx.compose.foundation.layout.* 11 | import androidx.compose.material3.MaterialTheme 12 | import androidx.compose.material3.Surface 13 | import androidx.compose.material3.Text 14 | import androidx.compose.runtime.* 15 | import androidx.compose.ui.Alignment 16 | import androidx.compose.ui.Modifier 17 | import androidx.compose.ui.geometry.Offset 18 | import androidx.compose.ui.graphics.Path 19 | import androidx.compose.ui.graphics.SolidColor 20 | import androidx.compose.ui.graphics.drawscope.Stroke 21 | import androidx.compose.ui.graphics.drawscope.rotate 22 | import androidx.compose.ui.graphics.nativeCanvas 23 | import androidx.compose.ui.platform.LocalContext 24 | import androidx.compose.ui.tooling.preview.Preview 25 | import androidx.compose.ui.unit.dp 26 | import dev.synapsetech.compass.ui.theme.CompassTheme 27 | import kotlinx.coroutines.flow.collect 28 | import kotlinx.coroutines.flow.onEach 29 | import kotlinx.coroutines.flow.receiveAsFlow 30 | import kotlinx.coroutines.launch 31 | 32 | class MainActivity : ComponentActivity() { 33 | @RequiresApi(Build.VERSION_CODES.O) 34 | override fun onCreate(savedInstanceState: Bundle?) { 35 | super.onCreate(savedInstanceState) 36 | 37 | setContent { 38 | CompassTheme { 39 | // A surface container using the 'background' color from the theme 40 | Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { 41 | MainPage() 42 | } 43 | } 44 | } 45 | } 46 | } 47 | 48 | @RequiresApi(Build.VERSION_CODES.O) 49 | @Composable 50 | fun MainPage() { 51 | var currentDegree by remember { mutableStateOf(0f) } 52 | val context = LocalContext.current 53 | val scope = rememberCoroutineScope() 54 | 55 | DisposableEffect(Unit) { 56 | val dataManager = SensorDataManager(context) 57 | dataManager.init() 58 | 59 | val job = scope.launch { 60 | dataManager.data 61 | .receiveAsFlow() 62 | .onEach { currentDegree = it } 63 | .collect {} 64 | } 65 | onDispose { 66 | dataManager.cancel() 67 | job.cancel() 68 | } 69 | } 70 | 71 | val bgColor = MaterialTheme.colorScheme.background 72 | val circleColor = MaterialTheme.colorScheme.onBackground 73 | val arrowPosColor = MaterialTheme.colorScheme.tertiary 74 | val arrowNegColor = MaterialTheme.colorScheme.primary 75 | 76 | Column( 77 | modifier = Modifier.fillMaxSize(), 78 | verticalArrangement = Arrangement.Center, 79 | horizontalAlignment = Alignment.CenterHorizontally 80 | ) { 81 | Text(text = "$currentDegree° ${Cardinal.fromDegree(currentDegree.toInt()).letter}") 82 | Canvas(modifier = Modifier 83 | .width(128.dp) 84 | .height(128.dp)) { 85 | drawCircle( 86 | color = circleColor, 87 | style = Stroke(15f), 88 | center = Offset(x = size.width / 2, y = size.height / 2), 89 | radius = size.width 90 | ) 91 | 92 | val arrowPath = Path() 93 | arrowPath.moveTo(size.width / 2, (size.height * .9).toFloat()) 94 | arrowPath.lineTo(size.width / 2 + 30, size.height / 2) 95 | arrowPath.lineTo(size.width / 2 - 30, size.height / 2) 96 | arrowPath.lineTo(size.width / 2, (size.height * .9).toFloat()) 97 | 98 | rotate(-currentDegree) { 99 | Cardinal.values().forEach { 100 | rotate(it.degree.toFloat()) { 101 | drawContext.canvas.nativeCanvas.apply { 102 | drawText( 103 | it.letter, 104 | size.width / 2, 105 | -(size.width / 2 + 40), 106 | Paint().apply { 107 | textSize = 70f 108 | color = android.graphics.Color.argb( 109 | circleColor.alpha, 110 | circleColor.red, 111 | circleColor.blue, 112 | circleColor.green 113 | ) 114 | textAlign = Paint.Align.CENTER 115 | } 116 | ) 117 | } 118 | } 119 | } 120 | 121 | for (i in 0..350 step 10) { 122 | rotate(i.toFloat()) { 123 | drawLine( 124 | color = circleColor, 125 | start = Offset(x = size.width / 2, ((size.height / 2) - size.width) + 25), 126 | end = Offset(x = size.width / 2, (size.height / 2) - size.width), 127 | strokeWidth = 5f, 128 | ) 129 | } 130 | } 131 | 132 | drawPath(arrowPath, SolidColor(arrowNegColor)) 133 | rotate(180f) { 134 | drawPath(arrowPath, SolidColor(arrowPosColor)) 135 | } 136 | } 137 | 138 | drawLine( 139 | color = arrowNegColor, 140 | start = Offset(x = size.width / 2, ((size.height / 2) - size.width) + 30), 141 | end = Offset(x = size.width / 2, ((size.height / 2) - size.width) - 30), 142 | strokeWidth = 10f, 143 | ) 144 | } 145 | } 146 | } 147 | 148 | @RequiresApi(Build.VERSION_CODES.O) 149 | @Preview(showBackground = true) 150 | @Composable 151 | fun DefaultPreview() { 152 | CompassTheme { 153 | MainPage() 154 | } 155 | } -------------------------------------------------------------------------------- /app/src/main/java/dev/synapsetech/compass/SensorDataManager.kt: -------------------------------------------------------------------------------- 1 | package dev.synapsetech.compass 2 | 3 | import android.content.Context 4 | import android.hardware.Sensor 5 | import android.hardware.SensorEvent 6 | import android.hardware.SensorEventListener 7 | import android.hardware.SensorManager 8 | import kotlinx.coroutines.channels.Channel 9 | 10 | class SensorDataManager (context: Context): SensorEventListener { 11 | private val sensorManager by lazy { 12 | context.getSystemService(Context.SENSOR_SERVICE) as SensorManager 13 | } 14 | 15 | fun init() { 16 | sensorManager.registerListener( 17 | this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 18 | SensorManager.SENSOR_DELAY_GAME 19 | ) 20 | } 21 | 22 | val data: Channel = Channel(Channel.UNLIMITED) 23 | 24 | override fun onSensorChanged(event: SensorEvent) { 25 | val degree = Math.round(event.values[0]).toFloat() 26 | 27 | data.trySend(degree) 28 | } 29 | 30 | override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {} 31 | 32 | fun cancel() { 33 | sensorManager.unregisterListener(this); 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/dev/synapsetech/compass/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package dev.synapsetech.compass.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple80 = Color(0xFFD0BCFF) 6 | val PurpleGrey80 = Color(0xFFCCC2DC) 7 | val Pink80 = Color(0xFFEFB8C8) 8 | 9 | val Purple40 = Color(0xFF6650a4) 10 | val PurpleGrey40 = Color(0xFF625b71) 11 | val Pink40 = Color(0xFF7D5260) -------------------------------------------------------------------------------- /app/src/main/java/dev/synapsetech/compass/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package dev.synapsetech.compass.ui.theme 2 | 3 | import android.app.Activity 4 | import android.os.Build 5 | import androidx.compose.foundation.isSystemInDarkTheme 6 | import androidx.compose.material3.MaterialTheme 7 | import androidx.compose.material3.darkColorScheme 8 | import androidx.compose.material3.dynamicDarkColorScheme 9 | import androidx.compose.material3.dynamicLightColorScheme 10 | import androidx.compose.material3.lightColorScheme 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.runtime.SideEffect 13 | import androidx.compose.ui.graphics.toArgb 14 | import androidx.compose.ui.platform.LocalContext 15 | import androidx.compose.ui.platform.LocalView 16 | import androidx.core.view.ViewCompat 17 | 18 | private val DarkColorScheme = darkColorScheme( 19 | primary = Purple80, 20 | secondary = PurpleGrey80, 21 | tertiary = Pink80 22 | ) 23 | 24 | private val LightColorScheme = lightColorScheme( 25 | primary = Purple40, 26 | secondary = PurpleGrey40, 27 | tertiary = Pink40 28 | 29 | /* Other default colors to override 30 | background = Color(0xFFFFFBFE), 31 | surface = Color(0xFFFFFBFE), 32 | onPrimary = Color.White, 33 | onSecondary = Color.White, 34 | onTertiary = Color.White, 35 | onBackground = Color(0xFF1C1B1F), 36 | onSurface = Color(0xFF1C1B1F), 37 | */ 38 | ) 39 | 40 | @Composable 41 | fun CompassTheme( 42 | darkTheme: Boolean = isSystemInDarkTheme(), 43 | // Dynamic color is available on Android 12+ 44 | dynamicColor: Boolean = true, 45 | content: @Composable () -> Unit 46 | ) { 47 | val colorScheme = when { 48 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { 49 | val context = LocalContext.current 50 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) 51 | } 52 | darkTheme -> DarkColorScheme 53 | else -> LightColorScheme 54 | } 55 | val view = LocalView.current 56 | if (!view.isInEditMode) { 57 | SideEffect { 58 | (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb() 59 | ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme 60 | } 61 | } 62 | 63 | MaterialTheme( 64 | colorScheme = colorScheme, 65 | typography = Typography, 66 | content = content 67 | ) 68 | } -------------------------------------------------------------------------------- /app/src/main/java/dev/synapsetech/compass/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package dev.synapsetech.compass.ui.theme 2 | 3 | import androidx.compose.material3.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | // Set of Material typography styles to start with 10 | val Typography = Typography( 11 | bodyLarge = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp, 15 | lineHeight = 24.sp, 16 | letterSpacing = 0.5.sp 17 | ) 18 | /* Other default text styles to override 19 | titleLarge = TextStyle( 20 | fontFamily = FontFamily.Default, 21 | fontWeight = FontWeight.Normal, 22 | fontSize = 22.sp, 23 | lineHeight = 28.sp, 24 | letterSpacing = 0.sp 25 | ), 26 | labelSmall = TextStyle( 27 | fontFamily = FontFamily.Default, 28 | fontWeight = FontWeight.Medium, 29 | fontSize = 11.sp, 30 | lineHeight = 16.sp, 31 | letterSpacing = 0.5.sp 32 | ) 33 | */ 34 | ) -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Compass 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |