forked from sagnik/Project_Velocity
feat/#24 WebOS Completion (#25)
#24 WebOS Completion Co-authored-by: Sayan Datta <sayan@Sayans-MacBook-Air.local> Reviewed-on: sagnik/Project_Velocity#25
This commit is contained in:
63
android-tablet/app/build.gradle.kts
Normal file
63
android-tablet/app/build.gradle.kts
Normal file
@@ -0,0 +1,63 @@
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
id("org.jetbrains.kotlin.plugin.compose")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.desineuron.velocity.tablet"
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.desineuron.velocity.tablet"
|
||||
minSdk = 28
|
||||
targetSdk = 35
|
||||
versionCode = 1
|
||||
versionName = "1.0.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
useSupportLibrary = true
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
val composeBom = platform("androidx.compose:compose-bom:2025.02.00")
|
||||
|
||||
implementation(composeBom)
|
||||
androidTestImplementation(composeBom)
|
||||
|
||||
implementation("androidx.core:core-ktx:1.15.0")
|
||||
implementation("androidx.activity:activity-compose:1.10.1")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
|
||||
implementation("androidx.navigation:navigation-compose:2.8.5")
|
||||
implementation("androidx.compose.material3:material3")
|
||||
implementation("androidx.compose.ui:ui")
|
||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||
|
||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||
}
|
||||
1
android-tablet/app/proguard-rules.pro
vendored
Normal file
1
android-tablet/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# MVP scaffold: no custom rules yet.
|
||||
17
android-tablet/app/src/main/AndroidManifest.xml
Normal file
17
android-tablet/app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="Velocity Tablet"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@android:style/Theme.DeviceDefault.NoActionBar">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.desineuron.velocity.tablet
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationRail
|
||||
import androidx.compose.material3.NavigationRailItem
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.desineuron.velocity.tablet.features.DashboardScreen
|
||||
import com.desineuron.velocity.tablet.features.InventoryScreen
|
||||
import com.desineuron.velocity.tablet.features.OracleScreen
|
||||
import com.desineuron.velocity.tablet.features.SettingsScreen
|
||||
import com.desineuron.velocity.tablet.features.SentinelScreen
|
||||
import com.desineuron.velocity.tablet.ui.theme.VelocityTabletTheme
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContent {
|
||||
VelocityTabletTheme {
|
||||
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
|
||||
TabletApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class TabletDestination(val route: String, val label: String)
|
||||
|
||||
private val tabletDestinations = listOf(
|
||||
TabletDestination("dashboard", "Dashboard"),
|
||||
TabletDestination("inventory", "Inventory"),
|
||||
TabletDestination("oracle", "Oracle"),
|
||||
TabletDestination("sentinel", "Sentinel"),
|
||||
TabletDestination("settings", "Settings"),
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun TabletApp() {
|
||||
val navController = rememberNavController()
|
||||
val backStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentDestination = backStackEntry?.destination
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color(0xFF05070B)),
|
||||
) {
|
||||
NavigationRail(
|
||||
modifier = Modifier.padding(vertical = 20.dp, horizontal = 12.dp),
|
||||
containerColor = Color(0xFF0D1118),
|
||||
header = {
|
||||
Column(
|
||||
modifier = Modifier.padding(bottom = 20.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text("Velocity", color = Color.White, style = MaterialTheme.typography.titleMedium)
|
||||
Text("Tablet parity", color = Color(0xFF8A93A6), style = MaterialTheme.typography.labelSmall)
|
||||
}
|
||||
},
|
||||
) {
|
||||
tabletDestinations.forEach { destination ->
|
||||
val selected = currentDestination?.hierarchy?.any { it.route == destination.route } == true
|
||||
NavigationRailItem(
|
||||
selected = selected,
|
||||
onClick = {
|
||||
navController.navigate(destination.route) {
|
||||
popUpTo(navController.graph.findStartDestination().id) {
|
||||
saveState = true
|
||||
}
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
},
|
||||
icon = { Box(modifier = Modifier.padding(4.dp)) },
|
||||
label = { Text(destination.label) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = "dashboard",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(24.dp),
|
||||
) {
|
||||
composable("dashboard") { DashboardScreen() }
|
||||
composable("inventory") { InventoryScreen() }
|
||||
composable("oracle") { OracleScreen() }
|
||||
composable("sentinel") { SentinelScreen() }
|
||||
composable("settings") { SettingsScreen() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.desineuron.velocity.tablet.features
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun DashboardScreen() {
|
||||
FeatureScaffold(
|
||||
title = "Dashboard",
|
||||
subtitle = "Sales, sentiment, and operational posture for the field team.",
|
||||
chips = listOf("Visitors live", "Revenue outlook", "Queue health"),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.desineuron.velocity.tablet.features
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun FeatureScaffold(
|
||||
title: String,
|
||||
subtitle: String,
|
||||
chips: List<String>,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color(0xFF05070B))
|
||||
.padding(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(18.dp),
|
||||
) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
Text(title, style = MaterialTheme.typography.headlineMedium, color = Color.White)
|
||||
Text(subtitle, style = MaterialTheme.typography.bodyMedium, color = Color(0xFF94A3B8))
|
||||
}
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
chips.forEach { chip ->
|
||||
Text(
|
||||
text = chip,
|
||||
color = Color.White,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
modifier = Modifier
|
||||
.background(Color(0xFF111827), RoundedCornerShape(14.dp))
|
||||
.padding(horizontal = 14.dp, vertical = 10.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(Color(0xFF0B1220), RoundedCornerShape(28.dp))
|
||||
.padding(22.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
) {
|
||||
Text("Scaffold state", style = MaterialTheme.typography.titleMedium, color = Color.White)
|
||||
Text(
|
||||
"This screen is wired into the tablet navigation graph and is ready for the shared contract package once the API clients are connected.",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF94A3B8),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.desineuron.velocity.tablet.features
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun InventoryScreen() {
|
||||
FeatureScaffold(
|
||||
title = "Inventory",
|
||||
subtitle = "Property catalog, media assets, and ingest lifecycle visibility.",
|
||||
chips = listOf("Import batches", "Listings", "Validation state"),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.desineuron.velocity.tablet.features
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun OracleScreen() {
|
||||
FeatureScaffold(
|
||||
title = "Oracle",
|
||||
subtitle = "Template-guided intelligence views for pipeline and scheduling.",
|
||||
chips = listOf("Pipeline", "Lead map", "Calendar tasks"),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.desineuron.velocity.tablet.features
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun SentinelScreen() {
|
||||
FeatureScaffold(
|
||||
title = "Sentinel",
|
||||
subtitle = "Biometric and sentiment awareness stream for visitor sessions.",
|
||||
chips = listOf("Live session", "Journey river", "QD overlays"),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.desineuron.velocity.tablet.features
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen() {
|
||||
FeatureScaffold(
|
||||
title = "Settings",
|
||||
subtitle = "Surface registration, connection state, and operator preferences.",
|
||||
chips = listOf("Install info", "API endpoint", "Operator profile"),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.desineuron.velocity.tablet.ui.theme
|
||||
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
private val VelocityDarkColors = darkColorScheme(
|
||||
primary = Color(0xFF3B82F6),
|
||||
secondary = Color(0xFF14B8A6),
|
||||
tertiary = Color(0xFF22C55E),
|
||||
background = Color(0xFF05070B),
|
||||
surface = Color(0xFF0B1220),
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.White,
|
||||
onBackground = Color.White,
|
||||
onSurface = Color.White,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun VelocityTabletTheme(content: @Composable () -> Unit) {
|
||||
MaterialTheme(
|
||||
colorScheme = VelocityDarkColors,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
5
android-tablet/build.gradle.kts
Normal file
5
android-tablet/build.gradle.kts
Normal file
@@ -0,0 +1,5 @@
|
||||
plugins {
|
||||
id("com.android.application") version "8.7.3" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.0.21" apply false
|
||||
id("org.jetbrains.kotlin.plugin.compose") version "2.0.21" apply false
|
||||
}
|
||||
4
android-tablet/gradle.properties
Normal file
4
android-tablet/gradle.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
android.useAndroidX=true
|
||||
kotlin.code.style=official
|
||||
android.nonTransitiveRClass=true
|
||||
18
android-tablet/settings.gradle.kts
Normal file
18
android-tablet/settings.gradle.kts
Normal file
@@ -0,0 +1,18 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "velocity-android-tablet"
|
||||
include(":app")
|
||||
Reference in New Issue
Block a user