更改目录结构

This commit is contained in:
2024-07-23 15:25:00 +08:00
parent 82f58d4b9c
commit dfbc151e4e
47 changed files with 1007 additions and 533 deletions

View File

@@ -1,24 +0,0 @@
package com.aiosman.riderpro
import androidx.lifecycle.ViewModel
private val DATA = (0..60).toList().mapIndexed { idx, _ ->
MomentItem(
id = idx,
avatar = R.drawable.default_avatar,
nickname = "Onyama Limba",
location = "Japan",
time = "2023.02.02 11:23",
followStatus = false,
momentTextContent = "By strongarming Ducati into giving him the factory seat.Marquez effectively …",
momentPicture = R.drawable.default_moment_img,
likeCount = 21,
commentCount = 43,
shareCount = 33,
favoriteCount = 211
)
}
object HomeViewModel : ViewModel() {
val momentList = DATA
}

View File

@@ -1,22 +1,16 @@
package com.aiosman.riderpro
import ModificationListScreen
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
@@ -27,27 +21,18 @@ import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemColors
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.aiosman.riderpro.ui.theme.RiderProTheme
import com.aiosman.riderpro.ui.Navigation
import com.aiosman.riderpro.ui.index.NavigationItem
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.google.android.libraries.places.api.Places
@@ -79,98 +64,6 @@ val LocalAnimatedContentScope = compositionLocalOf<AnimatedContentScope> {
error("AnimatedContentScope not provided")
}
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun NavigationController(navController: NavHostController) {
val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp()
}
NavHost(
navController = navController,
startDestination = "Index",
) {
composable(route = "Index") {
CompositionLocalProvider(
LocalAnimatedContentScope provides this,
) {
ScaffoldWithNavigationBar2()
}
}
composable(route = "ProfileTimeline") {
GalleryPage()
}
composable(route = "LocationDetail") {
Box(
modifier = Modifier.padding(bottom = navigationBarHeight)
) {
LocationDetail()
}
}
composable(route = "OfficialPhoto") {
OfficialGalleryPage()
}
composable(route = "OfficialPhotographer") {
OfficialPhotographer()
}
composable(
route = "Post/{id}",
arguments = listOf(navArgument("id") { type = NavType.StringType })
) { backStackEntry ->
CompositionLocalProvider(
LocalAnimatedContentScope provides this,
) {
val id = backStackEntry.arguments?.getString("id")
PostPage(
id!!
)
}
}
composable(route = "ModificationList") {
ModificationListScreen()
}
composable(route = "MyMessage") {
NotificationsScreen()
}
composable(route = "Comments") {
CommentsScreen()
}
composable(route = "Likes") {
LikePage()
}
composable(route = "Followers") {
FollowerPage()
}
composable(route = "NewPost") {
NewPostScreen()
}
composable(route = "EditModification") {
Box(
modifier = Modifier.padding(top = 64.dp)
) {
EditModification()
}
}
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun Navigation() {
val navController = rememberNavController()
SharedTransitionLayout {
CompositionLocalProvider(
LocalNavController provides navController,
LocalSharedTransitionScope provides this@SharedTransitionLayout,
) {
Box {
NavigationController(navController = navController)
}
}
}
}
// 用于带导航栏的路由的可复用 composable
@Composable
@@ -266,204 +159,3 @@ fun ScaffoldWithNavigationBar(
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun ScaffoldWithNavigationBar2() {
val model = IndexViewModel
val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp()
}
val item = listOf(
NavigationItem.Home,
NavigationItem.Street,
NavigationItem.Add,
NavigationItem.Message,
NavigationItem.Profile
)
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(Color.Black)
}
Scaffold(
bottomBar = {
NavigationBar(
modifier = Modifier.height(56.dp + navigationBarHeight),
containerColor = Color.Black
) {
item.forEachIndexed { idx, it ->
val isSelected = model.tabIndex == idx
val iconTint by animateColorAsState(
targetValue = if (isSelected) Color.Red else Color.White,
animationSpec = tween(durationMillis = 250), label = ""
)
NavigationBarItem(
selected = isSelected,
onClick = {
model.tabIndex = idx
// if (it.route == NavigationItem.Add.route || it.route == NavigationItem.Message.route) {
// systemUiController.setStatusBarColor(Color.Black, darkIcons = false)
// } else {
// systemUiController.setStatusBarColor(
// Color.Transparent,
// darkIcons = true
// )
// }
},
colors = NavigationBarItemColors(
selectedTextColor = Color.Red,
selectedIndicatorColor = Color.Black,
unselectedTextColor = Color.Red,
disabledIconColor = Color.Red,
disabledTextColor = Color.Red,
selectedIconColor = iconTint,
unselectedIconColor = iconTint,
),
icon = {
Icon(
modifier = Modifier.size(24.dp),
imageVector = if (isSelected) it.selectedIcon() else it.icon(),
contentDescription = null,
tint = iconTint
)
}
)
}
}
}
) { innerPadding ->
Box(
modifier = Modifier
) {
when (model.tabIndex) {
0 -> Box(
modifier = Modifier.padding(innerPadding)
) {
Home()
}
1 -> Street()
2 -> Box(
modifier = Modifier.padding(innerPadding)
) { Add() }
3 -> Box(
modifier = Modifier.padding(innerPadding)
) { Video() }
4 -> Box(
modifier = Modifier.padding(innerPadding)
) { Profile() }
}
}
}
}
@Composable
fun Home() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
PagingBackendSample()
}
}
@Composable
fun Street() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
StreetPage()
}
}
@Composable
fun Add() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Black, darkIcons = false)
}
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Black),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
AddPage()
}
}
@Composable
fun Video() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Black, darkIcons = false)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
) {
ShortVideo()
}
}
@Composable
fun Message() {
val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp()
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
) {
MessagePage()
}
}
@Composable
fun Profile() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
ProfilePage()
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
RiderProTheme {
Surface(modifier = Modifier.fillMaxSize(), color = Color.White) {
Navigation()
}
}
}

View File

@@ -0,0 +1,9 @@
package com.aiosman.riderpro.data
data class ListContainer<T>(
val total: Int,
val page: Int,
val pageSize: Int,
val list: List<T>
)

View File

@@ -0,0 +1,92 @@
package com.aiosman.riderpro.data.moment
import android.net.http.HttpException
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.aiosman.riderpro.R
import com.aiosman.riderpro.data.ListContainer
import com.aiosman.riderpro.model.MomentItem
import java.io.IOException
class MomentPagingSource(
private val remoteDataSource: MomentRemoteDataSource,
) : PagingSource<Int, MomentItem>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MomentItem> {
return try {
val currentPage = params.key ?: 1
val moments = remoteDataSource.getMoments(
pageNumber = currentPage
)
LoadResult.Page(
data = moments.list,
prevKey = if (currentPage == 1) null else currentPage - 1,
nextKey = if (moments.list.isEmpty()) null else moments.page + 1
)
} catch (exception: IOException) {
return LoadResult.Error(exception)
}
}
override fun getRefreshKey(state: PagingState<Int, MomentItem>): Int? {
return state.anchorPosition
}
}
class MomentRemoteDataSource(
private val momentService: MomentService,
) {
suspend fun getMoments(pageNumber: Int): ListContainer<MomentItem> {
return momentService.getMoments(pageNumber)
}
}
interface MomentService {
suspend fun getMoments(pageNumber: Int): ListContainer<MomentItem>
}
class TestMomentServiceImpl() : MomentService {
val mockData = (0..300).toList().mapIndexed { idx, _ ->
MomentItem(
id = idx,
avatar = R.drawable.default_avatar,
nickname = "Onyama Limba",
location = "Japan",
time = "2023.02.02 11:23",
followStatus = false,
momentTextContent = "By strongarming Ducati into giving him the factory seat.Marquez effectively …",
momentPicture = R.drawable.default_moment_img,
likeCount = 21,
commentCount = 43,
shareCount = 33,
favoriteCount = 211
)
}
val testMomentBackend = TestMomentBackend(mockData)
override suspend fun getMoments(pageNumber: Int): ListContainer<MomentItem> {
return testMomentBackend.fetchMomentItems(pageNumber)
}
}
class TestMomentBackend(
private val mockData: List<MomentItem>,
private val loadDelay: Long = 500,
) {
val DataBatchSize = 5
suspend fun fetchMomentItems(pageNumber: Int): ListContainer<MomentItem> {
val from = pageNumber * DataBatchSize
val to = (pageNumber + 1) * DataBatchSize
val currentSublist = mockData.subList(from, to)
// delay
kotlinx.coroutines.delay(loadDelay)
return ListContainer(
total = mockData.size,
page = pageNumber,
pageSize = DataBatchSize,
list = currentSublist
)
}
}

View File

@@ -1,21 +1,16 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.exp
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.RelativeLayout
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
//import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
private const val COLOR_TRANSPARENT = 0

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.model
import androidx.annotation.DrawableRes

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.model
import androidx.paging.PagingSource
import androidx.paging.PagingState

View File

@@ -1,6 +1,7 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.model
import androidx.annotation.DrawableRes
import com.aiosman.riderpro.R
data class MomentItem(
val id: Int,

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.test
import kotlin.math.min

View File

@@ -1,7 +1,8 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.test
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.aiosman.riderpro.model.MomentItem
import kotlinx.coroutines.delay
import kotlin.math.ceil

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.test
data class StreetPosition(
val name:String,

View File

@@ -0,0 +1,156 @@
package com.aiosman.riderpro.ui
import ModificationListScreen
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.aiosman.riderpro.LocalAnimatedContentScope
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.LocalSharedTransitionScope
import com.aiosman.riderpro.ui.comment.CommentsScreen
import com.aiosman.riderpro.ui.follower.FollowerScreen
import com.aiosman.riderpro.ui.gallery.OfficialGalleryScreen
import com.aiosman.riderpro.ui.gallery.OfficialPhotographerScreen
import com.aiosman.riderpro.ui.gallery.ProfileTimelineScreen
import com.aiosman.riderpro.ui.index.IndexScreen
import com.aiosman.riderpro.ui.like.LikeScreen
import com.aiosman.riderpro.ui.location.LocationDetailScreen
import com.aiosman.riderpro.ui.message.NotificationsScreen
import com.aiosman.riderpro.ui.modification.EditModificationScreen
import com.aiosman.riderpro.ui.post.NewPostScreen
import com.aiosman.riderpro.ui.post.PostScreen
sealed class NavigationRoute(
val route: String,
) {
data object Index : NavigationRoute("Index")
data object ProfileTimeline : NavigationRoute("ProfileTimeline")
data object LocationDetail : NavigationRoute("LocationDetail/{x}/{y}")
data object OfficialPhoto : NavigationRoute("OfficialPhoto")
data object OfficialPhotographer : NavigationRoute("OfficialPhotographer")
data object Post : NavigationRoute("Post/{id}")
data object ModificationList : NavigationRoute("ModificationList")
data object MyMessage : NavigationRoute("MyMessage")
data object Comments : NavigationRoute("Comments")
data object Likes : NavigationRoute("Likes")
data object Followers : NavigationRoute("Followers")
data object NewPost : NavigationRoute("NewPost")
data object EditModification : NavigationRoute("EditModification")
}
@Composable
fun NavigationController(navController: NavHostController) {
val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp()
}
NavHost(
navController = navController,
startDestination = NavigationRoute.Index.route,
) {
composable(route = NavigationRoute.Index.route) {
CompositionLocalProvider(
LocalAnimatedContentScope provides this,
) {
IndexScreen()
}
}
composable(route = NavigationRoute.ProfileTimeline.route) {
ProfileTimelineScreen()
}
composable(
route = NavigationRoute.LocationDetail.route,
arguments = listOf(
navArgument("x") { type = NavType.FloatType },
navArgument("y") { type = NavType.FloatType }
)
) {
Box(
modifier = Modifier.padding(bottom = navigationBarHeight)
) {
val x = it.arguments?.getFloat("x") ?: 0f
val y = it.arguments?.getFloat("y") ?: 0f
LocationDetailScreen(
x, y
)
}
}
composable(route = NavigationRoute.OfficialPhoto.route) {
OfficialGalleryScreen()
}
composable(route = NavigationRoute.OfficialPhotographer.route) {
OfficialPhotographerScreen()
}
composable(
route = NavigationRoute.Post.route,
arguments = listOf(navArgument("id") { type = NavType.StringType })
) { backStackEntry ->
CompositionLocalProvider(
LocalAnimatedContentScope provides this,
) {
val id = backStackEntry.arguments?.getString("id")
PostScreen(
id!!
)
}
}
composable(route = NavigationRoute.ModificationList.route) {
ModificationListScreen()
}
composable(route = NavigationRoute.MyMessage.route) {
NotificationsScreen()
}
composable(route = NavigationRoute.Comments.route) {
CommentsScreen()
}
composable(route = NavigationRoute.Likes.route) {
LikeScreen()
}
composable(route = NavigationRoute.Followers.route) {
FollowerScreen()
}
composable(route = NavigationRoute.NewPost.route) {
NewPostScreen()
}
composable(route = NavigationRoute.EditModification.route) {
Box(
modifier = Modifier.padding(top = 64.dp)
) {
EditModificationScreen()
}
}
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun Navigation() {
val navController = rememberNavController()
SharedTransitionLayout {
CompositionLocalProvider(
LocalNavController provides navController,
LocalSharedTransitionScope provides this@SharedTransitionLayout,
) {
Box {
NavigationController(navController = navController)
}
}
}
}

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.comment
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -35,6 +35,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.ui.post.CommentsSection
import com.aiosman.riderpro.R
@Preview
@@ -53,7 +55,7 @@ fun CommentModalContent(onDismiss: () -> Unit = {}) {
}
Column(
modifier = Modifier.height(500.dp)
modifier = Modifier
) {
Box(
modifier = Modifier

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.comment
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -25,6 +25,10 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
@Preview
@Composable

View File

@@ -0,0 +1,41 @@
package com.aiosman.riderpro.ui.composables
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.animation.with
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.sp
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun AnimatedCounter(count: Int, modifier: Modifier = Modifier, fontSize: Int = 24) {
AnimatedContent(
targetState = count,
transitionSpec = {
// Compare the incoming number with the previous number.
if (targetState > initialState) {
// If the target number is larger, it slides up and fades in
// while the initial (smaller) number slides up and fades out.
(slideInVertically { height -> height } + fadeIn()).togetherWith(slideOutVertically { height -> -height } + fadeOut())
} else {
// If the target number is smaller, it slides down and fades in
// while the initial number slides down and fades out.
(slideInVertically { height -> -height } + fadeIn()).togetherWith(slideOutVertically { height -> height } + fadeOut())
}.using(
// Disable clipping since the faded slide-in/out should
// be displayed out of bounds.
SizeTransform(clip = false)
)
}
) { targetCount ->
Text(text = "$targetCount", modifier = modifier, fontSize = fontSize.sp)
}
}

View File

@@ -0,0 +1,71 @@
package com.aiosman.riderpro.ui.composables
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import com.aiosman.riderpro.R
import kotlinx.coroutines.launch
@Composable
fun AnimatedLikeIcon(
modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null
) {
var liked by remember { mutableStateOf(false) }
val animatableRotation = remember { Animatable(0f) }
val animatedColor by animateColorAsState(targetValue = if (liked) Color(0xFFd83737) else Color.Black)
val scope = rememberCoroutineScope()
suspend fun shake() {
repeat(2) {
animatableRotation.animateTo(
targetValue = 10f,
animationSpec = tween(100)
) {
}
animatableRotation.animateTo(
targetValue = -10f,
animationSpec = tween(100)
) {
}
}
animatableRotation.animateTo(
targetValue = 0f,
animationSpec = tween(100)
)
}
Box(contentAlignment = Alignment.Center, modifier = Modifier.clickable {
liked = !liked
onClick?.invoke()
// Trigger shake animation
scope.launch {
shake()
}
}) {
Image(
painter = painterResource(id = R.drawable.rider_pro_like),
contentDescription = "Like",
modifier = modifier.graphicsLayer {
rotationZ = animatableRotation.value
},
colorFilter = androidx.compose.ui.graphics.ColorFilter.tint(animatedColor)
)
}
}

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.composables
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box

View File

@@ -1,13 +1,11 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.composables
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.areNavigationBarsVisible
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.follower
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
@@ -21,10 +21,13 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.comment.NoticeScreenHeader
@Preview
@Composable
fun FollowerPage() {
fun FollowerScreen() {
StatusBarMaskLayout(
modifier = Modifier.padding(horizontal = 16.dp)
) {

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.gallery
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.ExperimentalFoundationApi
@@ -44,12 +44,13 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.R
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable
fun GalleryPage() {
fun ProfileTimelineScreen() {
val pagerState = rememberPagerState(pageCount = { 2 })
val scope = rememberCoroutineScope()
val systemUiController = rememberSystemUiController()

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.gallery
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -32,10 +32,14 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
@Preview
@Composable
fun OfficialGalleryPage() {
fun OfficialGalleryScreen() {
StatusBarMaskLayout {
Column(
modifier = Modifier

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.gallery
import android.util.Log
import androidx.compose.foundation.Image
@@ -24,7 +24,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -38,12 +37,16 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
data class ArtWork(
val id: Int,
@@ -69,7 +72,7 @@ fun GenerateMockArtWorks(): List<ArtWork> {
@OptIn(ExperimentalLayoutApi::class)
@Preview
@Composable
fun OfficialPhotographer() {
fun OfficialPhotographerScreen() {
val lazyListState = rememberLazyListState()
var artWorks by remember { mutableStateOf<List<ArtWork>>(emptyList()) }
LaunchedEffect(Unit) {
@@ -135,7 +138,7 @@ fun OfficialPhotographer() {
)
)
.padding(16.dp)
.align(alignment = androidx.compose.ui.Alignment.BottomCenter)
.align(alignment = Alignment.BottomCenter)
) {
Column(
@@ -257,11 +260,11 @@ fun OfficialPhotographer() {
) {
Row(
modifier = Modifier.fillMaxSize(),
verticalAlignment = androidx.compose.ui.Alignment.CenterVertically,
verticalAlignment = Alignment.CenterVertically,
) {
Image(
painter = painterResource(id = R.drawable.rider_pro_nav_back),
colorFilter = androidx.compose.ui.graphics.ColorFilter.tint(Color.White),
colorFilter = ColorFilter.tint(Color.White),
contentDescription = "",
modifier = Modifier
.size(32.dp)

View File

@@ -0,0 +1,209 @@
package com.aiosman.riderpro.ui.index
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemColors
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import com.aiosman.riderpro.ui.index.tabs.add.AddPage
import com.aiosman.riderpro.ui.index.tabs.moment.MomentsList
import com.aiosman.riderpro.ui.index.tabs.profile.ProfilePage
import com.aiosman.riderpro.ui.index.tabs.shorts.ShortVideo
import com.aiosman.riderpro.ui.index.tabs.street.StreetPage
import com.google.accompanist.systemuicontroller.rememberSystemUiController
@Composable
fun IndexScreen() {
val model = IndexViewModel
val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp()
}
val item = listOf(
NavigationItem.Home,
NavigationItem.Street,
NavigationItem.Add,
NavigationItem.Message,
NavigationItem.Profile
)
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(Color.Black)
}
Scaffold(
bottomBar = {
NavigationBar(
modifier = Modifier.height(56.dp + navigationBarHeight),
containerColor = Color.Black
) {
item.forEachIndexed { idx, it ->
val isSelected = model.tabIndex == idx
val iconTint by animateColorAsState(
targetValue = if (isSelected) Color.Red else Color.White,
animationSpec = tween(durationMillis = 250), label = ""
)
NavigationBarItem(
selected = isSelected,
onClick = {
model.tabIndex = idx
// if (it.route == NavigationItem.Add.route || it.route == NavigationItem.Message.route) {
// systemUiController.setStatusBarColor(Color.Black, darkIcons = false)
// } else {
// systemUiController.setStatusBarColor(
// Color.Transparent,
// darkIcons = true
// )
// }
},
colors = NavigationBarItemColors(
selectedTextColor = Color.Red,
selectedIndicatorColor = Color.Black,
unselectedTextColor = Color.Red,
disabledIconColor = Color.Red,
disabledTextColor = Color.Red,
selectedIconColor = iconTint,
unselectedIconColor = iconTint,
),
icon = {
Icon(
modifier = Modifier.size(24.dp),
imageVector = if (isSelected) it.selectedIcon() else it.icon(),
contentDescription = null,
tint = iconTint
)
}
)
}
}
}
) { innerPadding ->
Box(
modifier = Modifier
) {
when (model.tabIndex) {
0 -> Box(
modifier = Modifier.padding(innerPadding)
) {
Home()
}
1 -> Street()
2 -> Box(
modifier = Modifier.padding(innerPadding)
) { Add() }
3 -> Box(
modifier = Modifier.padding(innerPadding)
) { Video() }
4 -> Box(
modifier = Modifier.padding(innerPadding)
) { Profile() }
}
}
}
}
@Composable
fun Home() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
MomentsList()
}
}
@Composable
fun Street() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
StreetPage()
}
}
@Composable
fun Add() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Black, darkIcons = false)
}
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Black),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
AddPage()
}
}
@Composable
fun Video() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Black, darkIcons = false)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
) {
ShortVideo()
}
}
@Composable
fun Profile() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
ProfilePage()
}
}

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.index
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf

View File

@@ -1,13 +1,9 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.index
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Place
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import com.aiosman.riderpro.R
sealed class NavigationItem(
val route: String,

View File

@@ -1,9 +1,8 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.index.tabs.add
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -11,19 +10,19 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.LocationOn
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusModifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.ui.post.NewPostViewModel
import com.aiosman.riderpro.R
@Composable
fun AddPage(){

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.index.tabs.moment
import androidx.annotation.DrawableRes
import androidx.compose.animation.ExperimentalSharedTransitionApi
@@ -42,6 +42,15 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.paging.compose.collectAsLazyPagingItems
import com.aiosman.riderpro.LocalAnimatedContentScope
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.LocalSharedTransitionScope
import com.aiosman.riderpro.R
import com.aiosman.riderpro.model.MomentItem
import com.aiosman.riderpro.ui.comment.CommentModalContent
import com.aiosman.riderpro.ui.composables.AnimatedCounter
import com.aiosman.riderpro.ui.composables.AnimatedLikeIcon
import com.google.accompanist.systemuicontroller.rememberSystemUiController
private val DATA = (0..60).toList().mapIndexed { idx, _ ->
@@ -63,41 +72,16 @@ private val DATA = (0..60).toList().mapIndexed { idx, _ ->
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun PagingBackendSample() {
// val myBackend = remember { TestBackend(DATA) }
// val pager = remember {
// Pager(
// PagingConfig(
// pageSize = myBackend.DataBatchSize,
// enablePlaceholders = true,
// maxSize = 200
// )
// ) {
// myBackend.getAllData()
// }
// }
val model = HomeViewModel
// val lazyPagingItems = model.pager.collectAsLazyPagingItems()
fun MomentsList() {
val model = MomentViewModel
val moments = model.momentsFlow.collectAsLazyPagingItems()
LazyColumn {
// if (lazyPagingItems.loadState.refresh == LoadState.Loading) {
// item {
// MomentListLoading()
// }
// }
items(count = model.momentList.size) { index ->
val item = model.momentList.getOrNull(index)
if (item != null) {
MomentCard(item)
}
items(moments.itemCount) { idx ->
val momentItem = moments[idx] ?: return@items
MomentCard(momentItem = momentItem)
}
// if (lazyPagingItems.loadState.append == LoadState.Loading) {
// item {
// MomentListLoading()
// }
// }
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@@ -124,7 +108,7 @@ fun MomentCard(
.fillMaxHeight()
.weight(1f)
ModificationListHeader()
MomentBottomOperateRowGroup(momentOperateBtnBoxModifier)
MomentBottomOperateRowGroup(momentOperateBtnBoxModifier, momentItem = momentItem)
}
}
@@ -312,9 +296,24 @@ fun MomentOperateBtn(@DrawableRes icon: Int, count: String) {
}
}
@Composable
fun MomentOperateBtn(count: String, content: @Composable () -> Unit) {
Row(
modifier = Modifier,
verticalAlignment = Alignment.CenterVertically
) {
content()
AnimatedCounter(
count = count.toInt(),
fontSize = 14,
modifier = Modifier.padding(start = 7.dp)
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MomentBottomOperateRowGroup(modifier: Modifier) {
fun MomentBottomOperateRowGroup(modifier: Modifier, momentItem: MomentItem) {
var systemUiController = rememberSystemUiController()
var showCommentModal by remember { mutableStateOf(false) }
if (showCommentModal) {
@@ -340,7 +339,14 @@ fun MomentBottomOperateRowGroup(modifier: Modifier) {
modifier = modifier,
contentAlignment = Alignment.Center
) {
MomentOperateBtn(icon = R.drawable.rider_pro_like, count = "21")
MomentOperateBtn(count = momentItem.likeCount.toString()) {
AnimatedLikeIcon(modifier = Modifier.size(24.dp)) {
MomentViewModel.updateById(
momentItem.id,
momentItem.copy(likeCount = momentItem.likeCount + 1)
)
}
}
}
Box(
modifier = modifier.clickable(

View File

@@ -0,0 +1,59 @@
package com.aiosman.riderpro.ui.index.tabs.moment
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.toMutableStateList
import androidx.lifecycle.ViewModel
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.aiosman.riderpro.R
import com.aiosman.riderpro.data.moment.MomentPagingSource
import com.aiosman.riderpro.data.moment.MomentRemoteDataSource
import com.aiosman.riderpro.data.moment.TestMomentServiceImpl
import com.aiosman.riderpro.model.MomentItem
import kotlinx.coroutines.flow.Flow
private val DATA = (0..60).toList().mapIndexed { idx, _ ->
MomentItem(
id = idx,
avatar = R.drawable.default_avatar,
nickname = "Onyama Limba",
location = "Japan",
time = "2023.02.02 11:23",
followStatus = false,
momentTextContent = "By strongarming Ducati into giving him the factory seat.Marquez effectively …",
momentPicture = R.drawable.default_moment_img,
likeCount = 21,
commentCount = 43,
shareCount = 33,
favoriteCount = 211
)
}
object MomentViewModel : ViewModel() {
var momentList by mutableStateOf(DATA)
fun updateById(id: Int, momentItem: MomentItem) {
momentList = momentList.map {
if (it.id == id) {
momentItem
} else {
it
}
}.toMutableStateList()
}
var momentListPagingSource = MomentPagingSource(
MomentRemoteDataSource(TestMomentServiceImpl())
)
val momentsFlow: Flow<PagingData<MomentItem>> = Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = { momentListPagingSource }
).flow
}

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.index.tabs.profile
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
@@ -31,6 +31,10 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
import com.aiosman.riderpro.model.MomentItem
import com.aiosman.riderpro.model.profileMomentItems
@Composable

View File

@@ -1,11 +1,10 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.index.tabs.shorts
import androidx.compose.animation.core.Animatable
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

View File

@@ -1,10 +1,8 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.index.tabs.shorts
import android.app.Activity
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import com.aiosman.riderpro.ShortViewCompose
import com.aiosman.riderpro.ui.theme.RiderProTheme
val videoUrls = listOf(

View File

@@ -1,4 +1,6 @@
package com.aiosman.riderpro
@file:kotlin.OptIn(ExperimentalMaterial3Api::class)
package com.aiosman.riderpro.ui.index.tabs.shorts
import android.net.Uri
import android.view.Gravity
@@ -9,6 +11,7 @@ import androidx.annotation.OptIn
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.Orientation
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -21,8 +24,11 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -59,22 +65,25 @@ import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.ProgressiveMediaSource
import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.comment.CommentModalContent
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun ShortViewCompose(
videoItemsUrl:List<String>,
clickItemPosition:Int = 0,
videoHeader:@Composable () -> Unit = {},
videoBottom:@Composable () -> Unit = {}
videoItemsUrl: List<String>,
clickItemPosition: Int = 0,
videoHeader: @Composable () -> Unit = {},
videoBottom: @Composable () -> Unit = {}
) {
val pagerState: PagerState = run {
remember {
PagerState(clickItemPosition, 0, videoItemsUrl.size - 1)
}
}
val initialLayout= remember {
val initialLayout = remember {
mutableStateOf(true)
}
val pauseIconVisibleState = remember {
@@ -85,19 +94,21 @@ fun ShortViewCompose(
orientation = Orientation.Vertical,
offscreenLimit = 1
) {
pauseIconVisibleState.value=false
SingleVideoItemContent(videoItemsUrl[page],
pauseIconVisibleState.value = false
SingleVideoItemContent(
videoItemsUrl[page],
pagerState,
page,
initialLayout,
pauseIconVisibleState,
videoHeader,
videoBottom)
videoBottom
)
}
LaunchedEffect(clickItemPosition){
LaunchedEffect(clickItemPosition) {
delay(300)
initialLayout.value=false
initialLayout.value = false
}
}
@@ -112,16 +123,18 @@ private fun SingleVideoItemContent(
VideoHeader: @Composable() () -> Unit,
VideoBottom: @Composable() () -> Unit,
) {
Box(modifier = Modifier.fillMaxSize()){
VideoPlayer(videoUrl,pagerState,pager,pauseIconVisibleState)
Box(modifier = Modifier.fillMaxSize()) {
VideoPlayer(videoUrl, pagerState, pager, pauseIconVisibleState)
VideoHeader.invoke()
Box(modifier = Modifier.align(Alignment.BottomStart)){
Box(modifier = Modifier.align(Alignment.BottomStart)) {
VideoBottom.invoke()
}
if (initialLayout.value) {
Box(modifier = Modifier
.fillMaxSize()
.background(color = Color.Black))
Box(
modifier = Modifier
.fillMaxSize()
.background(color = Color.Black)
)
}
}
}
@@ -135,9 +148,12 @@ fun VideoPlayer(
pauseIconVisibleState: MutableState<Boolean>,
) {
val context = LocalContext.current
val scope= rememberCoroutineScope()
val scope = rememberCoroutineScope()
val lifecycleOwner = LocalLifecycleOwner.current
var showCommentModal by remember { mutableStateOf(false) }
var sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true
)
val exoPlayer = remember {
ExoPlayer.Builder(context)
.build()
@@ -160,8 +176,12 @@ fun VideoPlayer(
}
exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
exoPlayer.repeatMode = Player.REPEAT_MODE_ONE
Box(modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.TopCenter) {
// player box
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.TopCenter
) {
var playerView by remember { mutableStateOf<PlayerView?>(null) } // Store reference to PlayerView
AndroidView(
@@ -176,7 +196,8 @@ fun VideoPlayer(
hideController()
useController = false
player = exoPlayer
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT // 或 RESIZE_MODE_ZOOM
resizeMode =
AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT // 或 RESIZE_MODE_ZOOM
layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -226,11 +247,13 @@ fun VideoPlayer(
Lifecycle.Event.ON_PAUSE -> {
exoPlayer.pause() // 应用进入后台时暂停
}
Lifecycle.Event.ON_RESUME -> {
if (pager == pagerState.currentPage) {
exoPlayer.play() // 返回前台且为当前页面时恢复播放
}
}
else -> {}
}
}
@@ -243,29 +266,58 @@ fun VideoPlayer(
}
Box(modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.BottomEnd){
Column (modifier = Modifier.padding(bottom = 72.dp, end = 12.dp),
horizontalAlignment = Alignment.CenterHorizontally){
// action buttons
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.BottomEnd
) {
Column(
modifier = Modifier.padding(bottom = 72.dp, end = 12.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
UserAvatar()
VideoBtn(icon = R.drawable.rider_pro_video_like, text = "975.9k")
VideoBtn(icon = R.drawable.rider_pro_video_comment, text = "1896")
VideoBtn(icon = R.drawable.rider_pro_video_comment, text = "1896") {
showCommentModal = true
}
VideoBtn(icon = R.drawable.rider_pro_video_favor, text = "234")
VideoBtn(icon = R.drawable.rider_pro_video_share, text = "677k")
}
}
Box(modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.BottomStart){
Column (modifier = Modifier.padding(start = 16.dp, bottom = 16.dp)){
Row (modifier = Modifier.padding(bottom = 8.dp).background(color = Color.Gray),
// info
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.BottomStart
) {
Column(modifier = Modifier.padding(start = 16.dp, bottom = 16.dp)) {
Row(
modifier = Modifier
.padding(bottom = 8.dp)
.background(color = Color.Gray),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start,
){
Image(modifier = Modifier.size(20.dp).padding(start = 4.dp, end = 6.dp), painter = painterResource(id = R.drawable.rider_pro_video_location), contentDescription = "")
Text(modifier = Modifier.padding(end = 4.dp),text = "USA",fontSize = 12.sp, color = Color.White, style = TextStyle(fontWeight = FontWeight.Bold))
) {
Image(
modifier = Modifier
.size(20.dp)
.padding(start = 4.dp, end = 6.dp),
painter = painterResource(id = R.drawable.rider_pro_video_location),
contentDescription = ""
)
Text(
modifier = Modifier.padding(end = 4.dp),
text = "USA",
fontSize = 12.sp,
color = Color.White,
style = TextStyle(fontWeight = FontWeight.Bold)
)
}
Text(text = "@Kevinlinpr",fontSize = 16.sp, color = Color.White, style = TextStyle(fontWeight = FontWeight.Bold))
Text(
text = "@Kevinlinpr",
fontSize = 16.sp,
color = Color.White,
style = TextStyle(fontWeight = FontWeight.Bold)
)
Text(
modifier = Modifier
.fillMaxWidth()
@@ -279,23 +331,54 @@ fun VideoPlayer(
)
}
}
if (showCommentModal) {
ModalBottomSheet(
onDismissRequest = { showCommentModal = false },
containerColor = Color.White,
sheetState = sheetState
) {
CommentModalContent() {
}
}
}
}
@Composable
fun UserAvatar(){
Image(modifier = Modifier.padding(bottom = 16.dp).size(40.dp).border(width = 3.dp, color = Color.White, shape = RoundedCornerShape(40.dp)).clip(
RoundedCornerShape(40.dp)
), painter = painterResource(id = R.drawable.default_avatar), contentDescription = "")
fun UserAvatar() {
Image(
modifier = Modifier
.padding(bottom = 16.dp)
.size(40.dp)
.border(width = 3.dp, color = Color.White, shape = RoundedCornerShape(40.dp))
.clip(
RoundedCornerShape(40.dp)
), painter = painterResource(id = R.drawable.default_avatar), contentDescription = ""
)
}
@Composable
fun VideoBtn(@DrawableRes icon: Int, text: String){
Column (
modifier = Modifier.padding(bottom = 16.dp),
fun VideoBtn(@DrawableRes icon: Int, text: String, onClick: (() -> Unit)? = null) {
Column(
modifier = Modifier
.padding(bottom = 16.dp)
.clickable {
onClick?.invoke()
},
horizontalAlignment = Alignment.CenterHorizontally,
){
Image(modifier = Modifier.size(36.dp), painter = painterResource(id = icon), contentDescription = "")
Text(text = text,fontSize = 11.sp, color = Color.White, style = TextStyle(fontWeight = FontWeight.Bold))
) {
Image(
modifier = Modifier.size(36.dp),
painter = painterResource(id = icon),
contentDescription = ""
)
Text(
text = text,
fontSize = 11.sp,
color = Color.White,
style = TextStyle(fontWeight = FontWeight.Bold)
)
}
}

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.index.tabs.street
import android.content.pm.PackageManager
import androidx.activity.compose.rememberLauncherForActivityResult
@@ -41,6 +41,10 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
import androidx.navigation.NavOptions
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
import com.aiosman.riderpro.test.countries
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.model.CameraPosition
@@ -80,6 +84,7 @@ fun StreetPage() {
}
}
)
LaunchedEffect(Unit) {
when (PackageManager.PERMISSION_GRANTED) {
ContextCompat.checkSelfPermission(
@@ -88,7 +93,7 @@ fun StreetPage() {
) -> {
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
if (location != null) {
currentLocation = LatLng(location.latitude, location.longitude)
// currentLocation = LatLng(location.latitude, location.longitude)
}
}
hasLocationPermission = true
@@ -100,11 +105,20 @@ fun StreetPage() {
}
}
LaunchedEffect(currentLocation) {
cameraPositionState.position =
CameraPosition.fromLatLngZoom(currentLocation ?: LatLng(0.0, 0.0), 10f)
CameraPosition.fromLatLngZoom(
currentLocation ?: LatLng(
countries[0].lat,
countries[0].lng
), 5f
)
}
Box(
modifier = Modifier.fillMaxSize().padding(bottom = 56.dp + navigationBarHeight)
modifier = Modifier
.fillMaxSize()
.padding(bottom = 56.dp + navigationBarHeight)
) {
GoogleMap(
modifier = Modifier.fillMaxSize(),
@@ -118,14 +132,24 @@ fun StreetPage() {
zoomControlsEnabled = false
)
) {
// pins
countries.forEach { position ->
MarkerComposable(
state = MarkerState(position = LatLng(position.lat, position.lng)),
onClick = { it ->
navController.navigate("LocationDetail")
onClick = {
val screenLocation =
cameraPositionState.projection?.toScreenLocation(it.position)
val x = screenLocation?.x ?: 0
val y = screenLocation?.y ?: 0
navController.navigate("LocationDetail/${x}/${y}",NavOptions.Builder()
.setEnterAnim(0)
.setExitAnim(0)
.setPopEnterAnim(0)
.setPopExitAnim(0)
.build())
true
}
},
) {
Image(
painter = painterResource(id = R.drawable.rider_pro_map_mark),
@@ -135,19 +159,20 @@ fun StreetPage() {
}
}
Image(
painter = painterResource(id = R.drawable.rider_pro_my_location),
contentDescription = "",
modifier = Modifier
.align(Alignment.BottomStart)
.padding(start = 16.dp, bottom = 16.dp + navigationBarHeight) .clickable(
.padding(start = 16.dp, bottom = 16.dp + navigationBarHeight)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
currentLocation?.let {
cameraPositionState.position = CameraPosition.fromLatLngZoom(it, cameraPositionState.position.zoom)
cameraPositionState.position =
CameraPosition.fromLatLngZoom(it, cameraPositionState.position.zoom)
}
}
)
@@ -167,7 +192,8 @@ fun StreetPage() {
painter = painterResource(id = R.drawable.rider_pro_new_post_add_pic),
contentDescription = "",
modifier = Modifier
.align(Alignment.Center).size(36.dp),
.align(Alignment.Center)
.size(36.dp),
colorFilter = ColorFilter.tint(Color.White)
)
@@ -178,10 +204,12 @@ fun StreetPage() {
modifier = Modifier
.fillMaxWidth()
.align(Alignment.TopCenter)
.padding(top = 64.dp, start = 16.dp,end=16.dp)
.padding(top = 64.dp, start = 16.dp, end = 16.dp)
) {
Box(
modifier = Modifier.background(Color.White).padding(16.dp),
modifier = Modifier
.background(Color.White)
.padding(16.dp),
) {
Box(
modifier = Modifier
@@ -205,7 +233,7 @@ fun StreetPage() {
modifier = Modifier
.fillMaxWidth()
) {
if (searchText.isEmpty()){
if (searchText.isEmpty()) {
Text(
text = "Please enter a search location",
color = Color(0xffc6c6c6),

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.like
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -29,10 +29,14 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.comment.NoticeScreenHeader
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
@Preview
@Composable
fun LikePage() {
fun LikeScreen() {
val model = LikePageViewModel
val coroutineScope = rememberCoroutineScope()
val listState = rememberLazyListState()
@@ -45,10 +49,10 @@ fun LikePage() {
}
}
LaunchedEffect(Unit) {
model.loader.loadData()
LikePageViewModel.loader.loadData()
}
LaunchedEffect(reachedBottom) {
if (reachedBottom) model.loader.loadMore()
if (reachedBottom) LikePageViewModel.loader.loadMore()
}
StatusBarMaskLayout(
darkIcons = true,
@@ -67,7 +71,7 @@ fun LikePage() {
state = listState,
) {
items(model.loader.list, key = { it.id }) {
items(LikePageViewModel.loader.list, key = { it.id }) {
LikeItem(it)
}
item {

View File

@@ -1,9 +1,12 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.like
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.aiosman.riderpro.test.MockDataContainer
import com.aiosman.riderpro.test.MockDataSource
import com.aiosman.riderpro.test.MockListContainer
class LikeDataSource : MockDataSource<LikeItemData>() {
init {

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.location
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
@@ -53,12 +53,14 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
data class OfficialGalleryItem(
val id: Int,
@@ -109,9 +111,8 @@ fun getFeedItems(): List<FeedItem> {
}
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Preview
@Composable
fun LocationDetail() {
fun LocationDetailScreen(x: Float, y: Float) {
val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState(
SheetState(
@@ -137,6 +138,25 @@ fun LocationDetail() {
val peekHeight = (screenHeight * 1 / 3).dp
return peekHeight
}
val view = LocalView.current
// LaunchedEffect(key1 = Unit) {
// val locationOnScreen = IntArray(2).apply {
// view.getLocationOnScreen(this)
// }
// val startX = x - locationOnScreen[0]
// val startY = y - locationOnScreen[1]
// val radius = hypot(view.width.toDouble(), view.height.toDouble()).toFloat()
//
// val anim = ViewAnimationUtils.createCircularReveal(view, startX.toInt(), startY.toInt(), 0f, radius).apply {
// duration = 600
// start()
// }
//
// }
val staggeredGridState = rememberLazyStaggeredGridState()
val coroutineScope = rememberCoroutineScope()
@@ -150,7 +170,7 @@ fun LocationDetail() {
}
Box(
modifier = Modifier.fillMaxSize()
modifier = Modifier.fillMaxSize().background(Color.Transparent)
) {
Image(
painter = painterResource(id = R.drawable.default_moment_img),
@@ -432,4 +452,5 @@ fun GalleryAndInfo(showGalleryAndInfo: Boolean) {
}
}
}
}
}

View File

@@ -1,6 +1,5 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.message
import android.view.RoundedCorner
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -8,8 +7,6 @@ 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.defaultMinSize
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -18,8 +15,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -29,9 +24,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@@ -40,6 +33,10 @@ import androidx.paging.LoadState
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.compose.collectAsLazyPagingItems
import com.aiosman.riderpro.ui.index.tabs.moment.MomentListLoading
import com.aiosman.riderpro.R
import com.aiosman.riderpro.model.ChatNotificationData
import com.aiosman.riderpro.model.TestChatBackend
val chatNotificationData = ChatNotificationData(
R.drawable.default_avatar,
@@ -49,7 +46,7 @@ val chatNotificationData = ChatNotificationData(
6
)
private val ChatData = (0..10).toList().map { chatNotificationData}
private val ChatData = (0..10).toList().map { chatNotificationData }
@Composable
fun MessagePage(){

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.message
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -8,12 +8,9 @@ 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.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -27,12 +24,15 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
import com.google.accompanist.systemuicontroller.rememberSystemUiController

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.modification
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -44,10 +44,14 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.ui.post.NewPostViewModel
import com.aiosman.riderpro.ui.comment.NoticeScreenHeader
import com.aiosman.riderpro.R
import com.aiosman.riderpro.utils.Utils
@Preview
@Composable
fun EditModification() {
fun EditModificationScreen() {
val model = NewPostViewModel
Column(
modifier = Modifier
@@ -62,9 +66,9 @@ fun EditModification() {
LazyColumn(
modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 16.dp)
) {
items(model.modificationList) { mod ->
items(NewPostViewModel.modificationList) { mod ->
AddModificationItem(mod) { updatedMod ->
model.modificationList = model.modificationList.map { existingMod ->
NewPostViewModel.modificationList = NewPostViewModel.modificationList.map { existingMod ->
if (existingMod.key == updatedMod.key) updatedMod else existingMod
}.toMutableList()
}
@@ -72,7 +76,7 @@ fun EditModification() {
}
item {
AddModificationButton {
model.modificationList += Modification(
NewPostViewModel.modificationList += Modification(
key = Utils.generateRandomString(4),
name = "",
price = "0.0"

View File

@@ -17,9 +17,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.BottomNavigationPlaceholder
import com.aiosman.riderpro.NoticeScreenHeader
import com.aiosman.riderpro.StatusBarMaskLayout
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
import com.aiosman.riderpro.ui.comment.NoticeScreenHeader
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.google.accompanist.systemuicontroller.rememberSystemUiController
@Preview

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.modifiers
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.post
import android.app.Activity
import android.content.Intent
@@ -43,6 +43,9 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.google.accompanist.systemuicontroller.rememberSystemUiController
@@ -62,8 +65,8 @@ fun NewPostScreen() {
.fillMaxSize()
) {
NewPostTopBar()
NewPostTextField("Share your adventure…", model.textContent) {
model.textContent = it
NewPostTextField("Share your adventure…", NewPostViewModel.textContent) {
NewPostViewModel.textContent = it
}
AddImageGrid()
AdditionalPostItem()
@@ -223,7 +226,7 @@ fun AdditionalPostItem() {
}
) {
isShowLocationModal = false
model.searchPlaceAddressResult = it
NewPostViewModel.searchPlaceAddressResult = it
}
}
}
@@ -241,9 +244,9 @@ fun AdditionalPostItem() {
onSelectLocationClick()
}
) {
model.searchPlaceAddressResult?.let {
NewPostViewModel.searchPlaceAddressResult?.let {
SelectedLocation(it) {
model.searchPlaceAddressResult = null
NewPostViewModel.searchPlaceAddressResult = null
}
} ?: Row(
verticalAlignment = Alignment.CenterVertically

View File

@@ -1,9 +1,10 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.post
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.aiosman.riderpro.ui.modification.Modification
object NewPostViewModel : ViewModel() {

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.post
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalSharedTransitionApi
@@ -56,6 +56,11 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.LocalAnimatedContentScope
import com.aiosman.riderpro.LocalSharedTransitionScope
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
import kotlinx.coroutines.launch
fun makeMockImages(): List<PostImage> {
@@ -69,7 +74,7 @@ fun makeMockImages(): List<PostImage> {
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun PostPage(
fun PostScreen(
id: String,
) {
var showCollapseContent by remember { mutableStateOf(true) }

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.ui.post
import android.util.Log
import androidx.compose.foundation.Image
@@ -33,10 +33,9 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.aiosman.riderpro.R
import com.google.android.gms.common.api.ApiException
import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.Place
@@ -49,7 +48,10 @@ data class SearchPlaceAddressResult(
)
@Composable
fun SelectLocationModal(onClose:() -> Unit,onSelectedLocation: (SearchPlaceAddressResult) -> Unit) {
fun SelectLocationModal(
onClose: () -> Unit,
onSelectedLocation: (SearchPlaceAddressResult) -> Unit
) {
val context = LocalContext.current
var queryString by remember { mutableStateOf("") }
var searchPlaceAddressResults by remember {
@@ -94,9 +96,11 @@ fun SelectLocationModal(onClose:() -> Unit,onSelectedLocation: (SearchPlaceAddre
)
Text(
"Cancel",
modifier = Modifier.align(Alignment.CenterEnd).clickable {
onClose()
},
modifier = Modifier
.align(Alignment.CenterEnd)
.clickable {
onClose()
},
fontSize = 16.sp
)
}

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro
package com.aiosman.riderpro.utils
object Utils {
fun generateRandomString(length: Int): String {

View File

@@ -20,4 +20,6 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.nonTransitiveRClass=true
org.gradle.daemon=true
ja