rebranding

This commit is contained in:
2026-05-25 22:49:37 -04:00
parent b62ab77fbe
commit 3d246af3f7
210 changed files with 1307 additions and 712 deletions

View File

@@ -99,7 +99,7 @@ jobs:
with:
file: ./coverage/lcov.info
flags: unittests
name: shieldai-coverage
name: kordant-coverage
fail_on_empty: false
docker-build:
@@ -115,7 +115,7 @@ jobs:
with:
context: .
push: false
tags: shieldai:${{ github.sha }}
tags: kordant:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -52,7 +52,7 @@ jobs:
terraform_version: "~> 1.5"
- name: Terraform Init
working-directory: infra/environments/${{ needs.detect-environment.outputs.environment }}
run: terraform init -backend-config="bucket=shieldai-${{ needs.detect-environment.outputs.environment }}-terraform-state"
run: terraform init -backend-config="bucket=kordant-${{ needs.detect-environment.outputs.environment }}-terraform-state"
- name: Terraform Plan
id: plan
working-directory: infra/environments/${{ needs.detect-environment.outputs.environment }}
@@ -113,8 +113,8 @@ jobs:
file: ${{ matrix.dockerfile }}
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/shieldai-${{ matrix.name }}:${{ steps.tag.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/shieldai-${{ matrix.name }}:latest
ghcr.io/${{ github.repository_owner }}/kordant-${{ matrix.name }}:${{ steps.tag.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/kordant-${{ matrix.name }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
@@ -137,8 +137,8 @@ jobs:
aws-region: us-east-1
- name: Update ECS Service
run: |
IMAGE="ghcr.io/${{ github.repository_owner }}/shieldai-${{ matrix.service }}:${{ needs.detect-environment.outputs.tag }}"
CLUSTER="shieldai-${{ needs.detect-environment.outputs.environment }}"
IMAGE="ghcr.io/${{ github.repository_owner }}/kordant-${{ matrix.service }}:${{ needs.detect-environment.outputs.tag }}"
CLUSTER="kordant-${{ needs.detect-environment.outputs.environment }}"
SERVICE="${{ matrix.service }}"
TASK_DEF=$(aws ecs describe-task-definition \
@@ -181,7 +181,7 @@ jobs:
id: health
run: |
ENV="${{ needs.detect-environment.outputs.environment }}"
CLUSTER="shieldai-${ENV}"
CLUSTER="kordant-${ENV}"
ALB_DNS=$(aws elbv2 describe-load-balancers \
--query "LoadBalancers[?contains(LoadBalancerName, '${CLUSTER}-alb')].DNSName" \
@@ -230,7 +230,7 @@ jobs:
aws-region: us-east-1
- name: Rollback ECS Service
run: |
CLUSTER="shieldai-${{ needs.detect-environment.outputs.environment }}"
CLUSTER="kordant-${{ needs.detect-environment.outputs.environment }}"
SERVICE="${{ matrix.service }}"
aws ecs update-service \

View File

@@ -1,8 +1,8 @@
# ShieldAI
# Kordant
**Multi-layered consumer identity protection against predatory AI-driven scams.**
ShieldAI combines three detection engines — voice cloning detection, dark web monitoring, and real-time spam classification — to give consumers proactive defense against modern identity fraud.
Kordant combines three detection engines — voice cloning detection, dark web monitoring, and real-time spam classification — to give consumers proactive defense against modern identity fraud.
---
@@ -10,13 +10,13 @@ ShieldAI combines three detection engines — voice cloning detection, dark web
Scammers are weaponizing AI at scale: voice clones that sound exactly like your family, hyper-personalized phishing messages that bypass filters, and synthetic identities that exploit stolen data within hours of a breach. Legacy credit monitoring is reactive — it tells you after the damage is done.
ShieldAI flips the model. We detect the scam _as it happens_:
Kordant flips the model. We detect the scam _as it happens_:
- **VoicePrint** analyzes inbound calls in real time to flag synthetic AI-generated voices before you're socially engineered.
- **DarkWatch** continuously monitors dark web forums, breach databases, and data broker caches — notifying you the moment your credentials, phone, or SSN surface.
- **SpamShield** intercepts and classifies spam calls and SMS at the network level, blocking threats before they reach your phone.
Backed by ML models (ECAPA-TDNN, BERT) and a real-time alert pipeline, ShieldAI gives consumers enterprise-grade threat detection for their personal life.
Backed by ML models (ECAPA-TDNN, BERT) and a real-time alert pipeline, Kordant gives consumers enterprise-grade threat detection for their personal life.
---
@@ -173,10 +173,10 @@ This launches the API server, all microservices, and the web frontend concurrent
pnpm build
# Build individual Docker images
docker build -f packages/api/Dockerfile -t shieldai-api .
docker build -f services/spamshield/Dockerfile -t shieldai-spamshield .
docker build -f services/darkwatch/Dockerfile -t shieldai-darkwatch .
docker build -f services/voiceprint/Dockerfile -t shieldai-voiceprint .
docker build -f packages/api/Dockerfile -t kordant-api .
docker build -f services/spamshield/Dockerfile -t kordant-spamshield .
docker build -f services/darkwatch/Dockerfile -t kordant-darkwatch .
docker build -f services/voiceprint/Dockerfile -t kordant-voiceprint .
```
---
@@ -191,10 +191,10 @@ pnpm test
pnpm test:coverage
# Individual service tests
pnpm test --filter @shieldai/spamshield
pnpm test --filter @shieldai/darkwatch
pnpm test --filter @shieldai/voiceprint
pnpm test --filter @shieldai/hometitle
pnpm test --filter @kordant/spamshield
pnpm test --filter @kordant/darkwatch
pnpm test --filter @kordant/voiceprint
pnpm test --filter @kordant/hometitle
# Integration & E2E
cd packages/integration-tests && pnpm test
@@ -242,7 +242,7 @@ See `infra/README.md` and `infra/ROLLBACK.md` for detailed operational runbooks.
## Project Structure
```
shieldai/
kordant/
├── packages/ # Shared libraries (20 packages)
│ ├── api/ # Fastify API server
│ ├── core/ # Core shared logic
@@ -292,7 +292,7 @@ shieldai/
| Push Notifications | `docs/PUSH_NOTIFICATIONS_SETUP.md` |
| Mobile Push Integration | `docs/MOBILE_PUSH_INTEGRATION.md` |
| Mixpanel Analytics | `docs/MIXPANEL_ANALYTICS.md` |
| Code Review Workflow | `shieldai-workflow.md` |
| Code Review Workflow | `kordant-workflow.md` |
---

View File

@@ -5,7 +5,7 @@ plugins {
}
android {
namespace = "com.shieldai.android"
namespace = "com.kordant.android"
compileSdk {
version = release(36) {
minorApiLevel = 1
@@ -13,7 +13,7 @@ android {
}
defaultConfig {
applicationId = "com.shieldai.android"
applicationId = "com.kordant.android"
minSdk = 26
targetSdk = 36
versionCode = 1
@@ -22,8 +22,8 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
buildConfigField("String", "API_BASE_URL", "\"http://10.0.2.2:3000\"")
buildConfigField("String", "API_STAGING_URL", "\"https://staging.api.shieldai.com\"")
buildConfigField("String", "API_PRODUCTION_URL", "\"https://api.shieldai.com\"")
buildConfigField("String", "API_STAGING_URL", "\"https://staging.api.kordant.com\"")
buildConfigField("String", "API_PRODUCTION_URL", "\"https://api.kordant.com\"")
}
buildTypes {
@@ -36,7 +36,7 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
buildConfigField("String", "API_BASE_URL", "\"https://api.shieldai.com\"")
buildConfigField("String", "API_BASE_URL", "\"https://api.kordant.com\"")
}
}
compileOptions {

View File

@@ -18,7 +18,7 @@
errorLine1="distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/wrapper/gradle-wrapper.properties"
file="$HOME/Code/Kordant/android/Kordant/gradle/wrapper/gradle-wrapper.properties"
line="5"
column="17"/>
</issue>
@@ -29,7 +29,7 @@
errorLine1="agp = &quot;9.1.1&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="2"
column="7"/>
</issue>
@@ -40,7 +40,7 @@
errorLine1="coreKtx = &quot;1.10.1&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="3"
column="11"/>
</issue>
@@ -51,7 +51,7 @@
errorLine1="junitVersion = &quot;1.1.5&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="5"
column="16"/>
</issue>
@@ -62,7 +62,7 @@
errorLine1="espressoCore = &quot;3.5.1&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="6"
column="16"/>
</issue>
@@ -73,7 +73,7 @@
errorLine1="lifecycleRuntimeKtx = &quot;2.6.1&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="7"
column="23"/>
</issue>
@@ -84,7 +84,7 @@
errorLine1="activityCompose = &quot;1.8.0&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="8"
column="19"/>
</issue>
@@ -95,7 +95,7 @@
errorLine1="navigationCompose = &quot;2.7.7&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="9"
column="21"/>
</issue>
@@ -106,7 +106,7 @@
errorLine1="composeBom = &quot;2025.12.00&quot;"
errorLine2=" ~~~~~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="11"
column="14"/>
</issue>
@@ -117,7 +117,7 @@
errorLine1="securityCrypto = &quot;1.1.0-alpha06&quot;"
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="13"
column="18"/>
</issue>
@@ -128,7 +128,7 @@
errorLine1="playServicesAuth = &quot;21.0.0&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="15"
column="20"/>
</issue>
@@ -139,7 +139,7 @@
errorLine1="work = &quot;2.9.1&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="23"
column="8"/>
</issue>
@@ -150,7 +150,7 @@
errorLine1="work = &quot;2.9.1&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="23"
column="8"/>
</issue>
@@ -161,7 +161,7 @@
errorLine1="kotlin = &quot;2.2.10&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="10"
column="10"/>
</issue>
@@ -172,7 +172,7 @@
errorLine1="kotlin = &quot;2.2.10&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="10"
column="10"/>
</issue>
@@ -183,7 +183,7 @@
errorLine1="okhttp = &quot;4.12.0&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="16"
column="10"/>
</issue>
@@ -194,7 +194,7 @@
errorLine1="okhttp = &quot;4.12.0&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="16"
column="10"/>
</issue>
@@ -205,7 +205,7 @@
errorLine1="gson = &quot;2.10.1&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="17"
column="8"/>
</issue>
@@ -216,7 +216,7 @@
errorLine1="lottieCompose = &quot;6.4.0&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="18"
column="17"/>
</issue>
@@ -227,7 +227,7 @@
errorLine1="coroutinesTest = &quot;1.7.3&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="19"
column="18"/>
</issue>
@@ -238,7 +238,7 @@
errorLine1="retrofit = &quot;2.11.0&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="20"
column="12"/>
</issue>
@@ -249,7 +249,7 @@
errorLine1="kotlinxSerializationJson = &quot;1.7.3&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="22"
column="28"/>
</issue>
@@ -260,7 +260,7 @@
errorLine1="truth = &quot;1.4.4&quot;"
errorLine2=" ~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="24"
column="9"/>
</issue>
@@ -271,7 +271,7 @@
errorLine1="mockwebserver = &quot;4.12.0&quot;"
errorLine2=" ~~~~~~~~">
<location
file="$HOME/Code/ShieldAI/android/ShieldAI/gradle/libs.versions.toml"
file="$HOME/Code/Kordant/android/Kordant/gradle/libs.versions.toml"
line="25"
column="17"/>
</issue>
@@ -279,10 +279,10 @@
<issue
id="LocalContextGetResourceValueCall"
message="Querying resource values using LocalContext.current"
errorLine1=" .requestIdToken(context.getString(com.shieldai.android.R.string.default_web_client_id))"
errorLine1=" .requestIdToken(context.getString(com.kordant.android.R.string.default_web_client_id))"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/ui/screens/auth/LoginScreen.kt"
file="src/main/java/com/kordant/android/ui/screens/auth/LoginScreen.kt"
line="56"
column="29"/>
</issue>
@@ -293,7 +293,7 @@
errorLine1=" private var userRepository: UserRepository? = null"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/di/RepositoryModule.kt"
file="src/main/java/com/kordant/android/di/RepositoryModule.kt"
line="11"
column="5"/>
</issue>
@@ -304,7 +304,7 @@
errorLine1=" private var darkWatchRepository: DarkWatchRepository? = null"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/di/RepositoryModule.kt"
file="src/main/java/com/kordant/android/di/RepositoryModule.kt"
line="12"
column="5"/>
</issue>
@@ -315,7 +315,7 @@
errorLine1=" private var voicePrintRepository: VoicePrintRepository? = null"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/di/RepositoryModule.kt"
file="src/main/java/com/kordant/android/di/RepositoryModule.kt"
line="13"
column="5"/>
</issue>
@@ -326,7 +326,7 @@
errorLine1=" private var alertRepository: AlertRepository? = null"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/di/RepositoryModule.kt"
file="src/main/java/com/kordant/android/di/RepositoryModule.kt"
line="14"
column="5"/>
</issue>
@@ -337,7 +337,7 @@
errorLine1=" private var subscriptionRepository: SubscriptionRepository? = null"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/di/RepositoryModule.kt"
file="src/main/java/com/kordant/android/di/RepositoryModule.kt"
line="15"
column="5"/>
</issue>
@@ -480,7 +480,7 @@
errorLine1=" securePrefs.edit()"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/data/repository/AuthRepository.kt"
file="src/main/java/com/kordant/android/data/repository/AuthRepository.kt"
line="144"
column="9"/>
</issue>
@@ -491,7 +491,7 @@
errorLine1=" securePrefs.edit()"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/data/repository/AuthRepository.kt"
file="src/main/java/com/kordant/android/data/repository/AuthRepository.kt"
line="155"
column="9"/>
</issue>
@@ -502,7 +502,7 @@
errorLine1=" prefs.edit().putBoolean(&quot;biometric_enabled&quot;, enabled).apply()"
errorLine2=" ~~~~~~~~~~~~">
<location
file="src/main/java/com/shieldai/android/ui/screens/auth/BiometricAuthScreen.kt"
file="src/main/java/com/kordant/android/ui/screens/auth/BiometricAuthScreen.kt"
line="88"
column="5"/>
</issue>

View File

@@ -1,4 +1,4 @@
package com.shieldai.android
package com.kordant.android
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.ui.Modifier
@@ -10,15 +10,15 @@ import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTextClearance
import androidx.compose.ui.test.performTextInput
import com.shieldai.android.ui.components.BadgeVariant
import com.shieldai.android.ui.components.ComponentShowcase
import com.shieldai.android.ui.components.InputType
import com.shieldai.android.ui.components.ShieldBadge
import com.shieldai.android.ui.components.ShieldButton
import com.shieldai.android.ui.components.ShieldButtonSize
import com.shieldai.android.ui.components.ShieldButtonVariant
import com.shieldai.android.ui.components.ShieldTextField
import com.shieldai.android.ui.theme.ShieldAITheme
import com.kordant.android.ui.components.BadgeVariant
import com.kordant.android.ui.components.ComponentShowcase
import com.kordant.android.ui.components.InputType
import com.kordant.android.ui.components.ShieldBadge
import com.kordant.android.ui.components.ShieldButton
import com.kordant.android.ui.components.ShieldButtonSize
import com.kordant.android.ui.components.ShieldButtonVariant
import com.kordant.android.ui.components.ShieldTextField
import com.kordant.android.ui.theme.KordantTheme
import org.junit.Rule
import org.junit.Test
@@ -30,7 +30,7 @@ class ComponentTests {
@Test
fun shieldButton_rendersWithText() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldButton(text = "Click Me", onClick = {})
}
}
@@ -41,7 +41,7 @@ class ComponentTests {
fun shieldButton_clickHandlerFires() {
var clicked = false
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldButton(text = "Click Me", onClick = { clicked = true })
}
}
@@ -53,7 +53,7 @@ class ComponentTests {
fun shieldButton_disabledDoesNotFireClick() {
var clicked = false
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldButton(text = "Click Me", onClick = { clicked = true }, enabled = false)
}
}
@@ -64,7 +64,7 @@ class ComponentTests {
@Test
fun shieldButton_showsLoadingIndicator() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldButton(text = "Saving", onClick = {}, loading = true)
}
}
@@ -74,7 +74,7 @@ class ComponentTests {
@Test
fun shieldButton_variantsRender() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldButton(text = "Primary", onClick = {}, variant = ShieldButtonVariant.Primary)
ShieldButton(text = "Secondary", onClick = {}, variant = ShieldButtonVariant.Secondary)
ShieldButton(text = "Ghost", onClick = {}, variant = ShieldButtonVariant.Ghost)
@@ -90,7 +90,7 @@ class ComponentTests {
@Test
fun shieldButton_sizesRender() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldButton(text = "Small", onClick = {}, size = ShieldButtonSize.Small)
ShieldButton(text = "Medium", onClick = {}, size = ShieldButtonSize.Medium)
ShieldButton(text = "Large", onClick = {}, size = ShieldButtonSize.Large)
@@ -104,7 +104,7 @@ class ComponentTests {
@Test
fun shieldButton_fullWidthRenders() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldButton(text = "Full Width", onClick = {}, fullWidth = true, modifier = Modifier.fillMaxWidth())
}
}
@@ -114,7 +114,7 @@ class ComponentTests {
@Test
fun shieldTextField_rendersWithLabel() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldTextField(value = "", onValueChange = {}, label = "Email")
}
}
@@ -124,7 +124,7 @@ class ComponentTests {
@Test
fun shieldTextField_showsErrorState() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldTextField(
value = "bad",
onValueChange = {},
@@ -140,7 +140,7 @@ class ComponentTests {
@Test
fun shieldTextField_helperTextDisplayed() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldTextField(
value = "",
onValueChange = {},
@@ -155,7 +155,7 @@ class ComponentTests {
@Test
fun shieldTextField_passwordToggleExists() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldTextField(
value = "",
onValueChange = {},
@@ -170,7 +170,7 @@ class ComponentTests {
@Test
fun shieldBadge_variantsRender() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldBadge(text = "Success", variant = BadgeVariant.Success)
ShieldBadge(text = "Error", variant = BadgeVariant.Error)
ShieldBadge(text = "Warning", variant = BadgeVariant.Warning)
@@ -188,7 +188,7 @@ class ComponentTests {
@Test
fun shieldTextField_acceptsInput() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ShieldTextField(
value = "",
onValueChange = {},
@@ -202,11 +202,11 @@ class ComponentTests {
@Test
fun componentShowcase_renders() {
composeTestRule.setContent {
ShieldAITheme {
KordantTheme {
ComponentShowcase()
}
}
composeTestRule.onNodeWithText("ShieldAI Design System").assertIsDisplayed()
composeTestRule.onNodeWithText("Kordant Design System").assertIsDisplayed()
composeTestRule.onNodeWithText("ShieldButton").assertIsDisplayed()
composeTestRule.onNodeWithText("ShieldCard").assertIsDisplayed()
composeTestRule.onNodeWithText("ShieldBadge").assertIsDisplayed()

View File

@@ -1,4 +1,4 @@
package com.shieldai.android
package com.kordant.android
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
@@ -11,6 +11,6 @@ class ExampleInstrumentedTest {
@Test
fun useAppContext() {
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.shieldai.android", appContext.packageName)
assertEquals("com.kordant.android", appContext.packageName)
}
}

View File

@@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".ShieldAIApp"
android:name=".KordantApp"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
@@ -13,12 +13,12 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ShieldAI">
android:theme="@style/Theme.Kordant">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.ShieldAI">
android:theme="@style/Theme.Kordant">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View File

@@ -5,14 +5,14 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import com.shieldai.android.navigation.AppNavigation
import com.shieldai.android.ui.theme.ShieldAITheme
import com.shieldai.android.ui.theme.KordantTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
ShieldAITheme {
KordantTheme {
AppNavigation()
}
}

View File

@@ -4,7 +4,7 @@ import android.app.Application
import com.shieldai.android.data.repository.AuthRepository
import com.shieldai.android.data.repository.AuthRepositoryImpl
class ShieldAIApp : Application() {
class KordantApp : Application() {
lateinit var authRepository: AuthRepository
private set
@@ -15,7 +15,7 @@ class ShieldAIApp : Application() {
}
companion object {
lateinit var instance: ShieldAIApp
lateinit var instance: KordantApp
private set
}
}

View File

@@ -11,13 +11,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.viewmodel.AuthViewModel
@Composable
fun AppNavigation() {
val context = LocalContext.current
val app = context.applicationContext as ShieldAIApp
val app = context.applicationContext as KordantApp
val viewModel: AuthViewModel = viewModel(
factory = AuthViewModel.Factory
)

View File

@@ -0,0 +1,292 @@
package com.shieldai.android.navigation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.shieldai.android.R
import com.shieldai.android.ui.screens.auth.AuthScreen
import com.shieldai.android.ui.screens.auth.ForgotPasswordScreen
import com.shieldai.android.ui.screens.auth.ResetPasswordScreen
import com.shieldai.android.ui.screens.dashboard.AlertDetailScreen
import com.shieldai.android.ui.screens.dashboard.DashboardScreen
import com.shieldai.android.ui.screens.onboarding.OnboardingScreen
import com.shieldai.android.ui.screens.services.DarkWatchScreen
import com.shieldai.android.ui.screens.services.HomeTitleScreen
import com.shieldai.android.ui.screens.services.RemoveBrokersScreen
import com.shieldai.android.ui.screens.services.SpamShieldScreen
import com.shieldai.android.ui.screens.services.VoicePrintScreen
import com.shieldai.android.ui.screens.settings.SettingsScreen
import com.shieldai.android.viewmodel.AuthViewModel
data class ServiceNavCard(
val title: String,
val route: String,
val description: String
)
@Composable
fun NavGraph(
navController: NavHostController,
viewModel: AuthViewModel,
modifier: Modifier = Modifier
) {
NavHost(
navController = navController,
startDestination = Screen.Dashboard.route,
modifier = modifier
) {
composable(Screen.Dashboard.route) {
DashboardScreen(
onNavigateToAlert = { alertId ->
navController.navigate(Screen.AlertDetail.createRoute(alertId))
},
onNavigateToService = { serviceRoute ->
navController.navigate(serviceRoute)
}
)
}
composable(Screen.Alerts.route) {
AlertsScreen(
onNavigateToAlert = { alertId ->
navController.navigate(Screen.AlertDetail.createRoute(alertId))
}
)
}
composable(
route = Screen.AlertDetail.ROUTE,
arguments = listOf(navArgument("alertId") { type = NavType.StringType })
) { backStackEntry ->
val alertId = backStackEntry.arguments?.getString("alertId") ?: ""
AlertDetailScreen(
alertId = alertId,
onBack = { navController.popBackStack() }
)
}
composable(Screen.Services.route) {
ServicesHubScreen(
onNavigateToService = { route ->
navController.navigate(route)
}
)
}
composable(Screen.DarkWatch.route) {
DarkWatchScreen(
onBack = { navController.popBackStack() }
)
}
composable(Screen.VoicePrint.route) {
VoicePrintScreen(
onBack = { navController.popBackStack() }
)
}
composable(Screen.SpamShield.route) {
SpamShieldScreen(
onBack = { navController.popBackStack() }
)
}
composable(Screen.HomeTitle.route) {
HomeTitleScreen(
onBack = { navController.popBackStack() }
)
}
composable(Screen.RemoveBrokers.route) {
RemoveBrokersScreen(
onBack = { navController.popBackStack() }
)
}
composable(Screen.Settings.route) {
SettingsScreen(
onBack = { navController.popBackStack(Screen.Dashboard.route, inclusive = false) }
)
}
composable(Screen.Account.route) {
PlaceholderScreen(title = "Account")
}
composable(
route = Screen.ServiceDetail.ROUTE,
arguments = listOf(navArgument("serviceId") { type = NavType.StringType })
) { backStackEntry ->
val serviceId = backStackEntry.arguments?.getString("serviceId") ?: ""
PlaceholderScreen(title = "Service: $serviceId")
}
}
}
@Composable
fun AuthNavHost(viewModel: AuthViewModel) {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Screen.Auth.route
) {
composable(Screen.Auth.route) {
AuthScreen(
viewModel = viewModel,
onNavigateToForgotPassword = {
navController.navigate(Screen.ForgotPassword.route)
},
onNavigateToResetPassword = {
navController.navigate(Screen.ResetPassword.createRoute(""))
}
)
}
composable(Screen.ForgotPassword.route) {
ForgotPasswordScreen(
viewModel = viewModel,
onBack = { navController.popBackStack() }
)
}
composable(
route = Screen.ResetPassword.route,
arguments = listOf(navArgument("email") { type = NavType.StringType; defaultValue = "" })
) { backStackEntry ->
val email = backStackEntry.arguments?.getString("email") ?: ""
ResetPasswordScreen(
viewModel = viewModel,
email = email,
onBack = { navController.popBackStack(Screen.Auth.route, false) }
)
}
}
}
@Composable
fun OnboardingNavHost(
viewModel: AuthViewModel,
onComplete: () -> Unit
) {
OnboardingScreen(
viewModel = viewModel,
onComplete = onComplete
)
}
@Composable
private fun ServicesHubScreen(
onNavigateToService: (String) -> Unit
) {
val services = listOf(
ServiceNavCard("DarkWatch", Screen.DarkWatch.route, "Monitor data exposures"),
ServiceNavCard("VoicePrint", Screen.VoicePrint.route, "Voice authentication"),
ServiceNavCard("SpamShield", Screen.SpamShield.route, "Spam call protection"),
ServiceNavCard("HomeTitle", Screen.HomeTitle.route, "Property title monitoring"),
ServiceNavCard("RemoveBrokers", Screen.RemoveBrokers.route, "Broker listing removal")
)
Column(
modifier = Modifier.fillMaxSize().padding(16.dp)
) {
Text(
text = "Services",
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(bottom = 16.dp)
)
LazyVerticalGrid(
columns = GridCells.Fixed(2),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(services.size) { index ->
val service = services[index]
com.shieldai.android.ui.components.ShieldCard(
onClick = { onNavigateToService(service.route) },
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier.padding(8.dp),
verticalArrangement = Arrangement.Center
) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_services),
contentDescription = service.title,
tint = MaterialTheme.colorScheme.primary
)
Text(
text = service.title,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
modifier = Modifier.padding(top = 12.dp)
)
Text(
text = service.description,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(top = 4.dp)
)
}
}
}
}
}
}
@Composable
private fun AlertsScreen(
onNavigateToAlert: (String) -> Unit
) {
Column(
modifier = Modifier.fillMaxSize().padding(16.dp)
) {
Text(
text = "Alerts",
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(bottom = 16.dp)
)
com.shieldai.android.ui.components.ShieldEmptyState(
title = "No alerts",
description = "You have no recent alerts"
)
}
}
@Composable
private fun PlaceholderScreen(title: String) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = title,
style = MaterialTheme.typography.headlineMedium,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onBackground
)
}
}

View File

@@ -18,4 +18,13 @@ sealed class Screen(val route: String) {
fun createRoute(serviceId: String) = "service_detail/$serviceId"
}
}
object AlertDetail {
const val ROUTE = "alert_detail/{alertId}"
fun createRoute(alertId: String) = "alert_detail/$alertId"
}
data object DarkWatch : Screen("darkwatch")
data object VoicePrint : Screen("voiceprint")
data object SpamShield : Screen("spamshield")
data object HomeTitle : Screen("hometitle")
data object RemoveBrokers : Screen("removebrokers")
}

View File

@@ -29,7 +29,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.shieldai.android.ui.theme.ShieldAITheme
import com.shieldai.android.ui.theme.KordantTheme
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@@ -50,7 +50,7 @@ fun ComponentShowcase(modifier: Modifier = Modifier) {
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(
text = "ShieldAI Design System",
text = "Kordant Design System",
style = MaterialTheme.typography.headlineMedium,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center
@@ -263,7 +263,7 @@ private fun SectionTitle(title: String) {
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, name = "Dark Mode")
@Composable
fun ComponentShowcasePreview() {
ShieldAITheme {
KordantTheme {
ComponentShowcase()
}
}

View File

@@ -2,7 +2,6 @@ package com.shieldai.android.ui.components
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.MaterialTheme
@@ -11,13 +10,16 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.unit.dp
import com.shieldai.android.ui.theme.Error
import com.shieldai.android.ui.theme.Success
import com.shieldai.android.ui.theme.TextPrimaryLight
import com.shieldai.android.ui.theme.Warning
@Composable
@@ -39,42 +41,30 @@ fun ThreatGauge(
Canvas(
modifier = Modifier.size(size.dp)
) {
val center = Offset(size / 2f, size / 2f)
val radius = (size / 2f - 16f) * dpiScale
val strokeWidth = 16f * dpiScale
val center = Offset(size.toPx() / 2, size.toPx() / 2)
val radius = center.x - 16.dp.toPx()
val strokeWidth = 16.dp.toPx()
drawArc(
color = Color(0xFFE2E8F0).copy(alpha = 0.3f),
startAngle = -135f,
sweepAngle = 270f,
useCenter = false,
topLeft = Offset(
center.x - radius,
center.y - radius
),
size = androidx.compose.ui.geometry.Size(radius * 2, radius * 2),
topLeft = Offset(center.x - radius, center.y - radius),
size = Size(radius * 2, radius * 2),
style = Stroke(width = strokeWidth)
)
val sweepAngle = (score / 100f) * 270f
val sweepAngle = (score.coerceIn(0, 100) / 100f) * 270f
if (sweepAngle > 0) {
val gradient = Brush.linearGradient(
colors = listOf(startColor, endColor),
start = Offset(center.x - radius, center.y),
end = Offset(center.x + radius, center.y)
)
drawArc(
brush = gradient,
color = startColor,
startAngle = -135f,
sweepAngle = sweepAngle,
useCenter = false,
topLeft = Offset(
center.x - radius,
center.y - radius
),
size = androidx.compose.ui.geometry.Size(radius * 2, radius * 2),
style = Stroke(width = strokeWidth, cap = androidx.compose.ui.graphics.Paint.Cap.Round)
topLeft = Offset(center.x - radius, center.y - radius),
size = Size(radius * 2, radius * 2),
style = Stroke(width = strokeWidth)
)
}
}
@@ -102,6 +92,3 @@ fun ThreatGauge(
)
}
}
private val Float.dpiScale: Float
get() = 1f

View File

@@ -55,14 +55,14 @@ fun AuthScreen(
Image(
painter = painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = "ShieldAI Logo",
contentDescription = "Kordant Logo",
modifier = Modifier.size(72.dp)
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "ShieldAI",
text = "Kordant",
style = MaterialTheme.typography.headlineLarge,
color = MaterialTheme.colorScheme.primary
)

View File

@@ -15,7 +15,7 @@ fun BiometricAuthScreen(
onAuthenticated: () -> Unit,
onError: (String) -> Unit,
title: String = "Biometric Authentication",
subtitle: String = "Authenticate to access ShieldAI",
subtitle: String = "Authenticate to access Kordant",
description: String = "Use your fingerprint or face to sign in"
) {
val context = LocalContext.current

View File

@@ -1,10 +1,9 @@
package com.shieldai.android.ui.screens.dashboard
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
@@ -20,16 +19,16 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PullToRefreshBox
import androidx.compose.material3.SwipeToDismissBox
import androidx.compose.material3.SwipeToDismissBoxState
import androidx.compose.material3.SwipeToDismissBoxValue
import androidx.compose.material3.Text
import androidx.compose.material3.pullToRefresh
import androidx.compose.material3.pullToRefreshDefaults
import androidx.compose.material3.rememberSwipeToDismissBoxState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@@ -41,12 +40,15 @@ import com.shieldai.android.R
import com.shieldai.android.data.model.Alert
import com.shieldai.android.ui.components.BadgeVariant
import com.shieldai.android.ui.components.ShieldBadge
import com.shieldai.android.ui.components.ShieldButton
import com.shieldai.android.ui.components.ShieldButtonVariant
import com.shieldai.android.ui.components.ShieldCard
import com.shieldai.android.ui.components.ShieldEmptyState
import com.shieldai.android.ui.components.ShieldSkeletonCard
import com.shieldai.android.ui.components.ThreatGauge
import com.shieldai.android.viewmodel.DashboardViewModel
import com.shieldai.android.viewmodel.DashboardViewModel as DashboardVM
import kotlinx.coroutines.launch
data class ServiceSummary(
val name: String,
@@ -64,28 +66,10 @@ fun DashboardScreen(
viewModel: DashboardViewModel = viewModel(factory = DashboardVM.Factory)
) {
val uiState by viewModel.uiState.collectAsState()
var isRefreshing by remember { mutableStateOf(false) }
var isRefreshingInternal by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
if (isRefreshing) {
viewModel.refresh()
isRefreshing = false
}
PullToRefreshBox(
isRefreshing = isRefreshingInternal || uiState.isLoading,
onRefresh = {
isRefreshingInternal = false
viewModel.refresh()
},
modifier = modifier,
indicator = {
androidx.compose.material3.pullToRefreshDefaults.indicator(
parent,
transformer,
isRefreshingInternal || uiState.isLoading
)
}
Box(
modifier = modifier.fillMaxSize()
) {
when {
uiState.isLoading && uiState.recentAlerts.isEmpty() -> {
@@ -97,9 +81,11 @@ fun DashboardScreen(
title = "Failed to load",
description = uiState.error ?: "Unknown error",
actionButton = {
androidx.compose.material3.TextButton(onClick = { viewModel.refresh() }) {
Text("Retry")
}
ShieldButton(
text = "Retry",
onClick = { viewModel.refresh() },
variant = ShieldButtonVariant.Primary
)
}
)
} else {
@@ -113,10 +99,22 @@ fun DashboardScreen(
DashboardContent(
uiState = uiState,
onNavigateToAlert = onNavigateToAlert,
onNavigateToService = onNavigateToService
onNavigateToService = onNavigateToService,
onRefresh = {
scope.launch {
viewModel.refresh()
}
}
)
}
}
if (uiState.isLoading) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.TopCenter).padding(top = 16.dp),
color = MaterialTheme.colorScheme.primary
)
}
}
}
@@ -140,18 +138,28 @@ private fun DashboardLoadingState() {
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun DashboardContent(
uiState: DashboardViewModel.DashboardUiState,
onNavigateToAlert: (String) -> Unit,
onNavigateToService: (String) -> Unit
onNavigateToService: (String) -> Unit,
onRefresh: () -> Unit
) {
val dismissState = rememberSwipeToDismissBoxState(
confirmValueChange = { value ->
if (value == SwipeToDismissBoxValue.EndToStart) {
onRefresh()
true
} else {
false
}
}
)
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = androidx.compose.foundation.layout.PaddingValues(
horizontal = 16.dp,
vertical = 16.dp
),
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
item {

View File

@@ -197,10 +197,10 @@ private fun AccountSection(user: com.shieldai.android.data.model.User) {
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
ShieldAvatar(
name = user.name,
avatarUrl = user.avatarUrl
)
ShieldAvatar(
name = user.name,
imageUrl = user.avatarUrl
)
Column {
Text(
text = user.name,

View File

@@ -57,7 +57,7 @@ private val DarkColorScheme = darkColorScheme(
)
@Composable
fun ShieldAITheme(
fun KordantTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = false,
content: @Composable () -> Unit

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.model.Alert
import com.shieldai.android.data.repository.AlertRepository
import com.shieldai.android.di.RepositoryModule
@@ -25,7 +25,7 @@ class AlertDetailViewModel : ViewModel() {
val uiState: StateFlow<AlertDetailUiState> = _uiState.asStateFlow()
private val alertRepo: AlertRepository by lazy {
RepositoryModule.provideAlertRepository(ShieldAIApp.instance)
RepositoryModule.provideAlertRepository(KordantApp.instance)
}
fun loadAlert(alertId: String) {
@@ -78,7 +78,7 @@ class AlertDetailViewModel : ViewModel() {
}
}
private fun markAlertRead(alertId: String) {
private suspend fun markAlertRead(alertId: String) {
alertRepo.markRead(alertId)
}

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.repository.AuthRepository
import com.shieldai.android.data.repository.AuthRepositoryImpl
import com.shieldai.android.data.repository.User
@@ -188,7 +188,7 @@ class AuthViewModel(
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val app = ShieldAIApp.instance
val app = KordantApp.instance
return AuthViewModel(app.authRepository) as T
}
}

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.model.Exposure
import com.shieldai.android.data.model.WatchlistItem
import com.shieldai.android.data.repository.DarkWatchRepository
@@ -26,7 +26,7 @@ class DarkWatchViewModel : ViewModel() {
val uiState: StateFlow<DarkWatchUiState> = _uiState.asStateFlow()
private val repo: DarkWatchRepository by lazy {
RepositoryModule.provideDarkWatchRepository(ShieldAIApp.instance)
RepositoryModule.provideDarkWatchRepository(KordantApp.instance)
}
init {

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.model.Alert
import com.shieldai.android.data.repository.AlertRepository
import com.shieldai.android.data.repository.DarkWatchRepository
@@ -35,22 +35,22 @@ class DashboardViewModel : ViewModel() {
val uiState: StateFlow<DashboardUiState> = _uiState.asStateFlow()
private val alertRepo: AlertRepository by lazy {
RepositoryModule.provideAlertRepository(ShieldAIApp.instance)
RepositoryModule.provideAlertRepository(KordantApp.instance)
}
private val darkWatchRepo: DarkWatchRepository by lazy {
RepositoryModule.provideDarkWatchRepository(ShieldAIApp.instance)
RepositoryModule.provideDarkWatchRepository(KordantApp.instance)
}
private val voicePrintRepo: VoicePrintRepository by lazy {
RepositoryModule.provideVoicePrintRepository(ShieldAIApp.instance)
RepositoryModule.provideVoicePrintRepository(KordantApp.instance)
}
private val spamShieldRepo: SpamShieldRepository by lazy {
RepositoryModule.provideSpamShieldRepository(ShieldAIApp.instance)
RepositoryModule.provideSpamShieldRepository(KordantApp.instance)
}
private val homeTitleRepo: HomeTitleRepository by lazy {
RepositoryModule.provideHomeTitleRepository(ShieldAIApp.instance)
RepositoryModule.provideHomeTitleRepository(KordantApp.instance)
}
private val removeBrokersRepo: RemoveBrokersRepository by lazy {
RepositoryModule.provideRemoveBrokersRepository(ShieldAIApp.instance)
RepositoryModule.provideRemoveBrokersRepository(KordantApp.instance)
}
init {

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.model.Property
import com.shieldai.android.data.repository.HomeTitleRepository
import com.shieldai.android.di.RepositoryModule
@@ -24,7 +24,7 @@ class HomeTitleViewModel : ViewModel() {
val uiState: StateFlow<HomeTitleUiState> = _uiState.asStateFlow()
private val repo: HomeTitleRepository by lazy {
RepositoryModule.provideHomeTitleRepository(ShieldAIApp.instance)
RepositoryModule.provideHomeTitleRepository(KordantApp.instance)
}
init {

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.model.BrokerListing
import com.shieldai.android.data.model.RemovalRequest
import com.shieldai.android.data.repository.RemoveBrokersRepository
@@ -26,7 +26,7 @@ class RemoveBrokersViewModel : ViewModel() {
val uiState: StateFlow<RemoveBrokersUiState> = _uiState.asStateFlow()
private val repo: RemoveBrokersRepository by lazy {
RepositoryModule.provideRemoveBrokersRepository(ShieldAIApp.instance)
RepositoryModule.provideRemoveBrokersRepository(KordantApp.instance)
}
init {

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.model.Subscription
import com.shieldai.android.data.model.User
import com.shieldai.android.data.repository.SubscriptionRepository
@@ -29,10 +29,10 @@ class SettingsViewModel : ViewModel() {
val uiState: StateFlow<SettingsUiState> = _uiState.asStateFlow()
private val userRepo: UserRepository by lazy {
RepositoryModule.provideUserRepository(ShieldAIApp.instance)
RepositoryModule.provideUserRepository(KordantApp.instance)
}
private val subscriptionRepo: SubscriptionRepository by lazy {
RepositoryModule.provideSubscriptionRepository(ShieldAIApp.instance)
RepositoryModule.provideSubscriptionRepository(KordantApp.instance)
}
init {

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.model.SpamRule
import com.shieldai.android.data.repository.SpamShieldRepository
import com.shieldai.android.di.RepositoryModule
@@ -27,7 +27,7 @@ class SpamShieldViewModel : ViewModel() {
val uiState: StateFlow<SpamShieldUiState> = _uiState.asStateFlow()
private val repo: SpamShieldRepository by lazy {
RepositoryModule.provideSpamShieldRepository(ShieldAIApp.instance)
RepositoryModule.provideSpamShieldRepository(KordantApp.instance)
}
init {

View File

@@ -3,7 +3,7 @@ package com.shieldai.android.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.shieldai.android.ShieldAIApp
import com.shieldai.android.KordantApp
import com.shieldai.android.data.model.VoiceEnrollment
import com.shieldai.android.data.repository.VoicePrintRepository
import com.shieldai.android.di.RepositoryModule
@@ -24,7 +24,7 @@ class VoicePrintViewModel : ViewModel() {
val uiState: StateFlow<VoicePrintUiState> = _uiState.asStateFlow()
private val repo: VoicePrintRepository by lazy {
RepositoryModule.provideVoicePrintRepository(ShieldAIApp.instance)
RepositoryModule.provideVoicePrintRepository(KordantApp.instance)
}
init {

Some files were not shown because too many files have changed in this diff Show More