diff --git a/.idea/TanksApp.iml b/.idea/TanksApp.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/TanksApp.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f8468d3 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..06fd2bc --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1703451140424 + + + + \ No newline at end of file diff --git a/compose/.gradle/8.0/executionHistory/executionHistory.bin b/compose/.gradle/8.0/executionHistory/executionHistory.bin index 6dd57db..28bbbf1 100644 Binary files a/compose/.gradle/8.0/executionHistory/executionHistory.bin and b/compose/.gradle/8.0/executionHistory/executionHistory.bin differ diff --git a/compose/.gradle/8.0/executionHistory/executionHistory.lock b/compose/.gradle/8.0/executionHistory/executionHistory.lock index 09d911f..6543fb5 100644 Binary files a/compose/.gradle/8.0/executionHistory/executionHistory.lock and b/compose/.gradle/8.0/executionHistory/executionHistory.lock differ diff --git a/compose/.gradle/8.0/fileHashes/fileHashes.bin b/compose/.gradle/8.0/fileHashes/fileHashes.bin index aeaf765..00f988d 100644 Binary files a/compose/.gradle/8.0/fileHashes/fileHashes.bin and b/compose/.gradle/8.0/fileHashes/fileHashes.bin differ diff --git a/compose/.gradle/8.0/fileHashes/fileHashes.lock b/compose/.gradle/8.0/fileHashes/fileHashes.lock index c0380cd..ad62f9a 100644 Binary files a/compose/.gradle/8.0/fileHashes/fileHashes.lock and b/compose/.gradle/8.0/fileHashes/fileHashes.lock differ diff --git a/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin b/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin index ab23362..91f08b3 100644 Binary files a/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin and b/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin differ diff --git a/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 9ce6e94..e829b2e 100644 Binary files a/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/compose/.gradle/file-system.probe b/compose/.gradle/file-system.probe index c9d4b02..9b786d8 100644 Binary files a/compose/.gradle/file-system.probe and b/compose/.gradle/file-system.probe differ diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/ServerService.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/ServerService.kt index 0c5d3cc..38b98f0 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/ServerService.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/ServerService.kt @@ -90,13 +90,13 @@ interface ServerService { @POST(ApiRoutes.NATION) suspend fun insertNation( - @Body product: NationRemote + @Body nation: NationRemote ): NationRemote @PUT("${ApiRoutes.NATION}/{id}") suspend fun updateNation( @Path("id") id: Long, - @Body product: NationRemote + @Body nation: NationRemote ): NationRemote @DELETE("${ApiRoutes.NATION}/{id}") @@ -159,12 +159,12 @@ interface ServerService { @GET("${ApiRoutes.USER_TANK}") suspend fun getUserTankCrossRef( - @Query("id") id: Long + @Query("userId") userId: Long ): List - @POST(ApiRoutes.USER_TANK) + @POST("${ApiRoutes.USER_TANK}") suspend fun insertUserTankCrossRef( - @Body tank: UserTankCrossRefRemote + @Body users_tank: UserTankCrossRefRemote ) : UserTankCrossRefRemote @DELETE("${ApiRoutes.USER_TANK}/deleteMyTank") diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/model/UserTankCrossRefRemote.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/model/UserTankCrossRefRemote.kt index 08e11bc..676d575 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/model/UserTankCrossRefRemote.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/model/UserTankCrossRefRemote.kt @@ -8,20 +8,22 @@ import java.util.Date @Serializable data class UserTankCrossRefRemote ( - val id: Long = 0, + val id: Long? = 0, + val userId: Long = 0, val tankId: Long = 0, @Serializable(with = DateSerializer::class) - val date: Date = Date() + val date: Date = Date(0) ) fun UserTankCrossRefRemote.toUserTankCrossRef(): UserTankCrossRef = UserTankCrossRef( - userId = id, + id = id, + userId = userId, tankId = tankId, date = date ) fun UserTankCrossRef.toRemote(): UserTankCrossRefRemote = UserTankCrossRefRemote( - id = userId, + userId = userId, tankId = tankId, date = date ) \ No newline at end of file diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/repository/RestTankRepository.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/repository/RestTankRepository.kt index 3e3d577..ecee2b5 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/repository/RestTankRepository.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/repository/RestTankRepository.kt @@ -115,7 +115,7 @@ class RestTankRepository ( } override suspend fun buyTank(tankId: Long, userId: Long, date: Date) { - service.insertUserTankCrossRef(UserTankCrossRefRemote(userId, tankId, date)) + service.insertUserTankCrossRef(UserTankCrossRef(userId, tankId, date).toRemote()) } override suspend fun insertMany(tankList: List) { diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/TankList.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/TankList.kt index 17c55b8..f77bfa8 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/TankList.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/TankList.kt @@ -59,6 +59,7 @@ import ru.ulstu.`is`.pmu.R import ru.ulstu.`is`.pmu.composeui.navigation.Screen import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.NationsListUiState +import ru.ulstu.`is`.pmu.tank.composeui.edit.PurchaseTankViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.UsersTanksEditViewModel import ru.ulstu.`is`.pmu.tank.composeui.list.TankListUiState @@ -77,6 +78,7 @@ import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme fun TankList( navController: NavController?, userTankEditViewModel: UsersTanksEditViewModel = viewModel(factory = AppViewModelProvider.Factory), + purchaseTankViewModel: PurchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory), viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory), listNations: NationDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory) ) { @@ -87,6 +89,7 @@ fun TankList( // Lazy Column, Pass the numbers array if (navController != null) { TankList( + purchaseTankViewModel = purchaseTankViewModel, nations = listNations.nationsListUiState, listTanks = viewModel.tankListUiState.tankList, viewModel = userTankEditViewModel @@ -99,6 +102,7 @@ fun TankList( @Composable fun ColumnItem( + purchaseTankViewModel: PurchaseTankViewModel, nation: Nation, tanks: List?, onClick: (uid: Long) -> Unit, @@ -106,14 +110,9 @@ fun ColumnItem( ) { val scope = rememberCoroutineScope() val tank = viewModel.usersTanksUiState + val userId = 100L - fun handleTankButtonClick() { - scope.launch { - if (tank.userTankCrossRef.tankId == 0L) { - viewModel.saveUserTank() - } - } - } + val coroutineScope = rememberCoroutineScope() Column( modifier = Modifier.padding(0.dp, 10.dp) @@ -177,11 +176,12 @@ fun ColumnItem( colors = ButtonDefaults.buttonColors( containerColor = CustomRed, contentColor = CustomDark), - onClick = { handleTankButtonClick() } + onClick = { + coroutineScope.launch { + purchaseTankViewModel.savePurchase(tank.tankId, userId) + } + } ) { - //navController?.navigate(Screen.Hangar.route) - //navController?.navigate(studentId) - //"${student.firstName} ${student.lastName}" Text(text = stringResource(id = R.string.purchase_button)) } } @@ -212,6 +212,7 @@ fun ColumnItem( @OptIn(ExperimentalMaterial3Api::class) @Composable private fun TankList( + purchaseTankViewModel: PurchaseTankViewModel, nations: NationsListUiState, listTanks: List, viewModel: UsersTanksEditViewModel, @@ -257,7 +258,7 @@ private fun TankList( } items(nations.nationList) {nation -> - ColumnItem(nation = nation, tanks = totalDictionary[nation], onClick = onClick, viewModel = viewModel) + ColumnItem(purchaseTankViewModel = purchaseTankViewModel, nation = nation, tanks = totalDictionary[nation], onClick = onClick, viewModel = viewModel) } // items(list/array) places number of @@ -279,6 +280,7 @@ fun TankListPreview() { color = CustomDark ) { TankList( + purchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory), nations = NationsListUiState(listOf()), viewModel = viewModel(factory = AppViewModelProvider.Factory), listTanks = (1..20).map { i -> Tank.getTank(i.toLong()) } @@ -296,6 +298,7 @@ fun TankEmptyListPreview() { color = CustomDark ) { TankList( + purchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory), nations = NationsListUiState(listOf()), viewModel = viewModel(factory = AppViewModelProvider.Factory), listTanks = listOf() diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/edit/BuyTankViewModel.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/edit/BuyTankViewModel.kt deleted file mode 100644 index 816cc65..0000000 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/edit/BuyTankViewModel.kt +++ /dev/null @@ -1,4 +0,0 @@ -package ru.ulstu.`is`.pmu.tank.composeui.edit - -class BuyTankViewModel { -} \ No newline at end of file diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/edit/PurchaseTankViewModel.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/edit/PurchaseTankViewModel.kt new file mode 100644 index 0000000..421293c --- /dev/null +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/edit/PurchaseTankViewModel.kt @@ -0,0 +1,61 @@ +package ru.ulstu.`is`.pmu.tank.composeui.edit + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef +import ru.ulstu.`is`.pmu.tank.repository.TankRepository +import java.util.Calendar +import java.util.Date + +class PurchaseTankViewModel ( + savedStateHandle: SavedStateHandle, + private val tankRepository: TankRepository +) : ViewModel() { + /*var purchaseUiState by mutableStateOf(PurchaseUiState()) + private set*/ + + suspend fun savePurchase(tankId: Long, userId: Long){ + if(tankId > 0 && userId > 0){ + tankRepository.buyTank(tankId, userId, Calendar.getInstance().time) + } + } + + /*private fun validateInput(uiState: PurchaseDetails = purchaseUiState.purchaseDetails): Boolean { + return with(uiState) { + userId > 0 + && tankId > 0 + } + }*/ +} + +/* +data class PurchaseUiState( + val purchaseDetails: PurchaseDetails = PurchaseDetails(), + val isEntryValid: Boolean = false +) + +data class PurchaseDetails( + val userId: Long = 0, + val tankId: Long = 0, + val date: Date = Calendar.getInstance().time, +) + +fun PurchaseDetails.toUserTankCrossRef(): UserTankCrossRef = UserTankCrossRef( + userId = userId, + tankId = tankId, + date = date +) + +fun UserTankCrossRef.toDetails(): PurchaseDetails = PurchaseDetails( + userId = userId, + tankId = tankId, + date = date +) + +fun UserTankCrossRef.toUiState(isEntryValid: Boolean = false) : PurchaseUiState = PurchaseUiState( + purchaseDetails = this.toDetails(), + isEntryValid = isEntryValid +)*/ \ No newline at end of file diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt index 013d53e..758ad03 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt @@ -52,7 +52,7 @@ abstract class AppDatabase : RoomDatabase() { abstract fun remoteKeysDao(): RemoteKeysDao companion object { - private const val DB_NAME: String = "25-db" + private const val DB_NAME: String = "27-db" @Volatile private var INSTANCE: AppDatabase? = null diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt index 52c0810..38df29c 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt @@ -1,5 +1,6 @@ package ru.ulstu.`is`.pmu.tank.model +import android.graphics.Bitmap import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.ForeignKey @@ -12,17 +13,26 @@ import java.util.Date //many to many for user and tank @Entity( tableName = "users_tanks", - primaryKeys = ["userId", "tankId"] ) data class UserTankCrossRef( + @PrimaryKey(autoGenerate = true) + val id: Long?, val userId: Long, val tankId: Long, @ColumnInfo(name = "date") val date: Date, ){ + @Ignore + constructor( + userId: Long, + tankId: Long, + date: Date, + ) : this(null, userId, tankId, date) + companion object { fun getEmpty(): UserTankCrossRef { return UserTankCrossRef( + id = 0, userId = 0, tankId = 0, date = Date() @@ -36,6 +46,7 @@ data class UserTankCrossRef( other as UserTankCrossRef + if (id != other.id) return false if (userId != other.userId) return false if (tankId != other.tankId) return false if (date != other.date) return false @@ -44,7 +55,8 @@ data class UserTankCrossRef( } override fun hashCode(): Int { - var result = userId.hashCode() + var result = id.hashCode() + result = 31 * result + userId.hashCode() result = 31 * result + tankId.hashCode() result = 31 * result + date.hashCode() return result diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt index f347887..fbcd56a 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt @@ -87,7 +87,7 @@ private fun Hangar( ) { var supportSizeRow = 1 - if(n == supportCountRow && supportSizeRow % 2 != 0 && tankList.size != 2){ + if(n == supportCountRow && index + supportSizeRow == tankList.size){ supportSizeRow = 0 } diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/ui/AppViewModelProvider.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/ui/AppViewModelProvider.kt index d60bb2e..9558347 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/ui/AppViewModelProvider.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/ui/AppViewModelProvider.kt @@ -9,6 +9,7 @@ import ru.ulstu.`is`.pmu.TankApplication import ru.ulstu.`is`.pmu.tank.composeui.edit.LevelDropDownViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.NationsListUiState +import ru.ulstu.`is`.pmu.tank.composeui.edit.PurchaseTankViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.ReportViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.UserEditViewModel @@ -30,6 +31,12 @@ object AppViewModelProvider { tankApplication().container.tankRestRepository ) } + initializer { + PurchaseTankViewModel( + this.createSavedStateHandle(), + tankApplication().container.tankRestRepository + ) + } initializer { UserEditViewModel( this.createSavedStateHandle(), diff --git a/compose/server/data.json b/compose/server/data.json index ec57225..0646c29 100644 --- a/compose/server/data.json +++ b/compose/server/data.json @@ -209,37 +209,44 @@ ], "users_tanks": [ { - "id": 100, + "id": 1, + "userId": 100, "tankId": 1, "date": "2023-12-12T12:06:14.720+0000" }, { - "id": 100, + "id": 2, + "userId": 100, "tankId": 5, "date": "2023-12-13T12:06:14.720+0000" }, { - "id": 100, + "id": 3, + "userId": 100, "tankId": 6, "date": "2023-12-14T12:06:14.720+0000" }, { - "id": 101, + "id": 4, + "userId": 101, "tankId": 6, "date": "2023-12-15T12:06:14.720+0000" }, { - "id": 101, + "id": 5, + "userId": 101, "tankId": 11, "date": "2023-12-16T12:06:14.720+0000" }, { - "id": 102, + "id": 6, + "userId": 102, "tankId": 6, "date": "2023-12-17T12:06:14.720+0000" }, { - "id": 102, + "id": 7, + "userId": 102, "tankId": 1, "date": "2023-12-18T12:06:14.720+0000" }