feat/#24 WebOS Completion (#25)

#24 WebOS Completion

Co-authored-by: Sayan Datta <sayan@Sayans-MacBook-Air.local>
Reviewed-on: #25
This commit was merged in pull request #25.
This commit is contained in:
2026-04-18 18:59:04 +05:30
parent 857e0b88e6
commit 84e439712c
459 changed files with 11713 additions and 3853 deletions

View 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
View File

@@ -0,0 +1 @@
# MVP scaffold: no custom rules yet.

View 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>

View File

@@ -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() }
}
}
}

View File

@@ -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"),
)
}

View File

@@ -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),
)
}
}
}

View File

@@ -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"),
)
}

View File

@@ -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"),
)
}

View File

@@ -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"),
)
}

View File

@@ -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"),
)
}

View File

@@ -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,
)
}

View 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
}

View File

@@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
kotlin.code.style=official
android.nonTransitiveRClass=true

View 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")