Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
bfeb08b
fix(ar): improve drag drop position and trash zone deletion
recepteksi Apr 6, 2026
7e5701c
fix(ar): fix trash zone detection with proper X and Y coordinate check
recepteksi Apr 6, 2026
a4f049b
fix: code review fixes and drag improvements
recepteksi Apr 6, 2026
5d5314f
fix(ar): improve drag drop to work on all screen positions
recepteksi Apr 6, 2026
2177109
style(ui): improve TrashZone design with transparency and centering
recepteksi Apr 6, 2026
44e7ad9
fix(ui): correct trash zone detection bounds for drag-to-delete
recepteksi Apr 6, 2026
67fde79
Merge remote-tracking branch 'origin/feature/ui-trash-design' into dev
recepteksi Apr 6, 2026
4eb0ecc
Merge remote-tracking branch 'origin/feature/fix-trash-delete' into dev
recepteksi Apr 6, 2026
9abb221
feat(ui): add thumbnails to object lists
recepteksi Apr 6, 2026
c7f8000
feat(di): setup Koin dependency injection
recepteksi Apr 6, 2026
1179b83
feat(ar): implement photo capture functionality
recepteksi Apr 7, 2026
50c06c7
feat(ar): implement video recording functionality
recepteksi Apr 7, 2026
652293c
feat(ui): implement object gallery screen
recepteksi Apr 7, 2026
7be3e25
build: add Kover test coverage plugin
recepteksi Apr 7, 2026
97af3b7
feat: Add video recording with camera-style UI
recepteksi Apr 7, 2026
f49f3de
fix: Improve AR screen layout and video recording connection
recepteksi Apr 7, 2026
2316036
feat: Add 3D model preview thumbnails in object lists
recepteksi Apr 7, 2026
6026dae
fix: Remove HDR environment dependency from ModelPreviewThumbnail
recepteksi Apr 7, 2026
f3139da
fix: Disable 3D preview to fix crash - use icon placeholder
recepteksi Apr 7, 2026
ef03c8a
Fix video recording and gallery integration
recepteksi Apr 7, 2026
19c214c
fix(di): prevent Koin crash on Activity recreation
recepteksi Apr 7, 2026
83a5fe5
Fix photo capture DI - ensure CapturePhotoUseCase is injected
recepteksi Apr 7, 2026
3276be1
fix(ui): improve camera controls symmetry
recepteksi Apr 8, 2026
b1564a4
fix(gallery): lazy inject GalleryViewModel to prevent crash
recepteksi Apr 8, 2026
65ab2ff
Merge branch 'fix/KAN-7-camera-controls-symmetry' into dev
recepteksi Apr 8, 2026
d4e5ff5
feat(ui): implement 3D model preview for Android and iOS (ARS-5)
recepteksi Apr 8, 2026
e072929
test(ui): add ModelPreviewThumbnail unit tests (ARS-5)
recepteksi Apr 8, 2026
7a84316
fix(ui): address code review issues for ARS-5 model preview
recepteksi Apr 8, 2026
6007cdd
Merge feature/ARS-5-3d-model-preview into dev (ARS-5)
recepteksi Apr 8, 2026
b87ee07
fix(ui): fix crash when opening model list (ARS-5)
recepteksi Apr 8, 2026
72933e0
fix(ios): fix iOS build error for model preview dependencies
recepteksi Apr 8, 2026
4f962b7
fix(ios): address code review issues for iOS build fix
recepteksi Apr 8, 2026
bacd775
fix(ui): address code review issues for model list crash fix
recepteksi Apr 8, 2026
fa575bb
Merge fix/ARS-ios-build-error into dev
recepteksi Apr 8, 2026
9cfdf49
Merge bugfix/ARS-5-model-list-crash into dev
recepteksi Apr 8, 2026
10f515c
fix(workflow): update branch names and task ID format in workflow doc…
recepteksi Apr 8, 2026
26eba64
fix(ar): fix gallery crash, thumbnail persistence, animated models, d…
recepteksi Apr 11, 2026
7c65a71
Merge bugfix/gallery-crash-shutter-thumbnail into dev
recepteksi Apr 11, 2026
7bc4368
fix(ar): prevent crash in PhotoThumbnail by using safe null handling
recepteksi Apr 17, 2026
0ffb154
fix(ar): improve PhotoThumbnail bitmap loading with proper exception …
recepteksi Apr 17, 2026
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
26 changes: 13 additions & 13 deletions .claude/WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ main (production-ready)
└─── dev (integration branch)
├─── feature/ddd-value-objects (task branch)
├─── feature/drag-and-drop (task branch)
├─── feature/bottomsheet-redesign (task branch)
├─── bugfix/bottomsheet-scroll (task branch)
└─── ci/ios-workflow (task branch)
├─── feature/ARS-5-3d-model-preview (task branch)
├─── bugfix/ARS-6-gallery-crash (task branch)
├─── fix/ARS-7-camera-controls-symmetry (task branch)
├─── feature/ARS-8-short-description (task branch)
└─── bugfix/ARS-9-short-description (task branch)
```

### Branch Types
Expand Down Expand Up @@ -78,7 +78,7 @@ main (production-ready)
│ Agent creates feature branch from 'dev' │
│ git checkout dev │
│ git pull origin dev │
│ git checkout -b feature/task-name │
│ git checkout -b feature/ARS-N-task-name │
└───────────────────────┬─────────────────────────────────────┘
Expand All @@ -105,7 +105,7 @@ main (production-ready)
│ Agent commits and pushes to remote │
│ git add . │
│ git commit -m "feat: task description" │
│ git push origin feature/task-name │
│ git push origin feature/ARS-N-task-name │
└───────────────────────┬─────────────────────────────────────┘
Expand Down Expand Up @@ -159,18 +159,18 @@ main (production-ready)
### Components

- **type**: Branch type prefix (feature, bugfix, ci, refactor, test)
- **task-id**: Task ID from SQL database (kebab-case)
- **task-id**: Task ID from Jira board (ARS-N format, e.g. ARS-5)
- **short-description**: Optional 2-3 word description

### Examples

| Task ID | Branch Name | Agent |
|---------|-------------|-------|
| `ddd-value-objects` | `refactor/ddd-value-objects` | main-developer-agent |
| `drag-and-drop` | `feature/drag-and-drop` | android-expert-agent |
| `bottomsheet-scroll-bug` | `bugfix/bottomsheet-scroll` | bug-fixer-agent |
| `github-workflow-ios` | `ci/ios-workflow` | ios-expert-agent |
| `prevent-accidental-tap` | `feature/prevent-accidental-tap` | main-developer-agent |
| `ARS-5` | `feature/ARS-5-3d-model-preview` | android-expert-agent |
| `ARS-6` | `bugfix/ARS-6-gallery-crash` | bug-fixer-agent |
| `ARS-7` | `fix/ARS-7-camera-controls-symmetry` | main-developer-agent |
| `ARS-8` | `feature/ARS-8-short-description` | main-developer-agent |
| `ARS-9` | `bugfix/ARS-9-short-description` | bug-fixer-agent |

### Branch Type Selection Guide

Expand Down
45 changes: 45 additions & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.kover)
}

kotlin {
Expand All @@ -23,6 +24,8 @@ kotlin {
iosTarget.binaries.framework {
baseName = "ComposeApp"
isStatic = true
// Required for ModelPreviewThumbnail.ios.kt: platform.SceneKit.*
linkerOpts("-framework", "SceneKit")
}
}

Expand All @@ -35,6 +38,7 @@ kotlin {
implementation(libs.sceneview)
implementation(libs.arcore)
implementation(libs.gson)
implementation(libs.koin.android)
}
commonMain.dependencies {
implementation(compose.runtime)
Expand All @@ -48,6 +52,8 @@ kotlin {
implementation(libs.androidx.lifecycle.runtimeCompose)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.koin.core)
implementation(libs.koin.compose)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
Expand Down Expand Up @@ -88,3 +94,42 @@ dependencies {
debugImplementation(libs.compose.uiTooling)
}

koverReport {
defaults {
html {
onCheck = true
}
xml {
onCheck = true
}
}

filters {
excludes {
// Exclude generated code
classes("*_Factory", "*_HiltModules*", "Hilt_*", "*BuildConfig")
// Exclude Android framework classes
packages("*.di", "*.ui.theme")
// Exclude Compose generated
annotatedBy("androidx.compose.runtime.Composable")
}
}

verify {
rule {
isEnabled = true
// Domain layer should have high coverage
filters {
includes {
packages("com.trendhive.arsample.domain.*")
packages("com.trendhive.arsample.application.*")
}
}
bound {
minValue = 80
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.LINE
}
}
}
}

5 changes: 5 additions & 0 deletions composeApp/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
<!-- Camera izni - AR icin zorunlu -->
<uses-permission android:name="android.permission.CAMERA" />

<!-- Medya okuma izinleri - Galeri icin -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />

<!-- AR ozelligi gerektiren cihazlari belirt -->
<uses-feature
android:name="android.hardware.camera.ar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.trendhive.arsample.infrastructure.persistence.local.*
import com.trendhive.arsample.infrastructure.persistence.repository.*
import com.trendhive.arsample.application.usecase.*
import java.io.File
import com.trendhive.arsample.di.appModules
import com.trendhive.arsample.di.platformDataSourceModule
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.GlobalContext
import org.koin.core.context.startKoin

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -18,36 +20,18 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
super.onCreate(savedInstanceState)

// Simple DI setup for Android
val filesDir = applicationContext.filesDir
val modelFileStorage = ModelFileStorageImpl(applicationContext, filesDir)
val objectLocalDataSource = ARObjectLocalDataSourceImpl(filesDir)
val sceneDataStore = ARSceneDataStoreImpl(filesDir)

val objectRepository = ARObjectRepositoryImpl(objectLocalDataSource, modelFileStorage)
val sceneRepository = ARSceneRepositoryImpl(sceneDataStore)

val importObjectUseCase = ImportObjectUseCase(objectRepository)
val getAllObjectsUseCase = GetAllObjectsUseCase(objectRepository)
val deleteObjectUseCase = DeleteObjectUseCase(objectRepository)
val placeObjectInSceneUseCase = PlaceObjectInSceneUseCase(sceneRepository, objectRepository)
val removeObjectFromSceneUseCase = RemoveObjectFromSceneUseCase(sceneRepository)
val getSceneUseCase = GetSceneUseCase(sceneRepository)
val saveSceneUseCase = SaveSceneUseCase(sceneRepository)
val moveObjectUseCase = MoveObjectUseCase(sceneRepository)
// Initialize Koin DI only if not already started
// This prevents crash on Activity recreation (e.g., configuration change)
if (GlobalContext.getOrNull() == null) {
startKoin {
androidLogger()
androidContext(applicationContext)
modules(platformDataSourceModule() + appModules)
}
}

setContent {
App(
importObjectUseCase = importObjectUseCase,
getAllObjectsUseCase = getAllObjectsUseCase,
deleteObjectUseCase = deleteObjectUseCase,
placeObjectInSceneUseCase = placeObjectInSceneUseCase,
removeObjectFromSceneUseCase = removeObjectFromSceneUseCase,
getSceneUseCase = getSceneUseCase,
saveSceneUseCase = saveSceneUseCase,
moveObjectUseCase = moveObjectUseCase,
sceneRepository = sceneRepository
)
App()
}
}
}
Loading
Loading