فهرست منبع

App: фильтры и личный кабинет

Blueris 17 ساعت پیش
والد
کامیت
e977845214

+ 1 - 0
OscellaMobile/app/build.gradle.kts

@@ -88,6 +88,7 @@ dependencies {
     implementation ("androidx.compose.ui:ui-tooling-preview:1.3.0") // для предварительного просмотра
     implementation ("androidx.activity:activity-compose:1.6.0")
     implementation ("com.pierfrancescosoffritti.androidyoutubeplayer:core:11.1.0")
+    implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.6.0") // или последняя версия
 
     implementation(libs.coil.compose)
 

+ 15 - 19
OscellaMobile/app/src/main/java/com/example/oscellamobile/Auth.kt

@@ -1,33 +1,19 @@
 package com.example.oscellamobile
 
+import android.R
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import androidx.navigation.NavController
 import com.example.oscellamobile.domain.utlis.Constant
+import com.example.oscellamobile.models.Users
 import io.github.jan.supabase.gotrue.auth
 import io.github.jan.supabase.gotrue.providers.builtin.Email
-import io.github.jan.supabase.gotrue.providers.builtin.OTP
+import io.github.jan.supabase.postgrest.from
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.selects.select
 
 
 class Auth(): ViewModel() {
-
-    fun onSignInEmailCode(emailUser: String) {
-        viewModelScope.launch {
-            try {
-                Constant.supabase.auth.signInWith(OTP) {
-                    email = emailUser
-                    createUser = false
-                }
-
-            } catch (e: Exception) {
-                println(e.message.toString())
-
-            }
-
-        }
-    }
-
     fun onSignInEmailPassword(emailUser: String, passwordUser: String, navController: NavController) {
         viewModelScope.launch {
             try {
@@ -45,16 +31,26 @@ class Auth(): ViewModel() {
             }
         }
     }
-    fun onSignUpEmail(emailUser: String, passwordUser: String) {
+
+    fun onSignUpEmail(emailUser: String, passwordUser: String, login: String, navController: NavController) {
         viewModelScope.launch {
             try{
                 var  user =  Constant.supabase.auth.signUpWith(Email) {
                     email = emailUser
                     password = passwordUser
                 }
+
                 println(user.toString())
                 println(Constant.supabase.auth.currentUserOrNull()!!.id)
                 println("Success")
+                val count = Constant.supabase.from("Users").select().data.count()
+                val NewUser = Users(
+                    id =  count.toInt(),
+                    user = (Constant.supabase.auth.currentUserOrNull()!!.id).toString(),
+                    login = login
+                )
+                Constant.supabase.from("Users").insert(NewUser)
+                navController.navigate("Auth")
             }
             catch (e: Exception) {
                 println("Error")

+ 64 - 0
OscellaMobile/app/src/main/java/com/example/oscellamobile/Favourites.kt

@@ -0,0 +1,64 @@
+package com.example.oscellamobile
+
+import androidx.compose.runtime.Composable
+import androidx.lifecycle.ViewModel
+import androidx.navigation.NavController
+import com.example.oscellamobile.domain.utlis.Constant.supabase
+import com.example.oscellamobile.models.Favorite
+import com.example.oscellamobile.models.Game
+import io.github.jan.supabase.postgrest.from
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+
+class Favourites(): ViewModel() {
+    suspend fun addToFavorites(id_game: Int, id_user: Int, navController: NavController, fav: Int?, screen: String) {
+        val newFav = Favorite(
+            id_game = id_game,
+            id_user = id_user
+        )
+
+        val newFavouritesCount = fav?.plus(1) ?: 1
+
+        val response = supabase.from("Game").update(
+            {
+                Game::favourites setTo newFavouritesCount
+                set("favourites", newFavouritesCount)
+            }
+        ) {
+            filter {
+                Game::id eq id_game
+            }
+        }
+
+        withContext(Dispatchers.IO) {
+            supabase.from("Favorite").insert(newFav)
+        }
+        navController.navigate(screen)
+    }
+
+    suspend fun removeFromFavorites(id_game: Int, id_user: Int, navController: NavController, fav: Int?, screen: String) {
+        withContext(Dispatchers.IO) {
+
+            val newFavouritesCount = fav?.minus(1) ?: 1
+
+            supabase.from("Game").update(
+                {
+                    Game::favourites setTo newFavouritesCount
+                    set("favourites", newFavouritesCount)
+                }
+            ) {
+                filter {
+                    Game::id eq id_game
+                }
+            }
+
+            val response = supabase.from("Favorite").delete {
+                filter {
+                    (Favorite::id_game eq id_game)
+                    (Favorite::id_user eq id_user)
+                }
+            }
+        }
+        navController.navigate(screen)
+    }
+}

+ 5 - 4
OscellaMobile/app/src/main/java/com/example/oscellamobile/Navigation/Navigation.kt

@@ -12,8 +12,8 @@ import com.example.oscellamobile.screens.AuthWithEmail
 import com.example.oscellamobile.screens.CloudList
 import com.example.oscellamobile.screens.CompanyList
 import com.example.oscellamobile.screens.MainWindow
+import com.example.oscellamobile.screens.PersonalView
 import com.example.oscellamobile.screens.Registration
-import com.example.oscellamobile.screens.RegistrationWithEmail
 import com.example.oscellamobile.screens.SplashScreen
 @Composable
 fun Navigation() {
@@ -33,9 +33,6 @@ fun Navigation() {
         composable("Registration") {
             Registration(navController)
         }
-        composable("RegistrationWithEmail"){
-            RegistrationWithEmail(navController)
-        }
         composable("MainWindow"){
             MainWindow(navController)
         }
@@ -59,5 +56,9 @@ fun Navigation() {
             val id = backStackEntry.arguments?.getString("id")?.toInt() ?: 0
             AboutCompany(navController, id)
         }
+        composable("PersonalView")
+        {
+            PersonalView(navController)
+        }
     }
 }

+ 64 - 0
OscellaMobile/app/src/main/java/com/example/oscellamobile/YouTube.kt

@@ -0,0 +1,64 @@
+package com.example.oscellamobile
+
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
+import androidx.lifecycle.ViewModel
+
+class YouTube(): ViewModel() {
+    fun extractVideoId(videoUrl: String): String? {
+        val regex = Regex("(?:https?://)?(?:www\\.)?(?:youtube\\.com/watch\\?v=|youtu\\.be/)([a-zA-Z0-9_-]{11})")
+        return regex.find(videoUrl)?.groups?.get(1)?.value
+    }
+
+    @Composable
+    fun VideoPlayerFromUrl(videoUrl: String) {
+        val videoId = extractVideoId(videoUrl)
+
+        if (videoId != null) {
+            VideoPlayer(videoId)
+        } else {
+            Text("Неверная ссылка на видео")
+        }
+    }
+
+    @Composable
+    fun VideoPlayer(videoId: String) {
+        AndroidView(
+            factory = { context ->
+                WebView(context).apply {
+                    webViewClient = WebViewClient()
+                    settings.javaScriptEnabled = true // Включаем JavaScript
+                }
+            },
+            update = { webView ->
+                val html = """
+  <html>
+    <body style="margin:0;padding:0;">
+        <div style="padding: 0 5px;">
+            <iframe 
+                width="100%" 
+                height="200" 
+                src="https://www.youtube.com/embed/$videoId" 
+                frameborder="0" 
+                allowfullscreen 
+                style="border-radius: 15px; overflow: hidden;">
+            </iframe>
+        </div>
+    </body>
+</html>
+            """.trimIndent()
+                webView.loadData(html, "text/html", "UTF-8")
+            },
+            modifier = Modifier.fillMaxWidth()
+                .height(200.dp)
+        )
+    }
+
+}

+ 38 - 37
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/AboutCloud.kt

@@ -1,20 +1,15 @@
 package com.example.oscellamobile.screens
 
 import android.util.Log
-import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
-import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
-import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
@@ -27,12 +22,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Card
-import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.Icon
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -40,64 +32,44 @@ import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
-import androidx.compose.ui.draw.shadow
-import androidx.compose.ui.geometry.CornerRadius
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.RadialGradientShader
-import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.graphics.Shadow
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.drawscope.DrawScope
-import androidx.compose.ui.graphics.painter.Painter
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.font.Font
-import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import androidx.navigation.NavHost
 import androidx.navigation.NavHostController
 import coil.compose.rememberAsyncImagePainter
 import com.example.oscellamobile.domain.utlis.Constant
 import com.example.oscellamobile.models.Game
-import com.google.accompanist.systemuicontroller.rememberSystemUiController
 import io.github.jan.supabase.postgrest.from
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
 import kotlinx.coroutines.withContext
-import kotlin.math.cos
-import kotlin.math.sin
 import com.example.oscellamobile.R
-import com.example.oscellamobile.models.Company
 import coil.compose.AsyncImagePainter
-import coil.compose.rememberAsyncImagePainter
 import coil.request.ImageRequest
 import coil.size.Size
 import com.example.oscellamobile.Link
-import com.example.oscellamobile.models.Age_rating
-import com.example.oscellamobile.models.Basic_labels
 import com.example.oscellamobile.models.Game_Cloud
-import com.example.oscellamobile.models.Genre
-import com.example.oscellamobile.models.Label
+import com.example.oscellamobile.models.Users
 import com.example.oscellamobile.models.Сloud_gaming
-import io.github.jan.supabase.realtime.Column
-import org.intellij.lang.annotations.JdkConstants
-import java.time.Month
+import io.github.jan.supabase.gotrue.auth
 
 @Composable
 fun AboutCloud(navHost: NavHostController, id: Int) {
     var clouds by remember { mutableStateOf<List<Сloud_gaming>>(listOf()) }
     var game by remember { mutableStateOf<List<Game>>(listOf()) }
     var gamecloud by remember { mutableStateOf<List<Game_Cloud>>(listOf()) }
+    var user by remember{mutableStateOf<List<Users>>(listOf())}
     LaunchedEffect(Unit) {
         withContext(Dispatchers.IO) {
             try {
                 clouds = Constant.supabase.from("Сloud_gaming").select().decodeList<Сloud_gaming>()
                 game = Constant.supabase.from("Game").select().decodeList<Game>()
                 gamecloud = Constant.supabase.from("Game_Cloud").select().decodeList<Game_Cloud>()
+                user = Constant.supabase.from("Users").select().decodeList<Users>()
                 clouds.forEach { Cloud ->
                     Log.d("C", Cloud.cloud_name)
                 }
@@ -136,11 +108,40 @@ fun AboutCloud(navHost: NavHostController, id: Int) {
             Spacer(modifier = Modifier.width(13.dp))
             Text(text = "Osccela", fontSize = 40.sp, fontFamily = kdamFontFamily)
             Spacer(modifier = Modifier.width(145.dp))
-            Image(
-                painter = painterResource(id = R.drawable.personall),
-                contentDescription = "Описание изображения",
-                modifier = Modifier.size(90.dp)
-            )
+            Column(
+                verticalArrangement = Arrangement.Center,
+                horizontalAlignment = Alignment.CenterHorizontally
+            ) {
+                Image(
+                    painter = painterResource(id = R.drawable.personall),
+                    contentDescription = "Описание изображения",
+                    modifier = Modifier.size(90.dp)
+                        .clickable(onClick = {
+                            navHost.navigate("PersonalView")
+                        })
+                )
+
+                val userId = Constant.supabase.auth.currentUserOrNull()?.id
+                val userIdString = userId.toString()
+
+                LazyColumn(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalAlignment = Alignment.CenterHorizontally
+                ) {
+                    items(user) { US ->
+                        if (userIdString == US.user) {
+                            Text(
+                                US.login,
+                                fontFamily = kdamFontFamily,
+                                fontSize = 20.sp,
+                                color = Color.Black,
+                                textAlign = TextAlign.Center,
+                                modifier = Modifier.fillMaxWidth()
+                            )
+                        }
+                    }
+                }
+            }
         }
         LazyColumn {
             items(

+ 38 - 32
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/AboutCompany.kt

@@ -1,20 +1,15 @@
 package com.example.oscellamobile.screens
 
 import android.util.Log
-import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
-import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
-import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
@@ -27,12 +22,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Card
-import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.Icon
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -40,19 +32,11 @@ import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
-import androidx.compose.ui.draw.shadow
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.RadialGradientShader
-import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.graphics.Shadow
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.font.Font
-import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
@@ -60,36 +44,29 @@ import androidx.navigation.NavHostController
 import coil.compose.rememberAsyncImagePainter
 import com.example.oscellamobile.domain.utlis.Constant
 import com.example.oscellamobile.models.Game
-import com.google.accompanist.systemuicontroller.rememberSystemUiController
 import io.github.jan.supabase.postgrest.from
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
 import kotlinx.coroutines.withContext
-import kotlin.math.cos
-import kotlin.math.sin
 import com.example.oscellamobile.R
 import com.example.oscellamobile.models.Company
 import coil.compose.AsyncImagePainter
-import coil.compose.rememberAsyncImagePainter
 import coil.request.ImageRequest
 import coil.size.Size
-import com.example.oscellamobile.Link
-import com.example.oscellamobile.models.Age_rating
-import com.example.oscellamobile.models.Basic_labels
-import com.example.oscellamobile.models.Genre
-import com.example.oscellamobile.models.Label
-import org.intellij.lang.annotations.JdkConstants
+import com.example.oscellamobile.models.Users
+import io.github.jan.supabase.gotrue.auth
 
 @Composable
 fun AboutCompany(navHost: NavHostController, id: Int) {
     var company by remember { mutableStateOf<List<Company>>(listOf()) }
     var games by remember { mutableStateOf<List<Game>>(listOf()) }
+    var user by remember { mutableStateOf<List<Users>>(listOf()) }
 
     LaunchedEffect(Unit) {
         withContext(Dispatchers.IO) {
             try {
                 company = Constant.supabase.from("Company").select().decodeList<Company>()
                 games = Constant.supabase.from("Game").select().decodeList<Game>()
+                user = Constant.supabase.from("Users").select().decodeList<Users>()
                 company.forEach { Company ->
                     Log.d("C", Company.name_company)
                 }
@@ -129,11 +106,40 @@ fun AboutCompany(navHost: NavHostController, id: Int) {
             Spacer(modifier = Modifier.width(13.dp))
             Text(text = "Osccela", fontSize = 40.sp, fontFamily = kdamFontFamily)
             Spacer(modifier = Modifier.width(145.dp))
-            Image(
-                painter = painterResource(id = R.drawable.personall),
-                contentDescription = "Описание изображения",
-                modifier = Modifier.size(90.dp)
-            )
+            Column(
+                verticalArrangement = Arrangement.Center,
+                horizontalAlignment = Alignment.CenterHorizontally // Центрируем по горизонтали
+            ) {
+                Image(
+                    painter = painterResource(id = R.drawable.personall),
+                    contentDescription = "Описание изображения",
+                    modifier = Modifier.size(90.dp)
+                        .clickable(onClick = {
+                            navHost.navigate("PersonalView")
+                        })
+                )
+
+                val userId = Constant.supabase.auth.currentUserOrNull()?.id
+                val userIdString = userId.toString()
+
+                LazyColumn(
+                    modifier = Modifier.fillMaxWidth(), // Заполняем ширину
+                    horizontalAlignment = Alignment.CenterHorizontally // Центрируем элементы внутри LazyColumn
+                ) {
+                    items(user) { US ->
+                        if (userIdString == US.user) {
+                            Text(
+                                US.login,
+                                fontFamily = kdamFontFamily,
+                                fontSize = 20.sp,
+                                color = Color.Black,
+                                textAlign = TextAlign.Center,
+                                modifier = Modifier.fillMaxWidth() // Заполняем ширину для центрирования
+                            )
+                        }
+                    }
+                }
+            }
         }
         LazyColumn {
             items(

+ 43 - 65
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/AboutGame.kt

@@ -1,12 +1,10 @@
 package com.example.oscellamobile.screens
 
-import android.graphics.Picture
 import android.util.Log
-import android.webkit.WebView
-import android.webkit.WebViewClient
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
@@ -21,7 +19,6 @@ import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.LazyRow
 import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.foundation.text.ClickableText
 import androidx.compose.material3.Card
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
@@ -36,16 +33,11 @@ import androidx.compose.ui.draw.clip
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.ModifierLocalBeyondBoundsLayout
 import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalUriHandler
 import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.buildAnnotatedString
 import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.text.style.TextDecoration
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import androidx.compose.ui.viewinterop.AndroidView
 import androidx.navigation.NavHostController
 import coil.compose.rememberAsyncImagePainter
 import com.example.oscellamobile.domain.utlis.Constant
@@ -61,21 +53,24 @@ import coil.compose.rememberImagePainter
 import coil.request.ImageRequest
 import coil.size.Size
 import com.example.oscellamobile.Link
+import com.example.oscellamobile.YouTube
 import com.example.oscellamobile.models.Game_Cloud
 import com.example.oscellamobile.models.Minimum_system_requirements
 import com.example.oscellamobile.models.Recommended_system_requirements
 import com.example.oscellamobile.models.Screnshot
+import com.example.oscellamobile.models.Users
 import com.example.oscellamobile.models.Сloud_gaming
-import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
+import io.github.jan.supabase.gotrue.auth
 
 @Composable
-fun AboutGame(navController: NavHostController, id: Int) {
+fun AboutGame(navHost: NavHostController, id: Int) {
     var games by remember { mutableStateOf<List<Game>>(listOf()) }
     var min by remember{mutableStateOf<List<Minimum_system_requirements>>(listOf())}
     var rec by remember{mutableStateOf<List<Recommended_system_requirements>>(listOf())}
     var cloudgame by remember{mutableStateOf<List<Game_Cloud>>(listOf())}
     var cloud by remember{mutableStateOf<List<Сloud_gaming>>(listOf())}
     var screen by remember { mutableStateOf<List<Screnshot>>(listOf())}
+    var user by remember { mutableStateOf<List<Users>>(listOf()) }
 
     LaunchedEffect(Unit) {
         withContext(Dispatchers.IO) {
@@ -86,7 +81,7 @@ fun AboutGame(navController: NavHostController, id: Int) {
                 cloudgame = Constant.supabase.from("Game_Cloud").select().decodeList<Game_Cloud>()
                 cloud = Constant.supabase.from("Сloud_gaming").select().decodeList<Сloud_gaming>()
                 screen = Constant.supabase.from("Screnshot").select().decodeList<Screnshot>()
-
+                user = Constant.supabase.from("Users").select().decodeList<Users>()
                 games.forEach { Game ->
                     Log.d("C", Game.name_game)
                 }
@@ -133,11 +128,40 @@ fun AboutGame(navController: NavHostController, id: Int) {
             Spacer(modifier = Modifier.width(13.dp))
             Text(text = "Osccela", fontSize = 40.sp, fontFamily = kdamFontFamily)
             Spacer(modifier = Modifier.width(145.dp))
-            Image(
-                painter = painterResource(id = R.drawable.personall),
-                contentDescription = "Описание изображения",
-                modifier = Modifier.size(90.dp)
-            )
+            Column(
+                verticalArrangement = Arrangement.Center,
+                horizontalAlignment = Alignment.CenterHorizontally
+            ) {
+                Image(
+                    painter = painterResource(id = R.drawable.personall),
+                    contentDescription = "Описание изображения",
+                    modifier = Modifier.size(90.dp)
+                        .clickable(onClick = {
+                            navHost.navigate("PersonalView")
+                        })
+                )
+
+                val userId = Constant.supabase.auth.currentUserOrNull()?.id
+                val userIdString = userId.toString()
+
+                LazyColumn(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalAlignment = Alignment.CenterHorizontally
+                ) {
+                    items(user) { US ->
+                        if (userIdString == US.user) {
+                            Text(
+                                US.login,
+                                fontFamily = kdamFontFamily,
+                                fontSize = 20.sp,
+                                color = Color.Black,
+                                textAlign = TextAlign.Center,
+                                modifier = Modifier.fillMaxWidth()
+                            )
+                        }
+                    }
+                }
+            }
         }
 
         LazyColumn {
@@ -436,8 +460,9 @@ fun GameItem(
                     verticalAlignment = Alignment.CenterVertically
                 )
                 {
+                    val viewModel = YouTube()
                     if (game.video != null) {
-                        VideoPlayerFromUrl(game.video)
+                        viewModel.VideoPlayerFromUrl(game.video)
                     }
                 }
             }
@@ -445,51 +470,4 @@ fun GameItem(
     }
 }
 
-fun extractVideoId(videoUrl: String): String? {
-    val regex = Regex("(?:https?://)?(?:www\\.)?(?:youtube\\.com/watch\\?v=|youtu\\.be/)([a-zA-Z0-9_-]{11})")
-    return regex.find(videoUrl)?.groups?.get(1)?.value
-}
-
-@Composable
-fun VideoPlayerFromUrl(videoUrl: String) {
-    val videoId = extractVideoId(videoUrl)
-
-    if (videoId != null) {
-        VideoPlayer(videoId)
-    } else {
-        Text("Неверная ссылка на видео")
-    }
-}
-
-@Composable
-fun VideoPlayer(videoId: String) {
-    AndroidView(
-        factory = { context ->
-            WebView(context).apply {
-                webViewClient = WebViewClient()
-                settings.javaScriptEnabled = true // Включаем JavaScript
-            }
-        },
-        update = { webView ->
-            val html = """
-  <html>
-    <body style="margin:0;padding:0;">
-        <div style="padding: 0 5px;">
-            <iframe 
-                width="100%" 
-                height="200" 
-                src="https://www.youtube.com/embed/$videoId" 
-                frameborder="0" 
-                allowfullscreen 
-                style="border-radius: 15px; overflow: hidden;">
-            </iframe>
-        </div>
-    </body>
-</html>
-            """.trimIndent()
-            webView.loadData(html, "text/html", "UTF-8")
-        },
-        modifier = Modifier.fillMaxWidth().height(200.dp)
-    )
-}
 

+ 38 - 30
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/CloudList.kt

@@ -1,13 +1,10 @@
 package com.example.oscellamobile.screens
 
 import android.util.Log
-import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
-import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
-import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -26,12 +23,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Card
-import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.Icon
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -43,45 +37,28 @@ import androidx.compose.ui.draw.shadow
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.RadialGradientShader
-import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.graphics.Shadow
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.font.Font
-import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.navigation.NavHostController
 import coil.compose.rememberAsyncImagePainter
 import com.example.oscellamobile.domain.utlis.Constant
-import com.example.oscellamobile.models.Game
 import com.google.accompanist.systemuicontroller.rememberSystemUiController
 import io.github.jan.supabase.postgrest.from
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.withContext
-import kotlin.math.cos
-import kotlin.math.sin
 import com.example.oscellamobile.R
-import com.example.oscellamobile.models.Company
 import coil.compose.AsyncImagePainter
-import coil.compose.rememberAsyncImagePainter
 import coil.request.ImageRequest
 import coil.size.Size
 import com.example.oscellamobile.models.Advantages_of_the_cloud
-import com.example.oscellamobile.models.Age_rating
-import com.example.oscellamobile.models.Basic_labels
 import com.example.oscellamobile.models.Cloud_advantage
 import com.example.oscellamobile.models.Сloud_gaming
-import com.example.oscellamobile.models.Genre
-import com.example.oscellamobile.models.Label
-import com.example.oscellamobile.models.Popular_games_of_the_company
-import io.github.jan.supabase.realtime.Column
-import org.intellij.lang.annotations.JdkConstants
+import com.example.oscellamobile.models.Users
+import io.github.jan.supabase.gotrue.auth
 
 
 @Composable
@@ -90,6 +67,7 @@ fun CloudList(navHost: NavHostController) {
     var cloud by remember { mutableStateOf<List<Сloud_gaming>>(listOf()) }
     var advantage by remember { mutableStateOf<List<Cloud_advantage>>(listOf()) }
     var cloudadvantage by remember { mutableStateOf<List<Advantages_of_the_cloud>>(listOf()) }
+    var user by remember {mutableStateOf<List<Users>>(listOf())}
 
     LaunchedEffect(Unit) {
         withContext(Dispatchers.IO) {
@@ -97,6 +75,7 @@ fun CloudList(navHost: NavHostController) {
                 cloud = Constant.supabase.from("Сloud_gaming").select().decodeList<Сloud_gaming>()
                 advantage = Constant.supabase.from("Cloud_advantage").select().decodeList<Cloud_advantage>()
                 cloudadvantage = Constant.supabase.from("Advantages_of_the_cloud").select().decodeList<Advantages_of_the_cloud>()
+                user = Constant.supabase.from("Users").select().decodeList<Users>()
                 cloud.forEach { Cloud ->
                     Log.d("C", Cloud.cloud_name)
                 }
@@ -141,11 +120,40 @@ fun CloudList(navHost: NavHostController) {
             Spacer(modifier = Modifier.width(13.dp))
             Text(text = "Osccela", fontSize = 40.sp, fontFamily = kdamFontFamily)
             Spacer(modifier = Modifier.width(145.dp))
-            Image(
-                painter = painterResource(id = R.drawable.personall),
-                contentDescription = "Описание изображения",
-                modifier = Modifier.size(90.dp)
-            )
+            Column(
+                verticalArrangement = Arrangement.Center,
+                horizontalAlignment = Alignment.CenterHorizontally
+            ) {
+                Image(
+                    painter = painterResource(id = R.drawable.personall),
+                    contentDescription = "Описание изображения",
+                    modifier = Modifier.size(90.dp)
+                        .clickable(onClick = {
+                            navHost.navigate("PersonalView")
+                        })
+                )
+
+                val userId = Constant.supabase.auth.currentUserOrNull()?.id
+                val userIdString = userId.toString()
+
+                LazyColumn(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalAlignment = Alignment.CenterHorizontally
+                ) {
+                    items(user) { US ->
+                        if (userIdString == US.user) {
+                            Text(
+                                US.login,
+                                fontFamily = kdamFontFamily,
+                                fontSize = 20.sp,
+                                color = Color.Black,
+                                textAlign = TextAlign.Center,
+                                modifier = Modifier.fillMaxWidth()
+                            )
+                        }
+                    }
+                }
+            }
         }
         Row(
             modifier = Modifier

+ 38 - 28
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/CompanyList.kt

@@ -1,13 +1,10 @@
 package com.example.oscellamobile.screens
 
 import android.util.Log
-import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
-import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
-import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -26,12 +23,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Card
-import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.Icon
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -43,42 +37,27 @@ import androidx.compose.ui.draw.shadow
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.RadialGradientShader
-import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.graphics.Shadow
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.drawscope.DrawScope
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.font.Font
-import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.navigation.NavHostController
 import coil.compose.rememberAsyncImagePainter
 import com.example.oscellamobile.domain.utlis.Constant
-import com.example.oscellamobile.models.Game
 import com.google.accompanist.systemuicontroller.rememberSystemUiController
 import io.github.jan.supabase.postgrest.from
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.withContext
-import kotlin.math.cos
-import kotlin.math.sin
 import com.example.oscellamobile.R
 import com.example.oscellamobile.models.Company
 import coil.compose.AsyncImagePainter
-import coil.compose.rememberAsyncImagePainter
 import coil.request.ImageRequest
 import coil.size.Size
-import com.example.oscellamobile.models.Age_rating
-import com.example.oscellamobile.models.Basic_labels
-import com.example.oscellamobile.models.Genre
-import com.example.oscellamobile.models.Label
 import com.example.oscellamobile.models.Popular_games_of_the_company
-import io.github.jan.supabase.realtime.Column
-import org.intellij.lang.annotations.JdkConstants
+import com.example.oscellamobile.models.Users
+import io.github.jan.supabase.gotrue.auth
 
 
 @Composable
@@ -86,12 +65,14 @@ fun CompanyList(navHost: NavHostController) {
 
     var сompany by remember { mutableStateOf<List<Company>>(listOf()) }
     var games by remember { mutableStateOf<List<Popular_games_of_the_company>>(listOf()) }
+    var user by remember { mutableStateOf<List<Users>>(listOf()) }
 
     LaunchedEffect(Unit) {
         withContext(Dispatchers.IO) {
             try {
                 сompany = Constant.supabase.from("Company").select().decodeList<Company>()
                 games = Constant.supabase.from("Popular_games_of_the_company").select().decodeList<Popular_games_of_the_company>()
+                user = Constant.supabase.from("Users").select().decodeList<Users>()
                 сompany.forEach { Comp ->
                     Log.d("C", Comp.name_company)
                 }
@@ -136,11 +117,40 @@ fun CompanyList(navHost: NavHostController) {
             Spacer(modifier = Modifier.width(13.dp))
             Text(text = "Osccela", fontSize = 40.sp, fontFamily = kdamFontFamily)
             Spacer(modifier = Modifier.width(145.dp))
-            Image(
-                painter = painterResource(id = R.drawable.personall),
-                contentDescription = "Описание изображения",
-                modifier = Modifier.size(90.dp)
-            )
+            Column(
+                verticalArrangement = Arrangement.Center,
+                horizontalAlignment = Alignment.CenterHorizontally
+            ) {
+                Image(
+                    painter = painterResource(id = R.drawable.personall),
+                    contentDescription = "Описание изображения",
+                    modifier = Modifier.size(90.dp)
+                        .clickable(onClick = {
+                            navHost.navigate("PersonalView")
+                        })
+                )
+
+                val userId = Constant.supabase.auth.currentUserOrNull()?.id
+                val userIdString = userId.toString()
+
+                LazyColumn(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalAlignment = Alignment.CenterHorizontally
+                ) {
+                    items(user) { US ->
+                        if (userIdString == US.user) {
+                            Text(
+                                US.login,
+                                fontFamily = kdamFontFamily,
+                                fontSize = 20.sp,
+                                color = Color.Black,
+                                textAlign = TextAlign.Center,
+                                modifier = Modifier.fillMaxWidth()
+                            )
+                        }
+                    }
+                }
+            }
         }
         Row(
             modifier = Modifier

+ 139 - 81
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/MainWindow.kt

@@ -22,9 +22,12 @@ import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.DropdownMenu
+import androidx.compose.material.DropdownMenuItem
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Card
+import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
@@ -47,7 +50,6 @@ import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import androidx.navigation.NavController
 import androidx.navigation.NavHostController
 import coil.compose.rememberAsyncImagePainter
 import com.example.oscellamobile.domain.utlis.Constant
@@ -64,7 +66,7 @@ import com.example.oscellamobile.models.Company
 import coil.compose.AsyncImagePainter
 import coil.request.ImageRequest
 import coil.size.Size
-import com.example.oscellamobile.domain.utlis.Constant.supabase
+import com.example.oscellamobile.Favourites
 import com.example.oscellamobile.models.Age_rating
 import com.example.oscellamobile.models.Basic_labels
 import com.example.oscellamobile.models.Favorite
@@ -90,6 +92,8 @@ val gradientButton = Brush.linearGradient(
     end = Offset(200f, 200f)
 )
 
+
+
 val gradientBox = Brush.linearGradient(
     colors = listOf(
         Color(0xFFFDFFFC),
@@ -166,31 +170,35 @@ fun MainWindow(navHost: NavHostController) {
             Text(text = "Osccela", fontSize = 40.sp, fontFamily = kdamFontFamily)
             Spacer(modifier = Modifier.width(145.dp))
             Column(
-                verticalArrangement = Arrangement.Center
+                verticalArrangement = Arrangement.Center,
+                horizontalAlignment = Alignment.CenterHorizontally
             ) {
                 Image(
                     painter = painterResource(id = R.drawable.personall),
                     contentDescription = "Описание изображения",
                     modifier = Modifier.size(90.dp)
+                        .clickable(onClick = {
+                            navHost.navigate("PersonalView")
+                        })
                 )
+
                 val userId = Constant.supabase.auth.currentUserOrNull()?.id
                 val userIdString = userId.toString()
-                LazyColumn{
+
+                LazyColumn(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalAlignment = Alignment.CenterHorizontally
+                ) {
                     items(user) { US ->
-                        if(userIdString == US.user){
-                            Row(
-                                horizontalArrangement = Arrangement.Center,
-                                modifier = Modifier.fillMaxWidth().
-                                padding(0.dp,0.dp,7.dp,0.dp)
-                            ) {
-                                Text(
-                                    US.login,
-                                    fontFamily = kdamFontFamily,
-                                    fontSize = 20.sp,
-                                    color = Color.Black,
-                                    textAlign = TextAlign.Center
-                                )
-                            }
+                        if (userIdString == US.user) {
+                            Text(
+                                US.login,
+                                fontFamily = kdamFontFamily,
+                                fontSize = 20.sp,
+                                color = Color.Black,
+                                textAlign = TextAlign.Center,
+                                modifier = Modifier.fillMaxWidth()
+                            )
                         }
                     }
                 }
@@ -279,10 +287,15 @@ fun MainWindow(navHost: NavHostController) {
             }
             Spacer(Modifier.width(10.dp))
         }
-        Spacer(Modifier.height(100.dp))
+        var list = ComboBoxExample(genres, сompany, games)
+        if(list.isEmpty())
+        {
+            list = games
+        }
+        Spacer(Modifier.height(50.dp))
         LazyColumn {
             items(
-                games,
+                list,
                 key = { Game -> Game.id },
             ) { Game ->
                 GameItem(
@@ -325,10 +338,8 @@ fun MainWindow(navHost: NavHostController) {
     ) {
         Row {
             Spacer(Modifier.width(10.dp))
+            var viewModel = Favourites()
             Column {
-                val userId = Constant.supabase.auth.currentUserOrNull()?.id
-                val userIdString = userId.toString()
-
                 val companyId = game.company
                 val companyy = company.find { it.id == companyId }
                 if (companyy != null) {
@@ -402,6 +413,7 @@ fun MainWindow(navHost: NavHostController) {
                             )
                     )
                     {
+
                         Text(
                             text = if (game.favourites == null) {
                                 "Избранное: 0"
@@ -423,21 +435,11 @@ fun MainWindow(navHost: NavHostController) {
                     val userr = user.find { it.user == userIdString }
 
                     var isOrange by remember { mutableStateOf(false) }
-                    LaunchedEffect(Unit) {
-                        if (userr != null) {
-                            val result = fav.find { it.id_game == game.id && it.id_user == userr.id }
-                            if (result != null) {
-                                Log.d("MyApp", "Found favorite: ${result.id_game}, ${result.id_user}")
-                                isOrange = true
 
-                            } else {
-                                Log.d("MyApp", "No favorite found for game ID: ${game.id} and user ID: ${userr.id}")
-                                isOrange = false
-                            }
-                        } else {
-                            Log.d("MyApp", "User  not found for user ID: $userIdString")
-                        }
+                    if (userr != null) {
+                        isOrange = fav.any { it.id_game == game.id && it.id_user == userr.id }
                     }
+
                     val buttonColor = if (isOrange) Color(0xFFFF9F1C) else Color.Gray
 
                     Canvas(
@@ -446,20 +448,15 @@ fun MainWindow(navHost: NavHostController) {
                             .clickable(onClick = {
                                 isOrange = !isOrange
                                 if (isOrange) {
-                                    if(userr != null) {
+                                    if (userr != null) {
                                         CoroutineScope(Dispatchers.Main).launch {
-                                            addToFavorites(game.id, userr.id, navHost, favv)
+                                            viewModel.addToFavorites(game.id, userr.id, navHost, favv, "MainWindow")
                                         }
                                     }
                                 } else {
                                     if (userr != null) {
                                         CoroutineScope(Dispatchers.Main).launch {
-                                            removeFromFavorites(
-                                                game.id,
-                                                userr.id,
-                                                navHost,
-                                                favv
-                                            )
+                                            viewModel.removeFromFavorites(game.id, userr.id, navHost, favv, "MainWindow")
                                         }
                                     }
                                 }
@@ -598,53 +595,114 @@ fun DrawScope.drawStar(center: Offset, radius: Float, color: Color) {
     drawPath(path, color)
 }
 
-suspend fun addToFavorites(id_game: Int, id_user: Int, navController: NavController, fav: Int?) {
-    val newFav = Favorite(
-        id_game = id_game,
-        id_user = id_user
-    )
+fun FilterGenre(games: List<Game>, genre: Int): List<Game> {
+    return games.filter { it.genre == genre }
+}
 
-    val newFavouritesCount = fav?.plus(1) ?: 1
+fun FilterCompany(games: List<Game>, company: Int): List<Game> {
+    return games.filter { it.company == company }
+}
 
-        val response = supabase.from("Game").update(
-            {
-                Game::favourites setTo newFavouritesCount
-                set("favourites", newFavouritesCount)
-            }
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun ComboBoxExample(genres: List<Genre>, companies: List<Company>, games: List<Game>): List<Game> {
+    var expanded by remember { mutableStateOf(false) }
+    var filteredGames by remember { mutableStateOf(games) }
+    var selectedGenre by remember { mutableStateOf<Genre?>(null) }
+    var selectedCompany by remember { mutableStateOf<Company?>(null) }
+    var filterByGenre by remember { mutableStateOf(true) }
+
+    Box {
+        Button(
+            onClick = { expanded = true },
+            modifier = Modifier
+                .shadow(100.dp)
+                .background(brush = gradientButton, shape = RoundedCornerShape(20.dp)),
+            colors = ButtonDefaults.buttonColors(
+                containerColor = Color.Transparent
+            )
         ) {
-            filter {
-                Game::id eq id_game
-            }
+            Text(
+                text = when {
+                    filteredGames.isEmpty() -> "Нет подходящих игр"
+                    selectedGenre != null -> "Жанр: ${selectedGenre!!.genre_name}"
+                    selectedCompany != null -> "Компания: ${selectedCompany!!.name_company}"
+                    else -> "Фильтр"
+                },
+                modifier = Modifier.padding(16.dp),
+                color = Color.White,
+                fontFamily = playfairdisplay,
+                fontSize = 20.sp
+            )
         }
 
-    withContext(Dispatchers.IO) {
-        supabase.from("Favorite").insert(newFav)
-    }
-    navController.navigate("MainWindow")
-}
-
-suspend fun removeFromFavorites(id_game: Int, id_user: Int, navController: NavController, fav: Int?) {
-    withContext(Dispatchers.IO) {
+        DropdownMenu(
+            expanded = expanded,
+            onDismissRequest = { expanded = false }
+        ) {
+            DropdownMenuItem(
+                onClick = {
+                    filteredGames = games
+                    selectedGenre = null
+                    selectedCompany = null
+                    expanded = false
+                }
+            ) {
+                Text("Сбросить фильтр")
+            }
 
-        val newFavouritesCount = fav?.minus(1) ?: 1
+            DropdownMenuItem(
+                onClick = {
+                    filterByGenre = true
+                    expanded = false
+                }
+            ) {
+                Text("Фильтровать по жанру")
+            }
 
-        supabase.from("Game").update(
-            {
-                Game::favourites setTo newFavouritesCount
-                set("favourites", newFavouritesCount)
+            DropdownMenuItem(
+                onClick = {
+                    filterByGenre = false
+                    expanded = false
+                }
+            ) {
+                Text("Фильтровать по компании")
             }
-        ) {
-            filter {
-                Game::id eq id_game
+
+            if (filterByGenre) {
+                genres.forEach { genre ->
+                    DropdownMenuItem(
+                        onClick = {
+                            filteredGames = FilterGenre(games, genre.id)
+                            selectedGenre = genre
+                            selectedCompany = null
+                            expanded = false
+                        }
+                    ) {
+                        Text(genre.genre_name)
+                    }
+                }
+            } else {
+                companies.forEach { company ->
+                    DropdownMenuItem(
+                        onClick = {
+                            filteredGames = FilterCompany(games, company.id)
+                            selectedCompany = company
+                            selectedGenre = null
+                            expanded = false
+                        }
+                    ) {
+                        Text(company.name_company)
+                    }
+                }
             }
-        }
 
-        val response = supabase.from("Favorite").delete {
-            filter {
-                (Favorite::id_game eq id_game)
-                (Favorite::id_user eq id_user)
+            if (filteredGames.isEmpty()) {
+                DropdownMenuItem(onClick = {}) {
+                    Text("Нет подходящих игр", color = Color.Red)
+                }
             }
         }
     }
-    navController.navigate("MainWindow")
-}
+    return filteredGames
+}

+ 311 - 0
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/PersonalView.kt

@@ -0,0 +1,311 @@
+package com.example.oscellamobile.screens
+
+import android.util.Log
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.Image
+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.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Card
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.navigation.NavController
+import androidx.navigation.NavHostController
+import coil.compose.rememberAsyncImagePainter
+import com.example.oscellamobile.domain.utlis.Constant
+import com.example.oscellamobile.models.Game
+import io.github.jan.supabase.postgrest.from
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import com.example.oscellamobile.R
+import coil.compose.AsyncImagePainter
+import coil.request.ImageRequest
+import coil.size.Size
+import com.example.oscellamobile.Favourites
+import com.example.oscellamobile.models.Favorite
+import com.example.oscellamobile.models.Users
+import io.github.jan.supabase.gotrue.auth
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+@Composable
+fun PersonalView (navHost: NavHostController) {
+    var user by remember{mutableStateOf<List<Users>>(listOf())}
+    var game by remember { mutableStateOf<List<Game>>(listOf()) }
+    var fav by remember { mutableStateOf<List<Favorite>>(listOf()) }
+
+
+    val gradientButton1 = Brush.linearGradient(
+        colors = listOf(
+            Color(0xFF2EC4B6),
+            Color(0xFFE71D36)
+        ),
+        start = Offset(30f, 30f),
+        end = Offset(200f, 200f)
+    )
+
+    LaunchedEffect(Unit) {
+        withContext(Dispatchers.IO) {
+            try {
+                user = Constant.supabase.from("Users").select().decodeList<Users>()
+                game = Constant.supabase.from("Game").select().decodeList<Game>()
+                fav = Constant.supabase.from("Favorite").select().decodeList<Favorite>()
+                user.forEach { User ->
+                    Log.d("C", User.user)
+                }
+            } catch (e: Exception) {
+                Log.e("C", "Ошибка загрузки данных", e)
+            }
+        }
+    }
+
+    Canvas(
+        modifier = Modifier
+            .fillMaxWidth()
+            .fillMaxHeight()
+    ) {
+        val gradient = Brush.linearGradient(
+            colors = listOf(
+                Color(0xFFFF9F1C),
+                Color(0xFFE71D36)
+            ),
+            start = Offset(size.width, 1200f),
+            end = Offset(150f, size.height)
+        )
+
+        drawRect(brush = gradient)
+    }
+
+    Column(
+        modifier = Modifier
+            .fillMaxWidth()
+            .fillMaxHeight()
+    ) {
+        Spacer(modifier = Modifier.height(10.dp))
+        Row {
+            Spacer(modifier = Modifier.width(13.dp))
+            Text(text = "Osccela", fontSize = 40.sp, fontFamily = kdamFontFamily)
+            Spacer(modifier = Modifier.width(145.dp))
+        }
+            Column(
+                verticalArrangement = Arrangement.Center,
+                horizontalAlignment = Alignment.CenterHorizontally // Центрируем по горизонтали
+            ) {
+                Image(
+                    painter = painterResource(id = R.drawable.personall),
+                    contentDescription = "Описание изображения",
+                    modifier = Modifier.size(150.dp)
+                )
+
+                val userId = Constant.supabase.auth.currentUserOrNull()?.id
+                val userIdString = userId.toString()
+                user = user.filter { it.user ==  userIdString}
+                var UserId = user.find { it.user == userIdString }
+                fav = fav.filter { it.id_user == UserId?.id }
+                LazyColumn(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalAlignment = Alignment.CenterHorizontally
+                ) {
+                    items(user) { US ->
+                            Text(
+                                US.login,
+                                fontFamily = kdamFontFamily,
+                                fontSize = 20.sp,
+                                color = Color.Black,
+                                textAlign = TextAlign.Center,
+                                modifier = Modifier.fillMaxWidth()
+                            )
+                        }
+                }
+                Button(onClick = {
+                    navHost.navigate("Auth") {
+                        popUpTo("Auth") { inclusive = true }
+                    }
+                },
+                    modifier = Modifier
+                        .background(
+                            brush = gradientButton1, shape = RoundedCornerShape(20.dp)
+                        )
+                        .width(200.dp),
+                    colors = ButtonDefaults.buttonColors(
+                        containerColor = Color.Transparent
+                    )) {
+                    Text( text = "Выйти",
+                        textAlign = TextAlign.Center,
+                        fontFamily = kdamFontFamily,
+                        fontSize = 24.sp,
+                        color = Color(0xFFFDFFFC))
+                }
+                Spacer(modifier = Modifier.height(50.dp))
+                Box(
+                    modifier = Modifier.background(color = Color.White, shape = RoundedCornerShape(5.dp))
+                        .fillMaxWidth()
+                ){
+                    Text(
+                        text = " Избранное:",
+                        fontSize = 25.sp,
+                        fontFamily = ibmplexmono,
+                        color = Color(0xFFFF9F1C),
+                        textAlign = TextAlign.Left
+                    )
+                }
+                LazyRow(
+                    modifier = Modifier.background(color = Color.White)
+                ) {
+                    items(
+                        game,
+                        key = { Game -> Game.id }
+                    ) { Game ->
+                        FavList(Game, fav, user, navHost)
+                    }
+                }
+            }
+    }
+}
+
+@Composable
+fun FavList(
+    game: Game,
+    fav: List<Favorite>,
+    user: List<Users>,
+    navHost: NavController
+){
+    Card(
+        modifier = Modifier
+            .fillMaxWidth()
+            .height(260.dp)
+            .padding(10.dp, 0.dp, 10.dp, 0.dp)
+            .background(color = Color(0xFFFDFFFC), shape = RoundedCornerShape(20.dp))
+    ) {
+        Box(
+            modifier = Modifier.fillMaxSize()
+                .background(color = Color.White),
+            contentAlignment = Alignment.Center,
+        ) {
+            val imageState = rememberAsyncImagePainter(
+                model = ImageRequest.Builder(LocalContext.current).data(game.picture)
+                    .size(Size.ORIGINAL).build()
+            ).state
+            val GameId = game.id
+            val favGame = fav.find { it.id_game == GameId }
+
+            if (favGame?.id_game == game.id) {
+                Column(
+                    horizontalAlignment = Alignment.CenterHorizontally,
+                    verticalArrangement = Arrangement.Center
+                ) {
+                    Row {
+                        Text(
+                            game.name_game,
+                            fontSize = 20.sp,
+                            fontFamily = kdamFontFamily,
+                            color = Color(0xFF7F807E),
+                            textAlign = TextAlign.Center
+                        )
+                        val userId = Constant.supabase.auth.currentUserOrNull()?.id
+                        val favv = game.favourites
+                        val userIdString = userId.toString()
+                        val userr = user.find { it.user == userIdString }
+                        val viewModel = Favourites()
+                        var isOrange by remember { mutableStateOf(true) }
+
+
+                        val size = 50.dp
+                        val buttonColor = if (isOrange) Color(0xFFFF9F1C) else Color.Gray
+
+                        Spacer(modifier = Modifier.width(30.dp))
+
+                        Canvas(
+                            modifier = Modifier
+                                .size(30.dp)
+                                .clickable(onClick = {
+                                    isOrange = !isOrange
+                                    if (isOrange) {
+                                        if (userr != null) {
+                                            CoroutineScope(Dispatchers.Main).launch {
+                                                viewModel.addToFavorites(game.id, userr.id, navHost, favv, "PersonalView")
+                                            }
+                                        }
+                                    } else {
+                                        if (userr != null) {
+                                            CoroutineScope(Dispatchers.Main).launch {
+                                                viewModel.removeFromFavorites(game.id, userr.id, navHost, favv, "PersonalView")
+                                            }
+                                        }
+                                    }
+                                })
+                        ) {
+                            drawStar(
+                                center = center,
+                                radius = size.toPx() / 2,
+                                color = buttonColor
+                            )
+                        }
+                    }
+                    if (imageState is AsyncImagePainter.State.Success) {
+                        Image(
+                            painter = imageState.painter,
+                            contentDescription = "Описание изображения",
+                            modifier = Modifier
+                                .width(280.dp)
+                                .clip(RoundedCornerShape(20.dp))
+                        )
+                    }
+                    Button(
+                        onClick = { navHost.navigate("AboutGame/${game.id}") },
+                        modifier = Modifier
+                            .background(
+                                color = Color(0xFFE71D36),
+                                shape = RoundedCornerShape(20.dp)
+                            ),
+                        colors = ButtonDefaults.buttonColors(
+                            containerColor = Color.Transparent
+                        )
+                    ) {
+                        Text(
+                            text = "Подробности",
+                            textAlign = TextAlign.Center,
+                            fontFamily = playfairdisplay,
+                            fontSize = 16.sp,
+                            color = Color(0xFFFDFFFC)
+                        )
+                    }
+                }
+            }
+        }
+    }
+}
+

+ 14 - 27
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/Registration.kt

@@ -32,14 +32,19 @@ import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.navigation.NavHostController
+import com.example.oscellamobile.Auth
 import org.w3c.dom.Text
 import com.example.oscellamobile.R
+import kotlin.math.log
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun Registration(navController: NavHostController) {
+    val viewModel = Auth()
     val kdamFontFamily = FontFamily(Font(R.font.kdam))
-    var text = ""
+    val email = remember { mutableStateOf("") }
+    val password = remember { mutableStateOf("") }
+    val login = remember { mutableStateOf("") }
 
 
     val gradientButton = Brush.linearGradient(
@@ -91,8 +96,8 @@ fun Registration(navController: NavHostController) {
         )
         Spacer(modifier = Modifier.height(29.dp))
         TextField(
-            value = text,
-            onValueChange = { text = it },
+            value = email.value,
+            onValueChange = { newText -> email.value = newText },
             placeholder = { Text("Email", fontSize = 24.sp, fontFamily = kdamFontFamily) },
             shape = RoundedCornerShape(20.dp),
             colors = TextFieldDefaults.textFieldColors(
@@ -105,8 +110,8 @@ fun Registration(navController: NavHostController) {
         )
         Spacer(modifier = Modifier.height(20.dp))
         TextField(
-            value = text,
-            onValueChange = { text = it },
+            value = login.value,
+            onValueChange = { newText -> login.value = newText },
             placeholder = { Text("Login", fontSize = 24.sp, fontFamily = kdamFontFamily) },
             shape = RoundedCornerShape(20.dp),
             colors = TextFieldDefaults.textFieldColors(
@@ -119,8 +124,8 @@ fun Registration(navController: NavHostController) {
         )
         Spacer(modifier = Modifier.height(20.dp))
         TextField(
-            value = text,
-            onValueChange = { text = it },
+            value = password.value,
+            onValueChange = { newText -> password.value = newText },
             placeholder = { Text("Password", fontSize = 24.sp, fontFamily = kdamFontFamily) },
             shape = RoundedCornerShape(20.dp),
             colors = TextFieldDefaults.textFieldColors(
@@ -132,26 +137,8 @@ fun Registration(navController: NavHostController) {
                 .height(66.dp)
         )
         Spacer(modifier = Modifier.height(20.dp))
-        TextField(
-            value = text,
-            onValueChange = {
-                if (it.length <= 6 && it.all { char -> char.isDigit() }) {
-                    text = it
-                }
-            },
-            placeholder = { Text("Enter code (6 digits)", fontSize = 24.sp, fontFamily = kdamFontFamily) },
-            shape = RoundedCornerShape(20.dp),
-            colors = TextFieldDefaults.textFieldColors(
-                focusedIndicatorColor = Color.Transparent,
-                unfocusedIndicatorColor = Color.Transparent
-            ),
-            modifier = Modifier
-                .width(330.dp)
-                .height(66.dp)
-        )
-        Spacer(modifier = Modifier.height(20.dp))
         Button(
-            onClick = {navController.navigate("RegistrationWithEmail")},
+            onClick = {viewModel.onSignUpEmail(email.value, password.value, login.value, navController)},
             modifier = Modifier
                 .shadow(100.dp)
                 .width(180.dp)
@@ -162,7 +149,7 @@ fun Registration(navController: NavHostController) {
             )
 
         ) {
-             Text("Send code", color = Color.White, fontFamily = kdamFontFamily, fontSize = 24.sp)
+             Text("Registration", color = Color.White, fontFamily = kdamFontFamily, fontSize = 24.sp)
         }
     }
 }

+ 0 - 121
OscellaMobile/app/src/main/java/com/example/oscellamobile/screens/RegistrationWithEmail.kt

@@ -1,121 +0,0 @@
-package com.example.oscellamobile.screens
-
-import android.icu.text.ListFormatter.Width
-import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.Button
-import androidx.compose.material3.ButtonDefaults
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.Text
-import androidx.compose.material3.TextField
-import androidx.compose.material3.TextFieldDefaults
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.shadow
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.graphics.Brush
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.text.font.Font
-import androidx.compose.ui.text.font.FontFamily
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import androidx.navigation.NavHostController
-import org.w3c.dom.Text
-import com.example.oscellamobile.R
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-fun RegistrationWithEmail(navController: NavHostController) {
-    val kdamFontFamily = FontFamily(Font(R.font.kdam))
-    var text = ""
-
-    val gradientButton = Brush.linearGradient(
-        colors = listOf(
-            Color(0xFF2EC4B6),
-            Color(0xFFFF9F1C)
-        ),
-        start = Offset(30f, 30f),
-        end = Offset(200f, 200f)
-    )
-
-    val gradientButton1 = Brush.linearGradient(
-        colors = listOf(
-            Color(0xFF2EC4B6),
-            Color(0xFFFF9F1C)
-        ),
-        start = Offset(0f, 0f),
-        end = Offset(150f, 150f)
-    )
-
-    Canvas(
-        modifier = Modifier
-            .fillMaxWidth()
-            .fillMaxHeight()
-    ) {
-        val gradient = Brush.linearGradient(
-            colors = listOf(
-                Color(0xFF2EC4B6),
-                Color(0xFFFF9F1C),
-                Color(0xFFE71D36)
-            ),
-            start = Offset(size.width, 1200f),
-            end = Offset(150f, size.height)
-        )
-
-        drawRect(brush = gradient)
-    }
-
-    Column(
-        modifier = Modifier
-            .fillMaxWidth()
-            .fillMaxHeight(),
-        horizontalAlignment = Alignment.CenterHorizontally
-    ) {
-        Spacer(modifier = Modifier.height(180.dp))
-        Text(
-            text = "Oscella", fontSize = 40.sp,
-           fontFamily = kdamFontFamily
-        )
-        Spacer(modifier = Modifier.height(60.dp))
-        TextField(
-            value = text,
-            onValueChange = { text = it },
-            placeholder = { Text("Enter Code", fontSize = 24.sp, fontFamily = kdamFontFamily) },
-            shape = RoundedCornerShape(20.dp),
-            colors = TextFieldDefaults.textFieldColors(
-                focusedIndicatorColor = Color.Transparent,
-                unfocusedIndicatorColor = Color.Transparent
-            ),
-            modifier = Modifier
-                .width(330.dp)
-                .height(66.dp)
-        )
-        Spacer(modifier = Modifier.height(20.dp))
-        Button(
-            onClick = {},
-            modifier = Modifier
-                .shadow(100.dp)
-                .width(180.dp)
-                .height(50.dp)
-                .background(brush = gradientButton, shape = RoundedCornerShape(20.dp)),
-            colors = ButtonDefaults.buttonColors(
-                containerColor = Color.Transparent
-            )
-
-        ) {
-           Text("SignUp", color = Color.White, fontFamily = kdamFontFamily, fontSize = 24.sp)
-        }
-    }
-}