Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 1 addition & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
name: TrackPro DevSecOps Pipeline

on:
push:
branches: [ "main", "develop" ]
Expand All @@ -12,52 +10,26 @@ permissions:
actions: read

jobs:
build-test-and-secure:
runs-on: ubuntu-latest

steps:
# 1. Fetch your code (Crucial: fetch-depth 0 gives scanners the full git commit history)
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0

# 2. SECRET SCANNING: Scans your recent commits for accidentally leaked API keys/tokens
- name: Run TruffleHog Secret Scanner
uses: trufflesecurity/trufflehog@main
with:
base: ${{ github.event.repository.default_branch }}
head: HEAD

# 3. Set up environment for Java/Kotlin
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'

# 4. Cache Gradle to keep builds lighting fast
- name: Setup Gradle Cache
uses: gradle/actions/setup-gradle@v3

# 5. Give execution rights to Gradle
- name: Grant Execute Permission for Gradle
run: chmod +x gradlew

# 6. SAST INITIALIZATION: Sets up GitHub's CodeQL engine to observe the build
- name: Initialize CodeQL (SAST)
uses: github/codeql-action/init@v3
with:
languages: 'java-kotlin'

# 7. Quality Gates: Run your unit tests
- name: Run Local Unit Tests
run: ./gradlew testDebugUnitTest

# 8. Build the App (CodeQL automatically scans the code while Gradle builds it here!)
- name: Build Debug App
run: ./gradlew assembleDebug

# 9. SAST ANALYSIS: Finalize analysis and upload vulnerabilities to your GitHub Security Tab
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
run: ./gradlew assembleDebug
73 changes: 36 additions & 37 deletions app/src/main/java/com/example/trackpro/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.example.trackpro

