diff --git a/submissions/T094_Echo&Exit/README.md b/submissions/T094_Echo&Exit/README.md new file mode 100644 index 00000000..1e817606 --- /dev/null +++ b/submissions/T094_Echo&Exit/README.md @@ -0,0 +1,60 @@ + +## Team Name & Team ID + +- Team Name: Echo & Exit +- Team ID: T094 + +## Members and Roles + +| Member | Role | +| --- | --- | +| Rohan| Backend architect and developer | +|Meenakshi | Idea and Presentation | +| Akshaya | Frontend | +| Parthiv | Data analysis on student records | +| RamTeja | Designing and presentation | + +> Please update the list above with real member names and roles. + +## Problem statement selected + +This submission implements the Android application for the selected BuildFest challenge. (Problem statement not found in the repository; please replace this line with the exact problem statement you selected.) + +## Tech stack used + +- Android (mobile) +- Kotlin +- Gradle / Gradle Wrapper +- Android Studio (recommended for development) + +## How to run the project (setup instructions) + +Prerequisites + +- JDK 11 or newer installed and JAVA_HOME set +- Android Studio (recommended) or Android SDK tools + platform tools +- An Android device or emulator + +Recommended (Android Studio) + +1. Open Android Studio. +2. Choose "Open" and select the `code/` folder inside this submission (path: `submissions/T094_Echo&Exit/code`). +3. Let Android Studio sync Gradle and download dependencies. +4. Run the app using the Run button or create an emulator and install to it. + +Command line (Windows PowerShell) + +From the root of this submission (where this README is located), run: + +```powershell +# Build debug APK +.\code\gradlew.bat assembleDebug + +# Install debug build to a connected device/emulator +.\code\gradlew.bat installDebug +``` + +Notes: + +- If you get "permission" errors running the wrapper, ensure `gradlew.bat` is executable; running from PowerShell as a normal user should work on Windows. +- The build requires a valid Android SDK installation. If local SDK path is not detected, confirm `local.properties` in `code/` points to your SDK (`sdk.dir=`). diff --git a/submissions/T094_Echo&Exit/T094_Echo&Exit.pdf b/submissions/T094_Echo&Exit/T094_Echo&Exit.pdf new file mode 100644 index 00000000..a887176f Binary files /dev/null and b/submissions/T094_Echo&Exit/T094_Echo&Exit.pdf differ diff --git a/submissions/T094_Echo&Exit/code/.gitignore b/submissions/T094_Echo&Exit/code/.gitignore new file mode 100644 index 00000000..aa724b77 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/submissions/T094_Echo&Exit/code/Vida.png b/submissions/T094_Echo&Exit/code/Vida.png new file mode 100644 index 00000000..87937f13 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/Vida.png differ diff --git a/submissions/T094_Echo&Exit/code/app/.gitignore b/submissions/T094_Echo&Exit/code/app/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/build.gradle.kts b/submissions/T094_Echo&Exit/code/app/build.gradle.kts new file mode 100644 index 00000000..952c71c9 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/build.gradle.kts @@ -0,0 +1,59 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) +} + +android { + namespace = "com.demo.vida" + compileSdk = 36 + + defaultConfig { + applicationId = "com.demo.vida" + minSdk = 32 + 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_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } + buildFeatures { + compose = true + } +} + +dependencies { + implementation("com.github.bumptech.glide:glide:4.16.0") + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + 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/submissions/T094_Echo&Exit/code/app/proguard-rules.pro b/submissions/T094_Echo&Exit/code/app/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/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/submissions/T094_Echo&Exit/code/app/src/androidTest/java/com/demo/vida/ExampleInstrumentedTest.kt b/submissions/T094_Echo&Exit/code/app/src/androidTest/java/com/demo/vida/ExampleInstrumentedTest.kt new file mode 100644 index 00000000..161bc7d3 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/androidTest/java/com/demo/vida/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.demo.vida + +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("com.demo.vida", appContext.packageName) + } +} \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/src/main/AndroidManifest.xml b/submissions/T094_Echo&Exit/code/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..52143354 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/submissions/T094_Echo&Exit/code/app/src/main/ic_launcher-playstore.png b/submissions/T094_Echo&Exit/code/app/src/main/ic_launcher-playstore.png new file mode 100644 index 00000000..81ca9746 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/ic_launcher-playstore.png differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/MainActivity.kt b/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/MainActivity.kt new file mode 100644 index 00000000..70913b20 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/MainActivity.kt @@ -0,0 +1,363 @@ +package com.demo.vida + +import android.Manifest +import android.annotation.SuppressLint +import android.content.ActivityNotFoundException +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.webkit.GeolocationPermissions +import android.webkit.ValueCallback +import android.webkit.WebChromeClient +import android.webkit.WebResourceRequest +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.Toast +import androidx.activity.ComponentActivity +import androidx.activity.OnBackPressedCallback +import androidx.activity.compose.setContent +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.content.ContextCompat +import androidx.core.net.toUri +import com.demo.vida.ui.theme.VidaTheme + +// Sealed class to represent the different permission states +sealed class PermissionStatus { + object Loading : PermissionStatus() + object Granted : PermissionStatus() + object Denied : PermissionStatus() +} + +class MainActivity : ComponentActivity() { + + private var permissionStatus by mutableStateOf(PermissionStatus.Loading) + private lateinit var webView: WebView + + // --- File Chooser State (CRITICAL FIX FOR FILE UPLOADS) --- + // 1. Holds the callback provided by the WebView for when the user selects a file. + private var filePathCallback: ValueCallback>? = null + + // 2. Launcher to handle the result of the native file selection Intent. + private val fileChooserLauncher: ActivityResultLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + // Determine the result URI(s) from the Intent data + val results: Array? = if (result.data == null || result.resultCode != RESULT_OK) { + null + } else { + result.data?.data?.let { arrayOf(it) } ?: result.data?.clipData?.let { clipData -> + // Handle multiple files if selected + Array(clipData.itemCount) { i -> clipData.getItemAt(i).uri } + } + } + + // Pass the result back to the WebView's JavaScript via the stored callback + filePathCallback?.onReceiveValue(results) + filePathCallback = null // Clear the callback after use + } + // ----------------------------------------------------------- + + // Use the ActivityResultLauncher for a modern way to request permissions + private val requestPermissionLauncher: ActivityResultLauncher> = + registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { isGranted -> + // Check if ALL mandatory permissions were granted + val allPermissionsGranted = isGranted.values.all { it } + if (allPermissionsGranted) { + permissionStatus = PermissionStatus.Granted + Toast.makeText(this, "All required permissions granted!", Toast.LENGTH_SHORT).show() + } else { + permissionStatus = PermissionStatus.Denied + Toast.makeText(this, "One or more permissions were denied. Check logs for details.", Toast.LENGTH_LONG).show() + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + if (::webView.isInitialized && webView.canGoBack()) { + webView.goBack() + } else { + // If the WebView cannot go back, disable this callback and let the default back press behavior occur + isEnabled = false + onBackPressedDispatcher.onBackPressed() + // Re-enable the callback if you want it to be active for future back presses + // isEnabled = true + } + } + }) + + setContent { + VidaTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + // Check the current permission status and show the appropriate UI + when (permissionStatus) { + is PermissionStatus.Loading, is PermissionStatus.Denied -> { + PermissionHandler(permissionStatus, requestPermissionLauncher) { status -> + permissionStatus = status + } + } + is PermissionStatus.Granted -> { + MyWebView( + onWebViewReady = { webViewInstance -> + webView = webViewInstance + }, + // Inject dependencies required for file upload handling + fileChooserLauncher = fileChooserLauncher, + setFilePathCallback = { callback -> filePathCallback = callback } + ) + } + } + } + } + } + } +} + +@Composable +fun PermissionHandler( + permissionStatus: PermissionStatus, + requestPermissionLauncher: ActivityResultLauncher>, + onStatusChange: (PermissionStatus) -> Unit // Callback to update state in MainActivity +) { + val context = LocalContext.current + + // Dynamically build the list of permissions required based on Android version + val permissionsToRequest = remember { + mutableListOf().apply { + // --- LOCATION PERMISSIONS (NEWLY ADDED) --- + add(Manifest.permission.ACCESS_FINE_LOCATION) + add(Manifest.permission.ACCESS_COARSE_LOCATION) + + // --- CORE APP PERMISSIONS --- + add(Manifest.permission.POST_NOTIFICATIONS) + add(Manifest.permission.CAMERA) + add(Manifest.permission.RECORD_AUDIO) + + // --- STORAGE/MEDIA PERMISSIONS (Handle API 33+ vs older) --- + add(Manifest.permission.READ_MEDIA_IMAGES) + add(Manifest.permission.READ_MEDIA_VIDEO) + add(Manifest.permission.READ_MEDIA_AUDIO) + }.toTypedArray() + } + + LaunchedEffect(Unit) { + val ungrantedPermissions = permissionsToRequest.filter { + ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED + }.toTypedArray() + + if (ungrantedPermissions.isNotEmpty()) { + requestPermissionLauncher.launch(ungrantedPermissions) + } else { + // Permissions were already granted, so update the state directly + onStatusChange(PermissionStatus.Granted) + } + } + + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + // Show different UI based on the permission status + when (permissionStatus) { + is PermissionStatus.Loading -> { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + CircularProgressIndicator() + Text( + text = "Checking permissions, including Location...", + modifier = Modifier.padding(16.dp), + textAlign = TextAlign.Center + ) + } + } + is PermissionStatus.Denied -> { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + Text( + text = "Permissions (including Location) are required to use this application. Please grant all permissions to continue.", + modifier = Modifier.padding(horizontal = 24.dp), + textAlign = TextAlign.Center + ) + Button(onClick = { + // Launch the permission request again + requestPermissionLauncher.launch(permissionsToRequest) + }) { + Text("Grant Permissions") + } + } + } + is PermissionStatus.Granted -> { + // The main activity will handle this state + } + } + } +} + +// Custom WebViewClient to intercept URLs and launch external apps (like Maps) +class VidaWebViewClient : WebViewClient() { + override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { + val url = request?.url.toString() + + // 1. Check if the URL is a Google Maps link (using the standard HTTPS format) + if (url.startsWith("https://www.google.com/maps/") || url.startsWith("https://maps.google.com/") || url.startsWith("geo:")) { + try { + // Manually create an Intent to view the URI + val intent = Intent(Intent.ACTION_VIEW, url.toUri()) + + // Add this flag to ensure the activity is started in a new task (necessary for external apps) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + // Launch the external application (which triggers the Maps prompt) + view?.context?.startActivity(intent) + + // Return true to indicate that we handled the navigation and the WebView should NOT load the URL internally. + return true + } catch (e: ActivityNotFoundException) { + // Log and optionally show a toast if no app can handle the URL + Log.e("VidaWebViewClient", "No app found to handle Maps URL: $url", e) + Toast.makeText(view?.context, "Could not open map. Please ensure Google Maps is installed.", Toast.LENGTH_LONG).show() + // Return false to let the WebView try to load the URL as a regular page (fallback) + return false + } + } + + // 2. For all other URLs (e.g., vidamedicare.blogspot.com), + // return false to let the WebView handle the loading internally. + return false + } +} + +// Custom WebChromeClient to handle browser events, including Geolocation and File Chooser +class VidaWebChromeClient( + // Dependencies injected from MainActivity for file upload + private val fileChooserLauncher: ActivityResultLauncher, + private val setFilePathCallback: (ValueCallback>?) -> Unit +) : WebChromeClient() { + + // Existing Geolocation handler + override fun onGeolocationPermissionsShowPrompt( + origin: String?, + callback: GeolocationPermissions.Callback? + ) { + // Since the main Android location permission is handled by PermissionHandler, + // we can grant this access to the specific web origin automatically. + callback?.invoke(origin, true, false) // Grant access, and don't remember the preference + } + + // NEW: File Chooser handler for + override fun onShowFileChooser( + webView: WebView?, + filePathCallback: ValueCallback>?, + fileChooserParams: FileChooserParams? + ): Boolean { + // 1. Store the callback using the lambda passed from the Activity + setFilePathCallback(filePathCallback) + + // 2. Create and launch the intent to open the native file picker + val intent = fileChooserParams?.createIntent() + if (intent != null) { + try { + fileChooserLauncher.launch(intent) + } catch (e: Exception) { + // Handle failure to launch the intent + setFilePathCallback(null) // Clear the callback if launch fails + Log.e("VidaWebChromeClient", "Cannot open file chooser", e) + return false + } + } else { + setFilePathCallback(null) + return false + } + + return true + } +} + +@Preview(showBackground = true) +@Composable +fun DefaultPreview() { + VidaTheme { + // NOTE: Preview cannot properly run MyWebView without the required activity result launchers. + Text("WebView Preview requires launcher dependencies.") + } +} + +@SuppressLint("SetJavaScriptEnabled") +@Composable +fun MyWebView( + modifier: Modifier = Modifier, + onWebViewReady: (WebView) -> Unit, + fileChooserLauncher: ActivityResultLauncher, // NEW: Dependency for file upload + setFilePathCallback: (ValueCallback>?) -> Unit // NEW: Dependency for file upload +) { + + AndroidView( + modifier = modifier.fillMaxSize(), + factory = { context -> + WebView(context).apply { + settings.javaScriptEnabled = true + settings.domStorageEnabled = true + settings.cacheMode = WebSettings.LOAD_DEFAULT + + // START: FIXES FOR CHATBOT WIDGET VISIBILITY + // These two settings are CRITICAL for correctly positioning 'position: fixed' elements + // relative to the device viewport, preventing them from disappearing. + settings.useWideViewPort = true + settings.loadWithOverviewMode = true + + // CRITICAL NEW FIX: Force WebView to use hardware acceleration for rendering. + // This improves performance and fixes positioning issues for fixed elements. + setLayerType(android.view.View.LAYER_TYPE_HARDWARE, null) + // END: FIXES FOR CHATBOT WIDGET VISIBILITY + + // Enable Geolocation for the WebView + settings.setGeolocationEnabled(true) + + // Set the custom WebChromeClient to handle Geolocation AND File Chooser requests + webChromeClient = VidaWebChromeClient( + fileChooserLauncher = fileChooserLauncher, + setFilePathCallback = setFilePathCallback + ) + + // *** CRITICAL UPDATE: Apply the custom WebViewClient for URL interception *** + webViewClient = VidaWebViewClient() + + loadUrl("https://smartagrigo.blogspot.com/") + onWebViewReady(this) // Pass the WebView instance back + } + } + ) +} diff --git a/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Color.kt b/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Color.kt new file mode 100644 index 00000000..8c6633cd --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Color.kt @@ -0,0 +1,11 @@ +package com.demo.vida.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Theme.kt b/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Theme.kt new file mode 100644 index 00000000..0c24bef5 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Theme.kt @@ -0,0 +1,58 @@ +package com.demo.vida.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun VidaTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Type.kt b/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Type.kt new file mode 100644 index 00000000..41a74f83 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/java/com/demo/vida/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package com.demo.vida.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/drawable/ic_launcher_background.xml b/submissions/T094_Echo&Exit/code/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..ca3826a4 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/drawable/ic_launcher_foreground.xml b/submissions/T094_Echo&Exit/code/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 00000000..2b068d11 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 00000000..c4a603d4 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 00000000..c4a603d4 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 00000000..3cb84e09 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp new file mode 100644 index 00000000..0a9e55b2 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 00000000..e7c3ea8a Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 00000000..e3e06a00 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp new file mode 100644 index 00000000..3c3ffb1b Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 00000000..3646a260 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 00000000..a3b1e63a Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp new file mode 100644 index 00000000..128d4f09 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 00000000..50cd0959 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 00000000..b5db27f8 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp new file mode 100644 index 00000000..a7a30046 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 00000000..b1145d27 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 00000000..1fc3dd8b Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 00000000..c0f17934 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 00000000..339d1b5a Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/raw/splash.gif b/submissions/T094_Echo&Exit/code/app/src/main/res/raw/splash.gif new file mode 100644 index 00000000..debed061 Binary files /dev/null and b/submissions/T094_Echo&Exit/code/app/src/main/res/raw/splash.gif differ diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/values/colors.xml b/submissions/T094_Echo&Exit/code/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..f8c6127d --- /dev/null +++ b/submissions/T094_Echo&Exit/code/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/submissions/T094_Echo&Exit/code/app/src/main/res/values/strings.xml b/submissions/T094_Echo&Exit/code/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..c8a39661 --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + AgriGo + Splash screen image + \ No newline at end of file diff --git a/submissions/T094_Echo&Exit/code/app/src/main/res/values/themes.xml b/submissions/T094_Echo&Exit/code/app/src/main/res/values/themes.xml new file mode 100644 index 00000000..73b204eb --- /dev/null +++ b/submissions/T094_Echo&Exit/code/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +