|
@@ -1,37 +1,31 @@
|
|
|
package com.example.oscellamobile.screens
|
|
|
|
|
|
+import android.graphics.Picture
|
|
|
import android.util.Log
|
|
|
-import androidx.compose.foundation.BorderStroke
|
|
|
+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.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
|
|
|
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.foundation.text.ClickableText
|
|
|
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
|
|
@@ -39,22 +33,19 @@ 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.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.font.Font
|
|
|
-import androidx.compose.ui.text.font.FontFamily
|
|
|
+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
|
|
@@ -64,28 +55,37 @@ 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.compose.rememberImagePainter
|
|
|
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 org.intellij.lang.annotations.JdkConstants
|
|
|
+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.Сloud_gaming
|
|
|
+import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
|
|
|
|
|
|
@Composable
|
|
|
fun AboutGame(navController: 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())}
|
|
|
|
|
|
LaunchedEffect(Unit) {
|
|
|
withContext(Dispatchers.IO) {
|
|
|
try {
|
|
|
games = Constant.supabase.from("Game").select().decodeList<Game>()
|
|
|
+ min = Constant.supabase.from("Minimum_system_requirements").select().decodeList<Minimum_system_requirements>()
|
|
|
+ rec = Constant.supabase.from("Recommended_system_requirements").select().decodeList<Recommended_system_requirements>()
|
|
|
+ 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>()
|
|
|
+
|
|
|
games.forEach { Game ->
|
|
|
Log.d("C", Game.name_game)
|
|
|
}
|
|
@@ -95,22 +95,422 @@ fun AboutGame(navController: NavHostController, id: Int) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- val filteredGames = games.filter { it.id == id}
|
|
|
+ val filteredGames = games.filter { it.id == id }
|
|
|
+
|
|
|
+ val systemUiController = rememberSystemUiController()
|
|
|
+
|
|
|
+ LaunchedEffect(Unit) {
|
|
|
+ systemUiController.isStatusBarVisible = false
|
|
|
+ delay(5000)
|
|
|
+ systemUiController.isStatusBarVisible = false
|
|
|
+ }
|
|
|
+
|
|
|
+ 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)
|
|
|
+ )
|
|
|
|
|
|
- LazyColumn {
|
|
|
- items(
|
|
|
- filteredGames,
|
|
|
- key = { game -> game.id }
|
|
|
- ) { game ->
|
|
|
- GameItem(game)
|
|
|
+ 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))
|
|
|
+ Image(
|
|
|
+ painter = painterResource(id = R.drawable.personall),
|
|
|
+ contentDescription = "Описание изображения",
|
|
|
+ modifier = Modifier.size(90.dp)
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ LazyColumn {
|
|
|
+ items(
|
|
|
+ filteredGames,
|
|
|
+ key = { game -> game.id }
|
|
|
+ ) { game ->
|
|
|
+ GameItem(
|
|
|
+ game = game,
|
|
|
+ min = min,
|
|
|
+ rec = rec,
|
|
|
+ gamecloud = cloudgame,
|
|
|
+ cloud = cloud,
|
|
|
+ screen = screen
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+@Composable
|
|
|
+fun GameItem(
|
|
|
+ game: Game,
|
|
|
+ min: List<Minimum_system_requirements>,
|
|
|
+ rec: List<Recommended_system_requirements>,
|
|
|
+ gamecloud: List<Game_Cloud>,
|
|
|
+ cloud: List<Сloud_gaming>,
|
|
|
+ screen: List<Screnshot>
|
|
|
+) {
|
|
|
+ val imageState = rememberAsyncImagePainter(
|
|
|
+ model = ImageRequest.Builder(LocalContext.current).data(game.picture)
|
|
|
+ .size(Size.ORIGINAL).build()
|
|
|
+ ).state
|
|
|
+
|
|
|
+ Card(
|
|
|
+ Modifier.width(400.dp)
|
|
|
+ .padding(10.dp, 10.dp, 10.dp, 10.dp)
|
|
|
+ .background(color = Color(0xFFFDFFFC), shape = RoundedCornerShape(20.dp)),
|
|
|
+ )
|
|
|
+ {
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.fillMaxWidth()
|
|
|
+ ) {
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.fillMaxWidth(),
|
|
|
+ horizontalAlignment = Alignment.CenterHorizontally
|
|
|
+ ) {
|
|
|
+ Text(
|
|
|
+ game.name_game,
|
|
|
+ textAlign = TextAlign.Center,
|
|
|
+ fontFamily = kdamFontFamily,
|
|
|
+ fontSize = 30.sp,
|
|
|
+ color = Color(0xFF7F807E)
|
|
|
+ )
|
|
|
+ Spacer(modifier = Modifier.height(5.dp)) // Space between Text and Image
|
|
|
+ if (imageState is AsyncImagePainter.State.Success) {
|
|
|
+ Image(
|
|
|
+ painter = imageState.painter,
|
|
|
+ contentDescription = "Описание изображения",
|
|
|
+ modifier = Modifier
|
|
|
+ .width(380.dp)
|
|
|
+ .clip(RoundedCornerShape(20.dp)),
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Text(
|
|
|
+ text = "Системные требования к игре:",
|
|
|
+ textAlign = TextAlign.Left,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 20.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ )
|
|
|
+ var GameID = game.id
|
|
|
+ val cloudingame = gamecloud.filter { it.game == GameID }
|
|
|
+ val clouddd = cloudingame.map { it.cloud }
|
|
|
+ val clouds = clouddd.mapNotNull { id ->
|
|
|
+ cloud.find { it.id == id }
|
|
|
+ }
|
|
|
+ val pictureforgame = screen.filter{it.game == GameID}
|
|
|
+ var minn = min.find { it.id_game == GameID }
|
|
|
+ var recc = rec.find { it.id_game == GameID }
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.padding(5.dp)
|
|
|
+ ) {
|
|
|
+ if (minn != null) {
|
|
|
+ Text(
|
|
|
+ text = "Минимальные системные требования:",
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Операционная система: " + minn.OS,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Процессор: " + minn.processor,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Оперативная память: " + minn.RAM,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Видеокарта: " + minn.graphic_card,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Свободное место на диске: " + minn.free_space,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.padding(5.dp)
|
|
|
+ ) {
|
|
|
+ if (recc != null) {
|
|
|
+ Text(
|
|
|
+ text = "Рекомендуемые системные требования:",
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Операционная система: " + recc.OS,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Процессор: " + recc.processor,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Оперативная память: " + recc.RAM,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Видеокарта: " + recc.graphic_card,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "·Свободное место на диске: " + recc.free_space,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 10.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.padding(5.dp,0.dp,0.dp,0.dp)
|
|
|
+ ) {
|
|
|
+ Text(
|
|
|
+ text = "Доступность игры:",
|
|
|
+ textAlign = TextAlign.Left,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 20.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ text = "Официальный источник:",
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 15.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ LinkText(game.link_oficial)
|
|
|
+ if(game.link_torrent != null)
|
|
|
+ {
|
|
|
+ Text(
|
|
|
+ text = "Сторонний источник:",
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 15.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
+ LinkText(game.link_torrent)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.padding(5.dp,0.dp,0.dp,0.dp)
|
|
|
+ )
|
|
|
+ {
|
|
|
+ Text(
|
|
|
+ text = "Наличие игры в облачном гейминге:",
|
|
|
+ textAlign = TextAlign.Left,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 20.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ )
|
|
|
+ for(cloud in clouds)
|
|
|
+ {
|
|
|
+ LinkText(cloud.link)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.padding(5.dp,0.dp,0.dp,0.dp)
|
|
|
+ ) {
|
|
|
+ if(game.description != null) {
|
|
|
+ Text(
|
|
|
+ text = "Описание игры:",
|
|
|
+ textAlign = TextAlign.Left,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 20.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ )
|
|
|
+ Text(
|
|
|
+ game.description,
|
|
|
+ textAlign = TextAlign.Center,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 12.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.padding(5.dp,0.dp,0.dp,0.dp)
|
|
|
+ ) {
|
|
|
+ Text(
|
|
|
+ text = "Скриншоты из игры:",
|
|
|
+ textAlign = TextAlign.Left,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 20.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ )
|
|
|
+ Row(
|
|
|
+ modifier = Modifier
|
|
|
+ .background(color = Color(0xFFFDFFFC), shape = RoundedCornerShape(20.dp))
|
|
|
+ .height(220.dp)
|
|
|
+ .fillMaxWidth(),
|
|
|
+ horizontalArrangement = Arrangement.Center,
|
|
|
+ verticalAlignment = Alignment.CenterVertically
|
|
|
+ ) {
|
|
|
+ LazyRow(
|
|
|
+ modifier = Modifier.fillMaxWidth()
|
|
|
+ ) {
|
|
|
+ items(pictureforgame) { screenshot ->
|
|
|
+ Image(
|
|
|
+ painter = rememberImagePainter(screenshot.picture),
|
|
|
+ contentDescription = "Описание изображения",
|
|
|
+ modifier = Modifier
|
|
|
+ .width(380.dp)
|
|
|
+ .height(200.dp)
|
|
|
+ .clip(RoundedCornerShape(20.dp))
|
|
|
+ .padding(4.dp)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Column(
|
|
|
+ modifier = Modifier.padding(5.dp,0.dp,0.dp,0.dp)
|
|
|
+ )
|
|
|
+ {
|
|
|
+ Text(
|
|
|
+ text = "Трейлер игры:",
|
|
|
+ textAlign = TextAlign.Left,
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 20.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ )
|
|
|
+ Row(
|
|
|
+ modifier = Modifier
|
|
|
+ .background(color = Color(0xFFFDFFFC), shape = RoundedCornerShape(20.dp))
|
|
|
+ .height(220.dp)
|
|
|
+ .fillMaxWidth(),
|
|
|
+ horizontalArrangement = Arrangement.Center,
|
|
|
+ verticalAlignment = Alignment.CenterVertically
|
|
|
+ )
|
|
|
+ {
|
|
|
+ if (game.video != null) {
|
|
|
+ VideoPlayerFromUrl(game.video)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+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 GameItem(game: Game)
|
|
|
-{
|
|
|
- Text(
|
|
|
- game.name_game
|
|
|
+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)
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+@Composable
|
|
|
+fun LinkText(gameLink: String) {
|
|
|
+ val uriHandler = LocalUriHandler.current
|
|
|
+
|
|
|
+ val annotatedString = buildAnnotatedString {
|
|
|
+ pushStyle(androidx.compose.ui.text.SpanStyle(color = Color.Black, textDecoration = TextDecoration.None))
|
|
|
+ append(gameLink)
|
|
|
+ pop()
|
|
|
+ }
|
|
|
+
|
|
|
+ ClickableText(
|
|
|
+ text = annotatedString,
|
|
|
+ onClick = { offset ->
|
|
|
+ uriHandler.openUri(gameLink)
|
|
|
+ },
|
|
|
+ style = androidx.compose.ui.text.TextStyle(
|
|
|
+ fontFamily = ibmplexmono,
|
|
|
+ fontSize = 15.sp,
|
|
|
+ color = Color.Black,
|
|
|
+ textAlign = TextAlign.Left
|
|
|
+ )
|
|
|
)
|
|
|
}
|