import TrackProTheme
import com.example.trackpro.extrasForUI.TrackProTheme
import android.Manifest
import android.app.Application
import android.os.Bundle
Expand Down Expand Up @@ -79,7 +79,6 @@ import com.example.trackpro.screens.listViewScreens.lapDetail.LapDetailScreen
import com.example.trackpro.screens.listViewScreens.listItems.CarViewScreen
import com.example.trackpro.screens.listViewScreens.listItems.GraphScreen
import com.example.trackpro.screens.listViewScreens.listItems.TimeAttackListItemScreen
import com.example.trackpro.theme.TrackProColors
import com.example.trackpro.viewModels.DragSessionViewModel
import com.example.trackpro.viewModels.DragSessionViewModelFactory
import com.example.trackpro.viewModels.SessionViewModel
Expand Down Expand Up @@ -293,14 +292,14 @@ fun MainScreen(
drawerState = drawerState,
drawerContent = {
ModalDrawerSheet(
drawerContainerColor = TrackProColors.BgCard,
drawerContentColor = TrackProColors.TextPrimary
drawerContainerColor = TrackProTheme.colors.bgCard,
drawerContentColor = TrackProTheme.colors.textPrimary
) {
// Drawer header
Box(
modifier = Modifier
.fillMaxWidth()
.background(TrackProColors.AccentRed)
.background(TrackProTheme.colors.accentCyan)
.padding(horizontal = 24.dp, vertical = 20.dp)
) {
Column {
Expand All @@ -326,55 +325,55 @@ fun MainScreen(
DrawerItem(
icon = Icons.Default.RocketLaunch,
label = "Drag Sessions",
tint = TrackProColors.AccentRed,
tint = TrackProTheme.colors.accentCyan,
onClick = { onNavigateToDragTimesList(); scope.launch { drawerState.close() } }
)
DrawerItem(
icon = Icons.Default.FlagCircle,
label = "Track Sessions",
tint = TrackProColors.AccentGreen,
tint = TrackProTheme.colors.accentBlue,
onClick = { onNavigateToTimeAttackListView(); scope.launch { drawerState.close() } }
)
}

HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
thickness = 1.dp,
color = TrackProColors.SectorLine
color = TrackProTheme.colors.sectorLine
)

DrawerSection(title = "MANAGEMENT") {
DrawerItem(
icon = Icons.Default.Timelapse,
label = "My Tracks",
tint = TrackProColors.AccentAmber,
tint = TrackProTheme.colors.accentAmber,
onClick = { onNavigateToTrackListScreen(); scope.launch { drawerState.close() } }
)
DrawerItem(
icon = Icons.Default.CarRepair,
label = "My Vehicles",
tint = TrackProColors.AccentAmber,
tint = TrackProTheme.colors.accentAmber,
onClick = { onNavigateToVehicleList(); scope.launch { drawerState.close() } }
)
}

HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
thickness = 1.dp,
color = TrackProColors.SectorLine
color = TrackProTheme.colors.sectorLine
)

DrawerSection(title = "SYSTEM") {
DrawerItem(
icon = Icons.Default.Wifi,
label = "ESP Connection",
tint = TrackProColors.TextMuted,
tint = TrackProTheme.colors.textMuted,
onClick = { onNavigateToESPTestScreen(); scope.launch { drawerState.close() } }
)
DrawerItem(
icon = Icons.Default.Settings,
label = "Settings",
tint = TrackProColors.TextMuted,
tint = TrackProTheme.colors.textMuted,
onClick = { onNavigateToSettings();scope.launch { drawerState.close() } }
)
}
Expand All @@ -384,15 +383,15 @@ fun MainScreen(
Box(
modifier = Modifier
.fillMaxSize()
.background(TrackProColors.BgDeep)
.background(TrackProTheme.colors.bgDeep)
) {
Column(modifier = Modifier.fillMaxSize()) {

// ── Top bar ───────────────────────────────────
Box(
modifier = Modifier
.fillMaxWidth()
.background(TrackProColors.BgCard)
.background(TrackProTheme.colors.bgCard)
.padding(horizontal = 8.dp, vertical = 4.dp)
) {
Row(
Expand All @@ -402,11 +401,11 @@ fun MainScreen(
) {
IconButton(onClick = { scope.launch { drawerState.open() } }) {
Icon(Icons.Default.Menu, contentDescription = "Menu",
tint = TrackProColors.TextPrimary)
tint = TrackProTheme.colors.textPrimary)
}
Text(
text = "TRACKPRO",
color = TrackProColors.AccentRed,
color = TrackProTheme.colors.accentCyan,
fontSize = 14.sp,
fontWeight = FontWeight.Black,
letterSpacing = 4.sp
Expand All @@ -416,13 +415,13 @@ fun MainScreen(
}
}

HorizontalDivider(color = TrackProColors.SectorLine, thickness = 1.dp)
HorizontalDivider(color = TrackProTheme.colors.sectorLine, thickness = 1.dp)

// ── Hero section ──────────────────────────────
Box(
modifier = Modifier
.fillMaxWidth()
.background(TrackProColors.BgCard)
.background(TrackProTheme.colors.bgCard)
.padding(horizontal = 28.dp, vertical = 32.dp)
) {
Column {
Expand All @@ -431,12 +430,12 @@ fun MainScreen(
modifier = Modifier
.width(40.dp)
.height(3.dp)
.background(TrackProColors.AccentRed)
.background(TrackProTheme.colors.accentCyan)
)
Spacer(Modifier.height(12.dp))
Text(
text = "READY TO\nBEAT RECORDS?",
color = TrackProColors.TextPrimary,
color = TrackProTheme.colors.textPrimary,
fontSize = 32.sp,
fontWeight = FontWeight.Black,
letterSpacing = (-0.5).sp,
Expand All @@ -445,14 +444,14 @@ fun MainScreen(
Spacer(Modifier.height(8.dp))
Text(
text = "GPS telemetry · Lap timing · Performance analysis",
color = TrackProColors.TextMuted,
color = TrackProTheme.colors.textMuted,
fontSize = 12.sp,
letterSpacing = 0.5.sp
)
}
}

HorizontalDivider(color = TrackProColors.SectorLine, thickness = 1.dp)
HorizontalDivider(color = TrackProTheme.colors.sectorLine, thickness = 1.dp)

// ── Action grid ───────────────────────────────
Column(
Expand All @@ -468,7 +467,7 @@ fun MainScreen(
icon = Icons.Default.RocketLaunch,
title = "DRAG TIMING",
subtitle = "0–100 · ¼ mile · speed trace",
accentColor = TrackProColors.AccentRed,
accentColor = TrackProTheme.colors.accentCyan,
onClick = onNavigateToDragRace,
fullWidth = true
)
Expand All @@ -477,15 +476,15 @@ fun MainScreen(
icon = Icons.Default.FlagCircle,
title = "LAP TIMING",
subtitle = "Circuit & sprint · live delta · best lap",
accentColor = TrackProColors.AccentGreen,
accentColor = TrackProTheme.colors.accentBlue,
onClick = onNavigateToTrackVehicleSelector,
fullWidth = true
)

HorizontalDivider(
modifier = Modifier.padding(vertical = 4.dp),
thickness = 1.dp,
color = TrackProColors.SectorLine
color = TrackProTheme.colors.sectorLine
)

// Secondary actions — 2 column grid
Expand All @@ -498,7 +497,7 @@ fun MainScreen(
icon = Icons.Default.CarRepair,
title = "ADD VEHICLES",
subtitle = "Create your own vehicles",
accentColor = TrackProColors.AccentAmber,
accentColor = TrackProTheme.colors.accentAmber,
onClick = onNavigateToVehicleCreatorScreen,
halfWidth = true
)
Expand All @@ -508,7 +507,7 @@ fun MainScreen(
icon = Icons.Default.Timelapse,
title = "TRACK\nBUILDER",
subtitle = "Define tracks",
accentColor = TrackProColors.AccentAmber,
accentColor = TrackProTheme.colors.accentAmber,
onClick = onNavigateToTrackBuilder,
halfWidth = true
)
Expand All @@ -524,7 +523,7 @@ fun MainScreen(
icon = Icons.Default.Wifi,
title = "ESP\nCONNECT",
subtitle = "Test connection",
accentColor = TrackProColors.TextMuted,
accentColor = TrackProTheme.colors.textMuted,
onClick = onNavigateToESPTestScreen,
halfWidth = true
)
Expand All @@ -534,7 +533,7 @@ fun MainScreen(
icon = Icons.Default.Settings,
title = "SETTINGS",
subtitle = "Global settings",
accentColor = TrackProColors.TextMuted,
accentColor = TrackProTheme.colors.textMuted,
onClick = onNavigateToSettings,
halfWidth = true,
)
Expand All @@ -546,7 +545,7 @@ fun MainScreen(
// Version tag
Text(
text = "TrackPro · GPS Telemetry System",
color = TrackProColors.TextMuted.copy(alpha = 0.4f),
color = TrackProTheme.colors.textMuted.copy(alpha = 0.4f),
fontSize = 10.sp,
letterSpacing = 1.sp,
modifier = Modifier.align(Alignment.CenterHorizontally)
Expand Down Expand Up @@ -581,8 +580,8 @@ private fun ActionCard(
Box(
modifier = Modifier
.fillMaxWidth()
.background(TrackProColors.BgCard, RoundedCornerShape(10.dp))
.border(1.dp, TrackProColors.SectorLine, RoundedCornerShape(10.dp))
.background(TrackProTheme.colors.bgCard, RoundedCornerShape(10.dp))
.border(1.dp, TrackProTheme.colors.sectorLine, RoundedCornerShape(10.dp))
.then(if (!disabled) Modifier.clickable(onClick = onClick) else Modifier)
) {
// Left accent bar
Expand Down Expand Up @@ -621,7 +620,7 @@ private fun ActionCard(
Column(modifier = Modifier.weight(1f)) {
Text(
text = title,
color = TrackProColors.TextPrimary.copy(alpha = alpha),
color = TrackProTheme.colors.textPrimary.copy(alpha = alpha),
fontSize = titleSize,
fontWeight = FontWeight.Black,
letterSpacing = 0.5.sp, // reduced from 1.sp
Expand All @@ -630,7 +629,7 @@ private fun ActionCard(
)
Text(
text = subtitle,
color = TrackProColors.TextMuted.copy(alpha = alpha),
color = TrackProTheme.colors.textMuted.copy(alpha = alpha),
fontSize = subtitleSize,
letterSpacing = 0.sp,
maxLines = 2,
Expand All @@ -656,7 +655,7 @@ private fun ActionCard(
private fun DrawerSection(title: String, content: @Composable () -> Unit) {
Text(
text = title,
color = TrackProColors.TextMuted,
color = TrackProTheme.colors.textMuted,
fontSize = 9.sp,
fontWeight = FontWeight.Black,
letterSpacing = 3.sp,
Expand Down Expand Up @@ -688,7 +687,7 @@ private fun DrawerItem(
) {
Icon(icon, contentDescription = label, tint = tint, modifier = Modifier.size(16.dp))
}
Text(label, color = TrackProColors.TextPrimary, fontSize = 14.sp, fontWeight = FontWeight.Bold)
Text(label, color = TrackProTheme.colors.textPrimary, fontSize = 14.sp, fontWeight = FontWeight.Bold)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.example.trackpro.extrasForUI

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.foundation.isSystemInDarkTheme
import com.example.trackpro.theme.DarkTrackProColors
import com.example.trackpro.theme.LightTrackProColors
import com.example.trackpro.theme.TrackProColorScheme

private val LocalTrackProColors = staticCompositionLocalOf { DarkTrackProColors }

// 2. Create an elegant accessor object for UI code
object TrackProTheme {
val colors: TrackProColorScheme
@Composable
@ReadOnlyComposable
get() = LocalTrackProColors.current
}

@Composable
fun TrackProTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colorScheme = if (darkTheme) DarkTrackProColors else LightTrackProColors

CompositionLocalProvider(
LocalTrackProColors provides colorScheme,
content = content
)
}
Loading
Loading