This commit is contained in:
2024-05-01 17:34:48 +03:00
parent 812ceec09c
commit 263cf81618
21 changed files with 475 additions and 61 deletions
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AppInsightsSettings">
<option name="selectedTabId" value="Firebase Crashlytics" />
<option name="tabSettings">
<map>
<entry key="Firebase Crashlytics">
<value>
<InsightsFilterSettings>
<option name="connection">
<ConnectionSetting>
<option name="appId" value="com.yaros.sweetshopviki" />
<option name="mobileSdkAppId" value="1:196968989683:android:40a8cee7ccf184d17e0886" />
<option name="projectId" value="sweetshopviki" />
<option name="projectNumber" value="196968989683" />
</ConnectionSetting>
</option>
<option name="signal" value="SIGNAL_UNSPECIFIED" />
<option name="timeIntervalDays" value="THIRTY_DAYS" />
<option name="visibilityType" value="ALL" />
</InsightsFilterSettings>
</value>
</entry>
</map>
</option>
</component>
</project>
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<value>
<entry key="app">
<State>
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\Yaros\.android\avd\Pixel_7_Pro_API_34.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2024-04-04T15:21:12.772882Z" />
</State>
</entry>
</value>
</component>
</project>
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2024-05-01T11:57:27.461772200Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Yaros\.android\avd\Pixel_API_33.avd" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
</project>
+2 -3
View File
@@ -4,16 +4,15 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" /> <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
</set> </set>
</option> </option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>
+246
View File
@@ -0,0 +1,246 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="direct_access_persist.xml">
<option name="deviceSelectionList">
<list>
<PersistentDeviceSelectionData>
<option name="api" value="27" />
<option name="brand" value="DOCOMO" />
<option name="codename" value="F01L" />
<option name="id" value="F01L" />
<option name="manufacturer" value="FUJITSU" />
<option name="name" value="F-01L" />
<option name="screenDensity" value="360" />
<option name="screenX" value="720" />
<option name="screenY" value="1280" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="28" />
<option name="brand" value="DOCOMO" />
<option name="codename" value="SH-01L" />
<option name="id" value="SH-01L" />
<option name="manufacturer" value="SHARP" />
<option name="name" value="AQUOS sense2 SH-01L" />
<option name="screenDensity" value="480" />
<option name="screenX" value="1080" />
<option name="screenY" value="2160" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="31" />
<option name="brand" value="samsung" />
<option name="codename" value="a51" />
<option name="id" value="a51" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy A51" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
<option name="selected" value="true" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="samsung" />
<option name="codename" value="b0q" />
<option name="id" value="b0q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S22 Ultra" />
<option name="screenDensity" value="600" />
<option name="screenX" value="1440" />
<option name="screenY" value="3088" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="32" />
<option name="brand" value="google" />
<option name="codename" value="bluejay" />
<option name="id" value="bluejay" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 6a" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="29" />
<option name="brand" value="samsung" />
<option name="codename" value="crownqlteue" />
<option name="id" value="crownqlteue" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Note9" />
<option name="screenDensity" value="420" />
<option name="screenX" value="2220" />
<option name="screenY" value="1080" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="felix" />
<option name="id" value="felix" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Fold" />
<option name="screenDensity" value="420" />
<option name="screenX" value="2208" />
<option name="screenY" value="1840" />
<option name="selected" value="true" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="felix_camera" />
<option name="id" value="felix_camera" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Fold (Camera-enabled)" />
<option name="screenDensity" value="420" />
<option name="screenX" value="2208" />
<option name="screenY" value="1840" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="samsung" />
<option name="codename" value="gts8uwifi" />
<option name="id" value="gts8uwifi" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Tab S8 Ultra" />
<option name="screenDensity" value="320" />
<option name="screenX" value="1848" />
<option name="screenY" value="2960" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="husky" />
<option name="id" value="husky" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 8 Pro" />
<option name="screenDensity" value="390" />
<option name="screenX" value="1008" />
<option name="screenY" value="2244" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="30" />
<option name="brand" value="motorola" />
<option name="codename" value="java" />
<option name="id" value="java" />
<option name="manufacturer" value="Motorola" />
<option name="name" value="G20" />
<option name="screenDensity" value="280" />
<option name="screenX" value="720" />
<option name="screenY" value="1600" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="lynx" />
<option name="id" value="lynx" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 7a" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="31" />
<option name="brand" value="google" />
<option name="codename" value="oriole" />
<option name="id" value="oriole" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 6" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="panther" />
<option name="id" value="panther" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 7" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="31" />
<option name="brand" value="samsung" />
<option name="codename" value="q2q" />
<option name="id" value="q2q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Z Fold3" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1768" />
<option name="screenY" value="2208" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="q5q" />
<option name="id" value="q5q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Z Fold5" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1812" />
<option name="screenY" value="2176" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="30" />
<option name="brand" value="google" />
<option name="codename" value="r11" />
<option name="id" value="r11" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Watch" />
<option name="screenDensity" value="320" />
<option name="screenX" value="384" />
<option name="screenY" value="384" />
<option name="type" value="WEAR_OS" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="30" />
<option name="brand" value="google" />
<option name="codename" value="redfin" />
<option name="id" value="redfin" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 5" />
<option name="screenDensity" value="440" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="shiba" />
<option name="id" value="shiba" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 8" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
<option name="selected" value="true" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="tangorpro" />
<option name="id" value="tangorpro" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Tablet" />
<option name="screenDensity" value="320" />
<option name="screenX" value="1600" />
<option name="screenY" value="2560" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="29" />
<option name="brand" value="samsung" />
<option name="codename" value="x1q" />
<option name="id" value="x1q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S20" />
<option name="screenDensity" value="480" />
<option name="screenX" value="1440" />
<option name="screenY" value="3200" />
<option name="selected" value="true" />
</PersistentDeviceSelectionData>
</list>
</option>
<option name="selectedCloudProject" value="sweetshopviki" />
</component>
</project>
Generated
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="" vcs="Git" />
</component> </component>
</project> </project>
+20 -19
View File
@@ -52,7 +52,7 @@ android {
} }
packaging { packaging {
resources { resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}" excludes += "/META-INF/{AL2.0,LGPL2.1,NOTICE.md,LICENSE.md}"
} }
} }
java { java {
@@ -65,17 +65,18 @@ android {
dependencies { dependencies {
implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.activity:activity-compose:1.8.1") implementation("androidx.activity:activity-compose:1.8.2")
implementation(platform("androidx.compose:compose-bom:2023.03.00")) implementation(platform("androidx.compose:compose-bom:2024.04.00"))
implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3") implementation("androidx.compose.material3:material3")
implementation("com.google.firebase:firebase-database-ktx:20.3.1")
testImplementation("junit:junit:4.13.2") testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) androidTestImplementation(platform("androidx.compose:compose-bom:2024.04.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4") androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest") debugImplementation("androidx.compose.ui:ui-test-manifest")
@@ -83,14 +84,14 @@ dependencies {
implementation(kotlin("stdlib-jdk8")) implementation(kotlin("stdlib-jdk8"))
implementation("androidx.legacy:legacy-support-v4:1.0.0") implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2") implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.5") implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
implementation("androidx.navigation:navigation-ui-ktx:2.7.5") implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
implementation(platform("com.google.firebase:firebase-bom:32.5.0")) implementation(platform("com.google.firebase:firebase-bom:32.8.1"))
implementation("com.google.firebase:firebase-auth-ktx") implementation("com.google.firebase:firebase-auth-ktx")
implementation("com.firebaseui:firebase-ui-auth:7.2.0") implementation("com.firebaseui:firebase-ui-auth:7.2.0")
implementation("com.google.firebase:firebase-firestore-ktx") implementation("com.google.firebase:firebase-firestore-ktx")
@@ -103,15 +104,15 @@ dependencies {
implementation("com.github.Spikeysanju:MotionToast:1.4") implementation("com.github.Spikeysanju:MotionToast:1.4")
implementation("com.github.ibrahimsn98:SmoothBottomBar:1.7.9") implementation("com.github.ibrahimsn98:SmoothBottomBar:1.7.9")
implementation("com.apachat:loadingbutton-android:1.0.11") implementation("com.apachat:loadingbutton-android:1.0.11")
implementation("com.google.android.material:material:1.10.0") implementation("com.google.android.material:material:1.11.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4") implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("com.google.code.gson:gson:2.9.1") implementation("com.google.code.gson:gson:2.10.1")
implementation("com.squareup.retrofit2:converter-gson:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("androidx.room:room-runtime:2.6.0") implementation("androidx.room:room-runtime:2.6.1")
implementation("androidx.room:room-ktx:2.6.0") implementation("androidx.room:room-ktx:2.6.1")
ksp("androidx.room:room-compiler:2.6.0") ksp("androidx.room:room-compiler:2.6.1")
implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("com.sun.mail:android-mail:1.6.2") implementation ("com.sun.mail:android-mail:1.6.6")
implementation ("com.sun.mail:android-activation:1.6.2") implementation ("com.sun.mail:android-activation:1.6.6")
} }
@@ -20,7 +20,7 @@ fun Float.formatPrice(): String {
fun ImageView.loadImage(url: String?) { fun ImageView.loadImage(url: String?) {
Picasso.get() Picasso.get()
.load("https://static.1000.menu/img/content-v2/05/f0/6402/chizkeik-iz-smetani_1579155436_15_max.jpg") .load(url)
.placeholder(R.drawable.loading) .placeholder(R.drawable.loading)
.error(R.drawable.error) .error(R.drawable.error)
.into(this) .into(this)
@@ -3,6 +3,7 @@ package com.yaros.sweetshopviki.data.repo
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.google.firebase.database.FirebaseDatabase
import com.yaros.sweetshopviki.common.utils.ApiUtils import com.yaros.sweetshopviki.common.utils.ApiUtils
import com.yaros.sweetshopviki.data.models.Categories import com.yaros.sweetshopviki.data.models.Categories
import com.yaros.sweetshopviki.data.models.Product import com.yaros.sweetshopviki.data.models.Product
@@ -51,7 +52,7 @@ class Repository(context: Context) {
try { try {
isLoading.value = LOADING.LOADING isLoading.value = LOADING.LOADING
val response = dif.getProducts(categoryId) val response = dif.getProducts(categoryId)
Log.d("PRODUCT", response.toString()) Log.d("CATEGORY", response.toString())
if (response.isSuccessful) { if (response.isSuccessful) {
val tempList = response.body() val tempList = response.body()
productList.value = tempList!! productList.value = tempList!!
@@ -60,12 +61,14 @@ class Repository(context: Context) {
isLoading.value = LOADING.ERROR isLoading.value = LOADING.ERROR
} }
} catch (t: Throwable) { } catch (t: Throwable) {
t.localizedMessage?.toString()?.let { Log.e("getProducts", it) } t.localizedMessage?.toString()?.let { Log.e("getCategories", it) }
isLoading.value = LOADING.ERROR isLoading.value = LOADING.ERROR
} }
} }
suspend fun getSearch() { suspend fun getSearch() {
try { try {
isLoading.value = LOADING.LOADING isLoading.value = LOADING.LOADING
@@ -108,7 +111,6 @@ class Repository(context: Context) {
} }
suspend fun addBookToBasket(productModel: ProductsBasketRoomModel) { suspend fun addBookToBasket(productModel: ProductsBasketRoomModel) {
val productFromDatabase = basketDif?.getProductById(productModel.productId) val productFromDatabase = basketDif?.getProductById(productModel.productId)
if (productFromDatabase != null) { if (productFromDatabase != null) {
@@ -123,8 +125,6 @@ class Repository(context: Context) {
} else { } else {
basketDif?.addProductBasket(productModel) basketDif?.addProductBasket(productModel)
} }
} }
suspend fun deleteBookFromBasket(productId: Int) { suspend fun deleteBookFromBasket(productId: Int) {
@@ -134,4 +134,47 @@ class Repository(context: Context) {
suspend fun clearBasket() { suspend fun clearBasket() {
basketDif?.clearBasket() basketDif?.clearBasket()
} }
suspend fun sendBasketToFirebase(userId: String) {
// Получаем доступ к DAO для доступа к данным корзины
val basketDao = basketDif
basketDao?.let {
// Получаем все продукты в корзине
val allProducts = it.getProductsBasket() // Предполагаем, что у DAO есть такой метод
if (allProducts!!.isNotEmpty()) {
// Получаем ссылку на базу данных Firebase
val databaseReference = FirebaseDatabase.getInstance().getReference("user_baskets")
// Создадим уникальный ключ для заказа
val key = databaseReference.push().key ?: return
// Структура данных для отправки
val orderInfo = hashMapOf<String, Any>(
"userId" to userId,
"products" to allProducts.map { product ->
mapOf(
"productName" to product.productName,
"count" to product.productCount,
"price" to product.productPrice
)
},
"timestamp" to System.currentTimeMillis()
)
// Отправляем данные в Firebase
databaseReference.child(key).setValue(orderInfo).addOnCompleteListener { task ->
if (task.isSuccessful) {
Log.d("Order","Order has been successfully sent to Firebase.")
} else {
Log.d("Order","Failed to send order to Firebase: ${task.exception?.message}")
}
}
} else {
Log.d("Order","Basket is empty.")
}
} ?: run {
Log.d("Order","basketDao is null.")
}
}
} }
@@ -5,15 +5,16 @@ import com.yaros.sweetshopviki.data.models.Product
import retrofit2.Response import retrofit2.Response
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Path import retrofit2.http.Path
import retrofit2.http.Query
interface DAOInterface { interface DAOInterface {
@GET("categories") @GET("categories")
suspend fun getCategories(): Response<List<Categories>> suspend fun getCategories(): Response<List<Categories>>
@GET("products/{categoryId}") @GET("products")
suspend fun getProducts(@Path("categoryId") categoryId: Int): Response<List<Product>> suspend fun getProducts(@Query("categoryId") categoryId: Int): Response<List<Product>>
@GET("search") @GET("products")
suspend fun getSearch(): Response<List<Product>> suspend fun getSearch(): Response<List<Product>>
} }
@@ -28,7 +28,5 @@ class MainActivity : AppCompatActivity() {
popupMenu.inflate(R.menu.menu) popupMenu.inflate(R.menu.menu)
val menu = popupMenu.menu val menu = popupMenu.menu
binding.navigationView.setupWithNavController(menu, navHostFragment.navController) binding.navigationView.setupWithNavController(menu, navHostFragment.navController)
} }
} }
@@ -20,7 +20,7 @@ class SplashActivity : AppCompatActivity() {
setContentView(binding.root) setContentView(binding.root)
CoroutineScope(Dispatchers.Main).launch { CoroutineScope(Dispatchers.Main).launch {
val intent = Intent(this@SplashActivity, LoginActivity::class.java) val intent = Intent(this@SplashActivity, MainActivity::class.java)
startActivity(intent) startActivity(intent)
finish() finish()
} }
@@ -1,10 +1,12 @@
package com.yaros.sweetshopviki.ui.basket package com.yaros.sweetshopviki.ui.basket
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuHost import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider import androidx.core.view.MenuProvider
@@ -12,6 +14,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.auth.FirebaseAuth
import com.yaros.sweetshopviki.R import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.formatPrice import com.yaros.sweetshopviki.common.formatPrice
import com.yaros.sweetshopviki.common.gone import com.yaros.sweetshopviki.common.gone
@@ -19,6 +22,7 @@ import com.yaros.sweetshopviki.common.visible
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
import com.yaros.sweetshopviki.data.repo.Repository import com.yaros.sweetshopviki.data.repo.Repository
import com.yaros.sweetshopviki.databinding.FragmentBasketBinding import com.yaros.sweetshopviki.databinding.FragmentBasketBinding
import com.yaros.sweetshopviki.ui.login.LoginActivity
import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding
class BasketFragment : Fragment(R.layout.fragment_basket) { class BasketFragment : Fragment(R.layout.fragment_basket) {
@@ -26,6 +30,7 @@ class BasketFragment : Fragment(R.layout.fragment_basket) {
private val binding by viewBinding(FragmentBasketBinding::bind) private val binding by viewBinding(FragmentBasketBinding::bind)
private val viewModel by lazy { BasketViewModel(requireContext()) } private val viewModel by lazy { BasketViewModel(requireContext()) }
private var basketAmount: Double = 0.0 private var basketAmount: Double = 0.0
private lateinit var auth: FirebaseAuth
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
(activity as AppCompatActivity?)!!.supportActionBar!!.title = (activity as AppCompatActivity?)!!.supportActionBar!!.title =
@@ -61,6 +66,7 @@ class BasketFragment : Fragment(R.layout.fragment_basket) {
} }
private fun initObservers() { private fun initObservers() {
auth = FirebaseAuth.getInstance()
binding.apply { binding.apply {
viewModel.apply { viewModel.apply {
isLoading.observe(viewLifecycleOwner) { isLoading.observe(viewLifecycleOwner) {
@@ -124,13 +130,22 @@ class BasketFragment : Fragment(R.layout.fragment_basket) {
addOrder.setOnClickListener { findNavController().navigate(BasketFragmentDirections.actionBasketFragmentToCategoriesFragment()) } addOrder.setOnClickListener { findNavController().navigate(BasketFragmentDirections.actionBasketFragmentToCategoriesFragment()) }
approveBasket.setOnClickListener { approveBasket.setOnClickListener {
findNavController().navigate( if (auth.currentUser == null) {
BasketFragmentDirections.actionBasketFragmentToPaymentFragment(basketAmount.toFloat()) onLoginActivity()
) } else {
findNavController().navigate(
BasketFragmentDirections.actionBasketFragmentToPaymentFragment(basketAmount.toFloat())
)
}
} }
} }
} }
} }
private fun onLoginActivity(){
val LoginIntent = Intent(context, LoginActivity::class.java)
Toast.makeText(context, R.string.loginpls, Toast.LENGTH_LONG).show()
startActivity(LoginIntent)
}
private fun onDeleteClick(productId: Int) { private fun onDeleteClick(productId: Int) {
viewModel.deleteProductFromBasket(productId) viewModel.deleteProductFromBasket(productId)
@@ -11,19 +11,22 @@ import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import android.widget.Button import android.widget.Button
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.yaros.sweetshopviki.R import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.formatPrice import com.yaros.sweetshopviki.common.formatPrice
import com.yaros.sweetshopviki.common.getPaymentImages import com.yaros.sweetshopviki.common.getPaymentImages
import com.yaros.sweetshopviki.common.getPaymentNames import com.yaros.sweetshopviki.common.getPaymentNames
import com.yaros.sweetshopviki.data.repo.OrderManager
import com.yaros.sweetshopviki.data.repo.Repository
import com.yaros.sweetshopviki.databinding.FragmentPaymentBinding import com.yaros.sweetshopviki.databinding.FragmentPaymentBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.* import java.util.*
import javax.mail.* import javax.mail.*
import javax.mail.internet.InternetAddress import javax.mail.internet.InternetAddress
@@ -34,10 +37,9 @@ class PaymentFragment : BottomSheetDialogFragment() {
private var _binding: FragmentPaymentBinding? = null private var _binding: FragmentPaymentBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private val viewModel by lazy { PaymentViewModel(requireContext()) } private val viewModel by lazy { PaymentViewModel(requireContext()) }
private val args: PaymentFragmentArgs by navArgs() private val args: PaymentFragmentArgs by navArgs()
private lateinit var orderManager: OrderManager
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@@ -77,18 +79,26 @@ class PaymentFragment : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val repository = Repository(requireContext()) // Получаем контекст с помощью requireContext()
orderManager = OrderManager(repository)
val user = FirebaseAuth.getInstance().currentUser val user = FirebaseAuth.getInstance().currentUser
val email = user?.email val email = user?.email
val subject = "Ваш заказ" val subject = "Ваш заказ"
val body = "Уважаемый пользователь \n Ваш заказ отправлен на указанный вами адрес\n Ваш заказ готовится и скоро приедит к вам :) \n С уважением Кондитерская Вики" val name = user?.displayName
binding.apply { binding.apply {
closePaymentScreen.setOnClickListener { findNavController().popBackStack() } closePaymentScreen.setOnClickListener { findNavController().popBackStack() }
orderNow.setOnClickListener { orderNow.setOnClickListener {
if (orderAddress.text.isEmpty().not()) { if (orderAddress.text.isEmpty().not()) {
showOrderSuccessDialog() showOrderSuccessDialog()
sendMail(email!!, subject, body) val address = orderAddress.text
sendMail(email!!,subject, name!!, address.toString())
Log.d("Email", email) Log.d("Email", email)
lifecycleScope.launch {
handleOrder()
}
viewModel.clearBasket() viewModel.clearBasket()
} else { } else {
orderAddress.error = getString(R.string.address_error) orderAddress.error = getString(R.string.address_error)
@@ -113,6 +123,10 @@ class PaymentFragment : BottomSheetDialogFragment() {
} }
} }
private suspend fun handleOrder() {
orderManager.placeOrder()
}
private fun showOrderSuccessDialog() { private fun showOrderSuccessDialog() {
val alertDialog = AlertDialog.Builder(requireContext()) val alertDialog = AlertDialog.Builder(requireContext())
@@ -133,34 +147,45 @@ class PaymentFragment : BottomSheetDialogFragment() {
} }
} }
private fun sendMail(toEmail: String, subject: String, body: String) { private fun sendMail(toEmail: String, subject: String, name: String, address: String) {
Thread { lifecycleScope.launch(Dispatchers.IO) { // Используем IO диспетчер для выполнения сетевых операций
val props = Properties() val props = Properties()
props["mail.smtp.host"] = "smtp.yandex.ru" props["mail.smtp.host"] = "smtp.yandex.ru"
props["mail.smtp.socketFactory.port"] = "465" props["mail.smtp.socketFactory.port"] = "465"
props["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory" props["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"
props["mail.smtp.auth"] = "true" props["mail.smtp.auth"] = "true"
props["mail.smtp.port"] = "465" props["mail.smtp.port"] = "465"
val session = Session.getDefaultInstance(props, val session = Session.getDefaultInstance(props,
object : Authenticator() { object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication("VikiSweetShop@yandex.ru", "wpvldcgiythzbouq") return PasswordAuthentication("VikiSweetShop@yandex.ru", "wpvldcgiythzbouq")
} }
}) })
val message = MimeMessage(session) val message = MimeMessage(session)
try { try {
message.setFrom(InternetAddress.parse("VikiSweetShop@yandex.ru")[0]) val emailBody = """
<h1>Уважаемый(ая) $name,</h1>
<p>Благодарим вас за ваш заказ из Кондитерской Вики!</p>
<p>Ваш заказ</p>
<p>Будет отправлен на следующий адрес: $address</p>
<p>С уважением,<br>Команда Кондитерской Вики</p>
""".trimIndent()
message.setFrom(InternetAddress("VikiSweetShop@yandex.ru"))
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail)) message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail))
message.subject = subject message.subject = subject
message.setText(body) message.setContent(emailBody, "text/html; charset=utf-8")
Transport.send(message) Transport.send(message)
Log.d("EMAIL", "SUCCESS") Log.d("EMAIL", "Email sent successfully")
} catch (e: MessagingException) { } catch (e: MessagingException) {
Log.d("EMAIL", "Failed to send email", e) Log.e("EMAIL", "Failed to send email", e)
} }
}.start() }
} }
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null _binding = null
@@ -3,6 +3,7 @@ package com.yaros.sweetshopviki.ui.payment
import android.content.Context import android.content.Context
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
import com.yaros.sweetshopviki.data.repo.Repository import com.yaros.sweetshopviki.data.repo.Repository
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -46,12 +46,12 @@ class ProductDetailFragment : BottomSheetDialogFragment() {
val product = args.product val product = args.product
binding.apply { binding.apply {
productImage.loadImage(product.imagePath?.substring(39).toString()) productImage.loadImage(product.imagePath)
totalPrice = product.price totalPrice = product.price
price = product.price price = product.price
productName.text = product.name productName.text = product.name
updatePrice() updatePrice()
productCount.text = count.toString() productCount.text = minOf(count, 25).toString()
increase.setOnClickListener { increaseCount() } increase.setOnClickListener { increaseCount() }
decrease.setOnClickListener { decreaseCount() } decrease.setOnClickListener { decreaseCount() }
cancel.setOnClickListener { findNavController().popBackStack() } cancel.setOnClickListener { findNavController().popBackStack() }
@@ -80,19 +80,24 @@ class ProductDetailFragment : BottomSheetDialogFragment() {
} }
private fun increaseCount() { private fun increaseCount() {
count += 1 if (count < 25) {
binding.productCount.text = count.toString() count += 1
updatePrice() binding.productCount.text = count.toString()
updatePrice()
}
} }
private fun decreaseCount() { private fun decreaseCount() {
if (count >= 2) { if (count > 1) {
count -= 1 count -= 1
binding.productCount.text = count.toString() binding.productCount.text = count.toString()
updatePrice() updatePrice()
} }
} }
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null _binding = null
+1
View File
@@ -57,4 +57,5 @@
<string name="credit_card">Банковская карта</string> <string name="credit_card">Банковская карта</string>
<string name="cash">Наличные</string> <string name="cash">Наличные</string>
<string name="yorsorder">Ваш заказ</string> <string name="yorsorder">Ваш заказ</string>
<string name="loginpls">Пожалуйста войдите в свой аккаунт чтобы сделать заказ</string>
</resources> </resources>
+1
View File
@@ -56,6 +56,7 @@
<string name="credit_card">Credit Card</string> <string name="credit_card">Credit Card</string>
<string name="cash">Cash</string> <string name="cash">Cash</string>
<string name="yorsorder">Ваш заказ</string> <string name="yorsorder">Ваш заказ</string>
<string name="loginpls">Please log in to your account to place an order</string>
<string-array name="app_logo_strings"> <string-array name="app_logo_strings">
<item>M255.7,459.08c-56,0 -111.95,-0.09 -167.92,0.06 -15.52,0 -26.35,-6.78 -32.73,-20.69 -1.7,-3.71 -2,-7.93 -2,-12q0,-170.16 0,-340.31c0,-19 14.19,-33 33.22,-33q169.66,-0.06 339.34,0C445,53.11 459,67.14 459,86.5q0.06,169.91 0,339.82c0,18.76 -14.09,32.73 -32.86,32.74Q340.91,459.12 255.7,459.08ZM197.48,147.88c-14.66,0 -29.32,0.19 -44,-0.12 -4,-0.08 -5.88,1.25 -7.31,4.82 -3.95,9.9 -7.93,19.79 -10.67,30.08 -5.25,19.76 -8.78,39.72 -5.17,60.23 3,17.09 10.58,31.37 25.42,41.27 8.24,5.5 17.41,8.26 27,9.63 3.87,0.56 4.82,2.11 4.74,5.78q-0.33,16.23 0,32.47c0.08,3.48 -0.91,4.94 -4.42,5.68 -9,1.9 -17.81,4.21 -26.68,6.49 -5.25,1.35 -8.63,5.88 -8.11,10.5a10.33,10.33 0,0 0,10.43 9q38.48,0.13 77,0c5.66,0 9.9,-3.77 10.49,-8.77s-2.55,-9.31 -8.27,-10.76c-8.87,-2.24 -17.74,-4.56 -26.68,-6.5 -3.29,-0.71 -4.2,-2.12 -4.14,-5.36 0.19,-10.82 0.26,-21.66 0,-32.48 -0.1,-3.9 0.89,-5.48 4.95,-6 14.23,-1.94 27,-7.23 36.87,-18.08 14.61,-16.07 17.71,-35.69 16.54,-56.35 -1.34,-23.72 -8.09,-46.1 -17.53,-67.79 -1.32,-3 -2.93,-3.75 -6,-3.72C227.13,148 212.3,147.88 197.48,147.88ZM383.12,191.59c0,-11.67 0,-21.16 0,-30.65 0,-8.19 -3.69,-13.05 -9.83,-13s-9.52,4.7 -9.55,12.68c0,6.17 0,12.33 0,18.49 0,9 0.13,18 -0.06,27 -0.14,6.28 -4.25,10.31 -9.92,10.29 -5.83,0 -9.41,-3.9 -9.61,-10.42 -0.05,-1.66 0,-3.33 0,-5q0,-21.24 0,-42.47c0,-4.66 -2.22,-7.88 -6.44,-9.79 -3.66,-1.65 -6.86,-0.56 -9.75,1.75s-3.53,5.84 -3.53,9.46q0,22.72 0,45.46c0,3.66 -0.64,7 -4,9.17a9.76,9.76 0,0 1,-10.41 0.68c-3.91,-2 -5.2,-5.41 -5.21,-9.49 0,-15.49 0,-31 0,-46.47 0,-6.74 -3.75,-11.12 -9.42,-11.32s-10.11,4.67 -10.14,11.25c-0.07,18.65 -0.63,37.33 0.16,56 1,22.83 11.91,39.41 33.77,47.77 2.49,0.95 2.83,2.13 2.59,4.39Q320,284 318.49,300.61c-1.27,13.93 -2.7,27.85 -3.58,41.8C314,357.23 327,367 340.78,362.15c9.35,-3.29 13.84,-11.25 12.77,-22.74 -2.16,-23.2 -4.22,-46.42 -6.65,-69.6 -0.47,-4.5 0.78,-6.24 4.94,-7.84 16.26,-6.24 26.39,-18.12 30,-35.18C384.52,214.44 382.46,201.87 383.12,191.59Z</item> <item>M255.7,459.08c-56,0 -111.95,-0.09 -167.92,0.06 -15.52,0 -26.35,-6.78 -32.73,-20.69 -1.7,-3.71 -2,-7.93 -2,-12q0,-170.16 0,-340.31c0,-19 14.19,-33 33.22,-33q169.66,-0.06 339.34,0C445,53.11 459,67.14 459,86.5q0.06,169.91 0,339.82c0,18.76 -14.09,32.73 -32.86,32.74Q340.91,459.12 255.7,459.08ZM197.48,147.88c-14.66,0 -29.32,0.19 -44,-0.12 -4,-0.08 -5.88,1.25 -7.31,4.82 -3.95,9.9 -7.93,19.79 -10.67,30.08 -5.25,19.76 -8.78,39.72 -5.17,60.23 3,17.09 10.58,31.37 25.42,41.27 8.24,5.5 17.41,8.26 27,9.63 3.87,0.56 4.82,2.11 4.74,5.78q-0.33,16.23 0,32.47c0.08,3.48 -0.91,4.94 -4.42,5.68 -9,1.9 -17.81,4.21 -26.68,6.49 -5.25,1.35 -8.63,5.88 -8.11,10.5a10.33,10.33 0,0 0,10.43 9q38.48,0.13 77,0c5.66,0 9.9,-3.77 10.49,-8.77s-2.55,-9.31 -8.27,-10.76c-8.87,-2.24 -17.74,-4.56 -26.68,-6.5 -3.29,-0.71 -4.2,-2.12 -4.14,-5.36 0.19,-10.82 0.26,-21.66 0,-32.48 -0.1,-3.9 0.89,-5.48 4.95,-6 14.23,-1.94 27,-7.23 36.87,-18.08 14.61,-16.07 17.71,-35.69 16.54,-56.35 -1.34,-23.72 -8.09,-46.1 -17.53,-67.79 -1.32,-3 -2.93,-3.75 -6,-3.72C227.13,148 212.3,147.88 197.48,147.88ZM383.12,191.59c0,-11.67 0,-21.16 0,-30.65 0,-8.19 -3.69,-13.05 -9.83,-13s-9.52,4.7 -9.55,12.68c0,6.17 0,12.33 0,18.49 0,9 0.13,18 -0.06,27 -0.14,6.28 -4.25,10.31 -9.92,10.29 -5.83,0 -9.41,-3.9 -9.61,-10.42 -0.05,-1.66 0,-3.33 0,-5q0,-21.24 0,-42.47c0,-4.66 -2.22,-7.88 -6.44,-9.79 -3.66,-1.65 -6.86,-0.56 -9.75,1.75s-3.53,5.84 -3.53,9.46q0,22.72 0,45.46c0,3.66 -0.64,7 -4,9.17a9.76,9.76 0,0 1,-10.41 0.68c-3.91,-2 -5.2,-5.41 -5.21,-9.49 0,-15.49 0,-31 0,-46.47 0,-6.74 -3.75,-11.12 -9.42,-11.32s-10.11,4.67 -10.14,11.25c-0.07,18.65 -0.63,37.33 0.16,56 1,22.83 11.91,39.41 33.77,47.77 2.49,0.95 2.83,2.13 2.59,4.39Q320,284 318.49,300.61c-1.27,13.93 -2.7,27.85 -3.58,41.8C314,357.23 327,367 340.78,362.15c9.35,-3.29 13.84,-11.25 12.77,-22.74 -2.16,-23.2 -4.22,-46.42 -6.65,-69.6 -0.47,-4.5 0.78,-6.24 4.94,-7.84 16.26,-6.24 26.39,-18.12 30,-35.18C384.52,214.44 382.46,201.87 383.12,191.59Z</item>
+3 -3
View File
@@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id("com.android.application") version "8.1.4" apply false id("com.android.application") version "8.4.0" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false id("org.jetbrains.kotlin.android") version "1.9.0" apply false
id("com.google.gms.google-services") version "4.4.0" apply false id("com.google.gms.google-services") version "4.4.0" apply false
id("com.google.devtools.ksp") version "1.9.10-1.0.13" apply false id("com.google.devtools.ksp") version "1.9.10-1.0.13" apply false
@@ -15,7 +15,7 @@ buildscript {
} }
dependencies { dependencies {
classpath(kotlin("gradle-plugin", version = "1.9.10")) classpath(kotlin("gradle-plugin", version = "1.9.10"))
classpath ("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.5") classpath ("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7")
classpath ("com.google.gms:google-services:4.4.0") classpath ("com.google.gms:google-services:4.4.1")
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
#Sat Oct 14 21:46:09 MSK 2023 #Sat Oct 14 21:46:09 MSK 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists