commit 9af60e0c3b36748c839a3dfc21ac57fdc6e88464 Author: Alan Brault Date: Mon Nov 17 08:02:58 2025 -0500 chore: initial commit Signed-off-by: Alan Brault diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5cbb64 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Log/OS Files +*.log + +# Android Studio generated files and folders +captures/ +.externalNativeBuild/ +.cxx/ +*.aab +*.apk +output-metadata.json + +# IntelliJ +*.iml +.idea/ +misc.xml +deploymentTargetDropDown.xml +render.experimental.xml + +# Keystore files +*.jks +*.keystore + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Android Profiling +*.hprof diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..5628acd --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,60 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) +} + +android { + namespace = "io.visus.solanim" + compileSdk { + version = release(36) + } + + defaultConfig { + applicationId = "io.visus.solanim" + minSdk = 35 + targetSdk = 36 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = "17" + } + buildFeatures { + compose = true + } +} + +dependencies { + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.lifecycle.viewmodel.compose) + implementation(libs.koin.androidx.compose) + implementation(libs.koin.androidx.compose.navigation) + implementation(project(":lib:solanim-ui")) + implementation(project(":lib:vulkan")) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.compose.ui.test.junit4) + debugImplementation(libs.androidx.compose.ui.tooling) + debugImplementation(libs.androidx.compose.ui.test.manifest) +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/io/visus/solanim/ExampleInstrumentedTest.kt b/app/src/androidTest/java/io/visus/solanim/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..1788fa3 --- /dev/null +++ b/app/src/androidTest/java/io/visus/solanim/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package io.visus.solanim + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("io.visus.solanim", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d8534b8 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/MainApplication.kt b/app/src/main/java/io/visus/solanim/MainApplication.kt new file mode 100644 index 0000000..2ebd70a --- /dev/null +++ b/app/src/main/java/io/visus/solanim/MainApplication.kt @@ -0,0 +1,20 @@ +package io.visus.solanim + +import android.app.Application +import io.visus.solanim.di.appModule +import org.koin.android.ext.koin.androidContext +import org.koin.android.ext.koin.androidLogger +import org.koin.core.context.startKoin +import org.koin.core.logger.Level + +class MainApplication : Application() { + override fun onCreate() { + super.onCreate() + + startKoin { + androidContext(this@MainApplication) + androidLogger(Level.DEBUG) + modules(appModule) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/di/AppModule.kt b/app/src/main/java/io/visus/solanim/di/AppModule.kt new file mode 100644 index 0000000..5be4d44 --- /dev/null +++ b/app/src/main/java/io/visus/solanim/di/AppModule.kt @@ -0,0 +1,21 @@ +package io.visus.solanim.di + +import io.visus.solanim.presentation.viewmodel.MainViewModel +import io.visus.solanim.domain.repository.SolarAnimationSettingsRepository +import io.visus.solanim.domain.repository.SolarAnimationSettingsRepositoryImpl +import io.visus.solanim.domain.usecase.GetSettingsUseCase +import io.visus.solanim.domain.usecase.UpdateColorUseCase +import io.visus.solanim.domain.usecase.UpdateRotationSpeedUseCase +import org.koin.core.module.dsl.bind +import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.viewModelOf +import org.koin.dsl.module + +val appModule = module { + singleOf(::SolarAnimationSettingsRepositoryImpl) { bind() } + singleOf(::GetSettingsUseCase) + singleOf(::UpdateColorUseCase) + singleOf(::UpdateRotationSpeedUseCase) + + viewModelOf(::MainViewModel) +} \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/domain/model/SolarAnimationDefaults.kt b/app/src/main/java/io/visus/solanim/domain/model/SolarAnimationDefaults.kt new file mode 100644 index 0000000..3dbdb00 --- /dev/null +++ b/app/src/main/java/io/visus/solanim/domain/model/SolarAnimationDefaults.kt @@ -0,0 +1,9 @@ +package io.visus.solanim.domain.model + +/** + * Default values for solar animation settings. + */ +object SolarAnimationDefaults { + const val DEFAULT_COLOR: Int = 0xFFFC9601.toInt() + const val DEFAULT_ROTATION_SPEED: Float = 1.0f +} \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/domain/model/SolarAnimationSettings.kt b/app/src/main/java/io/visus/solanim/domain/model/SolarAnimationSettings.kt new file mode 100644 index 0000000..a3cce3f --- /dev/null +++ b/app/src/main/java/io/visus/solanim/domain/model/SolarAnimationSettings.kt @@ -0,0 +1,12 @@ +package io.visus.solanim.domain.model + +/** + * Data class representing the settings for solar animation. + * + * @property color The color of the solar animation. + * @property rotationSpeed The rotation speed of the solar animation. + */ +data class SolarAnimationSettings( + val color: Int, + val rotationSpeed: Float +) diff --git a/app/src/main/java/io/visus/solanim/domain/repository/SolarAnimationSettingsRepository.kt b/app/src/main/java/io/visus/solanim/domain/repository/SolarAnimationSettingsRepository.kt new file mode 100644 index 0000000..3b84a11 --- /dev/null +++ b/app/src/main/java/io/visus/solanim/domain/repository/SolarAnimationSettingsRepository.kt @@ -0,0 +1,30 @@ +package io.visus.solanim.domain.repository + +import io.visus.solanim.domain.model.SolarAnimationSettings +import kotlinx.coroutines.flow.Flow + +/** + * Repository interface for managing solar animation settings. + */ +interface SolarAnimationSettingsRepository { + /** + * Retrieves the current solar animation settings as a flow. + * + * @return A flow emitting the current [SolarAnimationSettings]. + */ + fun getSettings(): Flow + + /** + * Updates the color of the solar animation. + * + * @param color The new color value. + */ + suspend fun updateColor(color: Int) + + /** + * Updates the rotation speed of the solar animation. + * + * @param speed The new rotation speed value. + */ + suspend fun updateRotationSpeed(speed: Float) +} \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/domain/repository/SolarAnimationSettingsRepositoryImpl.kt b/app/src/main/java/io/visus/solanim/domain/repository/SolarAnimationSettingsRepositoryImpl.kt new file mode 100644 index 0000000..0f7d7f1 --- /dev/null +++ b/app/src/main/java/io/visus/solanim/domain/repository/SolarAnimationSettingsRepositoryImpl.kt @@ -0,0 +1,45 @@ +package io.visus.solanim.domain.repository + +import io.visus.solanim.domain.model.SolarAnimationDefaults +import io.visus.solanim.domain.model.SolarAnimationSettings +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update + +/** + * Implementation of [SolarAnimationSettingsRepository] using in-memory storage. + */ +class SolarAnimationSettingsRepositoryImpl : SolarAnimationSettingsRepository { + private val _settings: MutableStateFlow = MutableStateFlow( + SolarAnimationSettings( + color = SolarAnimationDefaults.DEFAULT_COLOR, + rotationSpeed = SolarAnimationDefaults.DEFAULT_ROTATION_SPEED + ) + ) + + /** + * Retrieves the current solar animation settings as a flow. + * + * @return A flow emitting the current [SolarAnimationSettings]. + */ + override fun getSettings(): Flow = _settings.asStateFlow() + + /** + * Updates the color of the solar animation. + * + * @param color The new color value. + */ + override suspend fun updateColor(color: Int) { + _settings.update { it.copy(color = color) } + } + + /** + * Updates the rotation speed of the solar animation. + * + * @param speed The new rotation speed value. + */ + override suspend fun updateRotationSpeed(speed: Float) { + _settings.update { it.copy(rotationSpeed = speed) } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/domain/usecase/GetSettingsUseCase.kt b/app/src/main/java/io/visus/solanim/domain/usecase/GetSettingsUseCase.kt new file mode 100644 index 0000000..4178845 --- /dev/null +++ b/app/src/main/java/io/visus/solanim/domain/usecase/GetSettingsUseCase.kt @@ -0,0 +1,12 @@ +package io.visus.solanim.domain.usecase + +import io.visus.solanim.domain.repository.SolarAnimationSettingsRepository + +/** + * Use case for retrieving solar animation settings. + * + * @property repository The repository to access solar animation settings. + */ +class GetSettingsUseCase(private val repository: SolarAnimationSettingsRepository) { + operator fun invoke() = repository.getSettings() +} \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/domain/usecase/UpdateColorUseCase.kt b/app/src/main/java/io/visus/solanim/domain/usecase/UpdateColorUseCase.kt new file mode 100644 index 0000000..27b6844 --- /dev/null +++ b/app/src/main/java/io/visus/solanim/domain/usecase/UpdateColorUseCase.kt @@ -0,0 +1,12 @@ +package io.visus.solanim.domain.usecase + +import io.visus.solanim.domain.repository.SolarAnimationSettingsRepository + +/** + * Use case for updating the color of the solar animation. + * + * @property repository The repository to access solar animation settings. + */ +class UpdateColorUseCase(private val repository: SolarAnimationSettingsRepository) { + suspend operator fun invoke(color: Int) = repository.updateColor(color) +} \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/domain/usecase/UpdateRotationSpeedUseCase.kt b/app/src/main/java/io/visus/solanim/domain/usecase/UpdateRotationSpeedUseCase.kt new file mode 100644 index 0000000..2905730 --- /dev/null +++ b/app/src/main/java/io/visus/solanim/domain/usecase/UpdateRotationSpeedUseCase.kt @@ -0,0 +1,12 @@ +package io.visus.solanim.domain.usecase + +import io.visus.solanim.domain.repository.SolarAnimationSettingsRepository + +/** + * Use case for updating the rotation speed of the solar animation. + * + * @property repository The repository to access solar animation settings. + */ +class UpdateRotationSpeedUseCase(private val repository: SolarAnimationSettingsRepository) { + suspend operator fun invoke(rotationSpeed: Float) = repository.updateRotationSpeed(rotationSpeed) +} \ No newline at end of file diff --git a/app/src/main/java/io/visus/solanim/presentation/ui/MainActivity.kt b/app/src/main/java/io/visus/solanim/presentation/ui/MainActivity.kt new file mode 100644 index 0000000..5858fd5 --- /dev/null +++ b/app/src/main/java/io/visus/solanim/presentation/ui/MainActivity.kt @@ -0,0 +1,136 @@ +package io.visus.solanim.presentation.ui + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.github.skydoves.colorpicker.compose.BrightnessSlider +import com.github.skydoves.colorpicker.compose.ColorEnvelope +import com.github.skydoves.colorpicker.compose.HsvColorPicker +import com.github.skydoves.colorpicker.compose.rememberColorPickerController +import io.visus.solanim.R +import io.visus.solanim.presentation.viewmodel.MainUiState +import io.visus.solanim.presentation.viewmodel.MainViewModel +import io.visus.solanim.ui.AppTheme +import io.visus.solanim.ui.components.Scaffold +import io.visus.solanim.ui.components.Slider +import io.visus.solanim.ui.components.SliderDefaults +import io.visus.solanim.ui.components.Text +import io.visus.solanim.ui.components.topbar.TopBar +import io.visus.solanim.ui.components.topbar.TopBarDefaults +import org.koin.androidx.viewmodel.ext.android.viewModel + +class MainActivity : ComponentActivity() { + private val mainViewModel: MainViewModel by viewModel() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + enableEdgeToEdge( + statusBarStyle = SystemBarStyle.dark( + scrim = android.graphics.Color.TRANSPARENT + ) + ) + + setContent { + val uiState by mainViewModel.uiState.collectAsState() + + AppTheme { + App( + uiState = uiState, + onRotationSpeedValueChange = { mainViewModel.onRotationSpeedChange(it) }, + onColorChange = { mainViewModel.onSelectColorChange(it.color.toArgb()) } + ) + } + } + } +} + +@Composable +fun App( + uiState: MainUiState, + onRotationSpeedValueChange: (Float) -> Unit, + onColorChange: (ColorEnvelope) -> Unit, +) { + Scaffold( + containerColor = Color.Transparent, + modifier = Modifier + .fillMaxSize() + .background(AppTheme.colors.defaultBackgroundGradient), + topBar = { + TopBar( + colors = TopBarDefaults.topBarColors( + containerColor = Color.Transparent, + ), + modifier = Modifier + .fillMaxWidth() + ) { + Column( + modifier = Modifier.padding(horizontal = 72.dp) + ) { + Text( + text = stringResource( + R.string.rotation_speed, + uiState.rotationSpeed + ), + color = AppTheme.colors.white, + ) + Slider( + value = uiState.rotationSpeed, + onValueChange = onRotationSpeedValueChange, + valueRange = 0f..2f, + colors = SliderDefaults.colors( + thumbColor = AppTheme.colors.tertiary, + activeTrackColor = AppTheme.colors.tertiary, + inactiveTrackColor = AppTheme.colors.tertiary.copy(alpha = 0.3f), + ), + modifier = Modifier.fillMaxWidth() + ) + } + } + }, + bottomBar = { + val colorPickerController = rememberColorPickerController() + + Column( + modifier = Modifier + .fillMaxWidth() + .background(Color.Transparent) + .padding(vertical = 96.dp, horizontal = 32.dp) + ) { + HsvColorPicker( + modifier = Modifier + .fillMaxWidth() + .height(150.dp), + controller = colorPickerController, + initialColor = Color(uiState.selectedColor), + onColorChanged = onColorChange + + ) + BrightnessSlider( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 10.dp) + .height(16.dp), + controller = colorPickerController, + initialColor = Color(uiState.selectedColor) + ) + } + } + ) { } +} diff --git a/app/src/main/java/io/visus/solanim/presentation/viewmodel/MainViewModel.kt b/app/src/main/java/io/visus/solanim/presentation/viewmodel/MainViewModel.kt new file mode 100644 index 0000000..7a59cee --- /dev/null +++ b/app/src/main/java/io/visus/solanim/presentation/viewmodel/MainViewModel.kt @@ -0,0 +1,66 @@ +package io.visus.solanim.presentation.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import io.visus.solanim.domain.model.SolarAnimationDefaults +import io.visus.solanim.domain.usecase.GetSettingsUseCase +import io.visus.solanim.domain.usecase.UpdateColorUseCase +import io.visus.solanim.domain.usecase.UpdateRotationSpeedUseCase +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch + +/** + * ViewModel for the main screen. + */ +class MainViewModel( + getSettingsUseCase: GetSettingsUseCase, + private val updateColorUseCase: UpdateColorUseCase, + private val updateRotationSpeedUseCase: UpdateRotationSpeedUseCase +) : ViewModel() { + + val uiState: StateFlow = getSettingsUseCase() + .map { settings -> + MainUiState( + selectedColor = settings.color, + rotationSpeed = settings.rotationSpeed + ) + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = MainUiState() + ) + + /** + * Updates the selected color. + * + * @param value The new color selected by the user. + */ + fun onSelectColorChange(value: Int) { + viewModelScope.launch { + updateColorUseCase(value) + } + } + + /** + * Updates the rotation speed. + * + * @param value The new value from the rotation speed. + */ + fun onRotationSpeedChange(value: Float) { + viewModelScope.launch { + updateRotationSpeedUseCase(value) + } + } +} + +/** + * UI state for the main screen. + */ +data class MainUiState( + val selectedColor: Int = SolarAnimationDefaults.DEFAULT_COLOR, + val rotationSpeed: Float = SolarAnimationDefaults.DEFAULT_ROTATION_SPEED +) diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..d1569ac --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + Solar Animation + Rotation Speed: %1$.2f + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..faf04e0 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +