更改目录结构
This commit is contained in:
@@ -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
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,16 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro
|
||||||
|
|
||||||
import ModificationListScreen
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.compose.animation.AnimatedContentScope
|
import androidx.compose.animation.AnimatedContentScope
|
||||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||||
import androidx.compose.animation.SharedTransitionLayout
|
|
||||||
import androidx.compose.animation.SharedTransitionScope
|
import androidx.compose.animation.SharedTransitionScope
|
||||||
import androidx.compose.animation.animateColorAsState
|
import androidx.compose.animation.animateColorAsState
|
||||||
import androidx.compose.animation.core.tween
|
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.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.navigationBars
|
import androidx.compose.foundation.layout.navigationBars
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@@ -27,27 +21,18 @@ import androidx.compose.material3.NavigationBar
|
|||||||
import androidx.compose.material3.NavigationBarItem
|
import androidx.compose.material3.NavigationBarItem
|
||||||
import androidx.compose.material3.NavigationBarItemColors
|
import androidx.compose.material3.NavigationBarItemColors
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.compositionLocalOf
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.navigation.NavHostController
|
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.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
import com.aiosman.riderpro.ui.Navigation
|
||||||
import androidx.navigation.navArgument
|
import com.aiosman.riderpro.ui.index.NavigationItem
|
||||||
import com.aiosman.riderpro.ui.theme.RiderProTheme
|
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.google.android.libraries.places.api.Places
|
import com.google.android.libraries.places.api.Places
|
||||||
|
|
||||||
@@ -79,98 +64,6 @@ val LocalAnimatedContentScope = compositionLocalOf<AnimatedContentScope> {
|
|||||||
error("AnimatedContentScope not provided")
|
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
|
||||||
@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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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>
|
||||||
|
)
|
||||||
@@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,21 +1,16 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.exp
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.RelativeLayout
|
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.ColorRes
|
|
||||||
//import androidx.appcompat.app.AppCompatActivity
|
//import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
|
|
||||||
private const val COLOR_TRANSPARENT = 0
|
private const val COLOR_TRANSPARENT = 0
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.model
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.model
|
||||||
|
|
||||||
import androidx.paging.PagingSource
|
import androidx.paging.PagingSource
|
||||||
import androidx.paging.PagingState
|
import androidx.paging.PagingState
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.model
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
|
import com.aiosman.riderpro.R
|
||||||
|
|
||||||
data class MomentItem(
|
data class MomentItem(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.test
|
||||||
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.test
|
||||||
|
|
||||||
import androidx.paging.PagingSource
|
import androidx.paging.PagingSource
|
||||||
import androidx.paging.PagingState
|
import androidx.paging.PagingState
|
||||||
|
import com.aiosman.riderpro.model.MomentItem
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.test
|
||||||
|
|
||||||
data class StreetPosition(
|
data class StreetPosition(
|
||||||
val name:String,
|
val name:String,
|
||||||
156
app/src/main/java/com/aiosman/riderpro/ui/Navi.kt
Normal file
156
app/src/main/java/com/aiosman/riderpro/ui/Navi.kt
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.comment
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.aiosman.riderpro.ui.post.CommentsSection
|
||||||
|
import com.aiosman.riderpro.R
|
||||||
|
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@@ -53,7 +55,7 @@ fun CommentModalContent(onDismiss: () -> Unit = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.height(500.dp)
|
modifier = Modifier
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.comment
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.composables
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.composables
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.areNavigationBarsVisible
|
|
||||||
import androidx.compose.foundation.layout.asPaddingValues
|
import androidx.compose.foundation.layout.asPaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.follower
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Box
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun FollowerPage() {
|
fun FollowerScreen() {
|
||||||
StatusBarMaskLayout(
|
StatusBarMaskLayout(
|
||||||
modifier = Modifier.padding(horizontal = 16.dp)
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
) {
|
) {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.gallery
|
||||||
|
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.aiosman.riderpro.R
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun GalleryPage() {
|
fun ProfileTimelineScreen() {
|
||||||
val pagerState = rememberPagerState(pageCount = { 2 })
|
val pagerState = rememberPagerState(pageCount = { 2 })
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val systemUiController = rememberSystemUiController()
|
val systemUiController = rememberSystemUiController()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.gallery
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun OfficialGalleryPage() {
|
fun OfficialGalleryScreen() {
|
||||||
StatusBarMaskLayout {
|
StatusBarMaskLayout {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.gallery
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.foundation.Image
|
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.material.icons.filled.Favorite
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@@ -38,12 +37,16 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
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 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(
|
data class ArtWork(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
@@ -69,7 +72,7 @@ fun GenerateMockArtWorks(): List<ArtWork> {
|
|||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun OfficialPhotographer() {
|
fun OfficialPhotographerScreen() {
|
||||||
val lazyListState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
var artWorks by remember { mutableStateOf<List<ArtWork>>(emptyList()) }
|
var artWorks by remember { mutableStateOf<List<ArtWork>>(emptyList()) }
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
@@ -135,7 +138,7 @@ fun OfficialPhotographer() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
.align(alignment = androidx.compose.ui.Alignment.BottomCenter)
|
.align(alignment = Alignment.BottomCenter)
|
||||||
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
@@ -257,11 +260,11 @@ fun OfficialPhotographer() {
|
|||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
verticalAlignment = androidx.compose.ui.Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.drawable.rider_pro_nav_back),
|
painter = painterResource(id = R.drawable.rider_pro_nav_back),
|
||||||
colorFilter = androidx.compose.ui.graphics.ColorFilter.tint(Color.White),
|
colorFilter = ColorFilter.tint(Color.White),
|
||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(32.dp)
|
.size(32.dp)
|
||||||
209
app/src/main/java/com/aiosman/riderpro/ui/index/Index.kt
Normal file
209
app/src/main/java/com/aiosman/riderpro/ui/index/Index.kt
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.index
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -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.runtime.Composable
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
|
import com.aiosman.riderpro.R
|
||||||
|
|
||||||
sealed class NavigationItem(
|
sealed class NavigationItem(
|
||||||
val route: String,
|
val route: String,
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.index.tabs.add
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
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.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
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.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.focusModifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.aiosman.riderpro.LocalNavController
|
||||||
|
import com.aiosman.riderpro.ui.post.NewPostViewModel
|
||||||
|
import com.aiosman.riderpro.R
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AddPage(){
|
fun AddPage(){
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.index.tabs.moment
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
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.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
|
|
||||||
private val DATA = (0..60).toList().mapIndexed { idx, _ ->
|
private val DATA = (0..60).toList().mapIndexed { idx, _ ->
|
||||||
@@ -63,41 +72,16 @@ private val DATA = (0..60).toList().mapIndexed { idx, _ ->
|
|||||||
|
|
||||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PagingBackendSample() {
|
fun MomentsList() {
|
||||||
|
val model = MomentViewModel
|
||||||
// val myBackend = remember { TestBackend(DATA) }
|
val moments = model.momentsFlow.collectAsLazyPagingItems()
|
||||||
// val pager = remember {
|
|
||||||
// Pager(
|
|
||||||
// PagingConfig(
|
|
||||||
// pageSize = myBackend.DataBatchSize,
|
|
||||||
// enablePlaceholders = true,
|
|
||||||
// maxSize = 200
|
|
||||||
// )
|
|
||||||
// ) {
|
|
||||||
// myBackend.getAllData()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
val model = HomeViewModel
|
|
||||||
// val lazyPagingItems = model.pager.collectAsLazyPagingItems()
|
|
||||||
|
|
||||||
LazyColumn {
|
LazyColumn {
|
||||||
// if (lazyPagingItems.loadState.refresh == LoadState.Loading) {
|
items(moments.itemCount) { idx ->
|
||||||
// item {
|
val momentItem = moments[idx] ?: return@items
|
||||||
// MomentListLoading()
|
MomentCard(momentItem = momentItem)
|
||||||
// }
|
|
||||||
// }
|
|
||||||
items(count = model.momentList.size) { index ->
|
|
||||||
val item = model.momentList.getOrNull(index)
|
|
||||||
if (item != null) {
|
|
||||||
MomentCard(item)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// if (lazyPagingItems.loadState.append == LoadState.Loading) {
|
|
||||||
// item {
|
|
||||||
// MomentListLoading()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
@@ -124,7 +108,7 @@ fun MomentCard(
|
|||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
ModificationListHeader()
|
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)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun MomentBottomOperateRowGroup(modifier: Modifier) {
|
fun MomentBottomOperateRowGroup(modifier: Modifier, momentItem: MomentItem) {
|
||||||
var systemUiController = rememberSystemUiController()
|
var systemUiController = rememberSystemUiController()
|
||||||
var showCommentModal by remember { mutableStateOf(false) }
|
var showCommentModal by remember { mutableStateOf(false) }
|
||||||
if (showCommentModal) {
|
if (showCommentModal) {
|
||||||
@@ -340,7 +339,14 @@ fun MomentBottomOperateRowGroup(modifier: Modifier) {
|
|||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
contentAlignment = Alignment.Center
|
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(
|
Box(
|
||||||
modifier = modifier.clickable(
|
modifier = modifier.clickable(
|
||||||
@@ -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
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.index.tabs.profile
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.compose.foundation.Image
|
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.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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
|
@Composable
|
||||||
@@ -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.animation.core.Animatable
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
import androidx.compose.foundation.gestures.Orientation
|
||||||
import androidx.compose.foundation.gestures.draggable
|
import androidx.compose.foundation.gestures.draggable
|
||||||
import androidx.compose.foundation.gestures.rememberDraggableState
|
import androidx.compose.foundation.gestures.rememberDraggableState
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -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.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import com.aiosman.riderpro.ShortViewCompose
|
|
||||||
import com.aiosman.riderpro.ui.theme.RiderProTheme
|
import com.aiosman.riderpro.ui.theme.RiderProTheme
|
||||||
|
|
||||||
val videoUrls = listOf(
|
val videoUrls = listOf(
|
||||||
@@ -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.net.Uri
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
@@ -9,6 +11,7 @@ import androidx.annotation.OptIn
|
|||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
import androidx.compose.foundation.gestures.Orientation
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
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.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.rememberModalBottomSheetState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@@ -59,22 +65,25 @@ import androidx.media3.exoplayer.ExoPlayer
|
|||||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource
|
import androidx.media3.exoplayer.source.ProgressiveMediaSource
|
||||||
import androidx.media3.ui.AspectRatioFrameLayout
|
import androidx.media3.ui.AspectRatioFrameLayout
|
||||||
import androidx.media3.ui.PlayerView
|
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.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ShortViewCompose(
|
fun ShortViewCompose(
|
||||||
videoItemsUrl:List<String>,
|
videoItemsUrl: List<String>,
|
||||||
clickItemPosition:Int = 0,
|
clickItemPosition: Int = 0,
|
||||||
videoHeader:@Composable () -> Unit = {},
|
videoHeader: @Composable () -> Unit = {},
|
||||||
videoBottom:@Composable () -> Unit = {}
|
videoBottom: @Composable () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val pagerState: PagerState = run {
|
val pagerState: PagerState = run {
|
||||||
remember {
|
remember {
|
||||||
PagerState(clickItemPosition, 0, videoItemsUrl.size - 1)
|
PagerState(clickItemPosition, 0, videoItemsUrl.size - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val initialLayout= remember {
|
val initialLayout = remember {
|
||||||
mutableStateOf(true)
|
mutableStateOf(true)
|
||||||
}
|
}
|
||||||
val pauseIconVisibleState = remember {
|
val pauseIconVisibleState = remember {
|
||||||
@@ -85,19 +94,21 @@ fun ShortViewCompose(
|
|||||||
orientation = Orientation.Vertical,
|
orientation = Orientation.Vertical,
|
||||||
offscreenLimit = 1
|
offscreenLimit = 1
|
||||||
) {
|
) {
|
||||||
pauseIconVisibleState.value=false
|
pauseIconVisibleState.value = false
|
||||||
SingleVideoItemContent(videoItemsUrl[page],
|
SingleVideoItemContent(
|
||||||
|
videoItemsUrl[page],
|
||||||
pagerState,
|
pagerState,
|
||||||
page,
|
page,
|
||||||
initialLayout,
|
initialLayout,
|
||||||
pauseIconVisibleState,
|
pauseIconVisibleState,
|
||||||
videoHeader,
|
videoHeader,
|
||||||
videoBottom)
|
videoBottom
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(clickItemPosition){
|
LaunchedEffect(clickItemPosition) {
|
||||||
delay(300)
|
delay(300)
|
||||||
initialLayout.value=false
|
initialLayout.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -112,16 +123,18 @@ private fun SingleVideoItemContent(
|
|||||||
VideoHeader: @Composable() () -> Unit,
|
VideoHeader: @Composable() () -> Unit,
|
||||||
VideoBottom: @Composable() () -> Unit,
|
VideoBottom: @Composable() () -> Unit,
|
||||||
) {
|
) {
|
||||||
Box(modifier = Modifier.fillMaxSize()){
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
VideoPlayer(videoUrl,pagerState,pager,pauseIconVisibleState)
|
VideoPlayer(videoUrl, pagerState, pager, pauseIconVisibleState)
|
||||||
VideoHeader.invoke()
|
VideoHeader.invoke()
|
||||||
Box(modifier = Modifier.align(Alignment.BottomStart)){
|
Box(modifier = Modifier.align(Alignment.BottomStart)) {
|
||||||
VideoBottom.invoke()
|
VideoBottom.invoke()
|
||||||
}
|
}
|
||||||
if (initialLayout.value) {
|
if (initialLayout.value) {
|
||||||
Box(modifier = Modifier
|
Box(
|
||||||
.fillMaxSize()
|
modifier = Modifier
|
||||||
.background(color = Color.Black))
|
.fillMaxSize()
|
||||||
|
.background(color = Color.Black)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,9 +148,12 @@ fun VideoPlayer(
|
|||||||
pauseIconVisibleState: MutableState<Boolean>,
|
pauseIconVisibleState: MutableState<Boolean>,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope= rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val lifecycleOwner = LocalLifecycleOwner.current
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
|
var showCommentModal by remember { mutableStateOf(false) }
|
||||||
|
var sheetState = rememberModalBottomSheetState(
|
||||||
|
skipPartiallyExpanded = true
|
||||||
|
)
|
||||||
val exoPlayer = remember {
|
val exoPlayer = remember {
|
||||||
ExoPlayer.Builder(context)
|
ExoPlayer.Builder(context)
|
||||||
.build()
|
.build()
|
||||||
@@ -160,8 +176,12 @@ fun VideoPlayer(
|
|||||||
}
|
}
|
||||||
exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
|
exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
|
||||||
exoPlayer.repeatMode = Player.REPEAT_MODE_ONE
|
exoPlayer.repeatMode = Player.REPEAT_MODE_ONE
|
||||||
Box(modifier = Modifier.fillMaxSize(),
|
// player box
|
||||||
contentAlignment = Alignment.TopCenter) {
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.TopCenter
|
||||||
|
) {
|
||||||
var playerView by remember { mutableStateOf<PlayerView?>(null) } // Store reference to PlayerView
|
var playerView by remember { mutableStateOf<PlayerView?>(null) } // Store reference to PlayerView
|
||||||
|
|
||||||
AndroidView(
|
AndroidView(
|
||||||
@@ -176,7 +196,8 @@ fun VideoPlayer(
|
|||||||
hideController()
|
hideController()
|
||||||
useController = false
|
useController = false
|
||||||
player = exoPlayer
|
player = exoPlayer
|
||||||
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT // 或 RESIZE_MODE_ZOOM
|
resizeMode =
|
||||||
|
AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT // 或 RESIZE_MODE_ZOOM
|
||||||
layoutParams = FrameLayout.LayoutParams(
|
layoutParams = FrameLayout.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
@@ -226,11 +247,13 @@ fun VideoPlayer(
|
|||||||
Lifecycle.Event.ON_PAUSE -> {
|
Lifecycle.Event.ON_PAUSE -> {
|
||||||
exoPlayer.pause() // 应用进入后台时暂停
|
exoPlayer.pause() // 应用进入后台时暂停
|
||||||
}
|
}
|
||||||
|
|
||||||
Lifecycle.Event.ON_RESUME -> {
|
Lifecycle.Event.ON_RESUME -> {
|
||||||
if (pager == pagerState.currentPage) {
|
if (pager == pagerState.currentPage) {
|
||||||
exoPlayer.play() // 返回前台且为当前页面时恢复播放
|
exoPlayer.play() // 返回前台且为当前页面时恢复播放
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,29 +266,58 @@ fun VideoPlayer(
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Box(modifier = Modifier.fillMaxSize(),
|
// action buttons
|
||||||
contentAlignment = Alignment.BottomEnd){
|
Box(
|
||||||
Column (modifier = Modifier.padding(bottom = 72.dp, end = 12.dp),
|
modifier = Modifier.fillMaxSize(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally){
|
contentAlignment = Alignment.BottomEnd
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(bottom = 72.dp, end = 12.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
UserAvatar()
|
UserAvatar()
|
||||||
VideoBtn(icon = R.drawable.rider_pro_video_like, text = "975.9k")
|
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_favor, text = "234")
|
||||||
VideoBtn(icon = R.drawable.rider_pro_video_share, text = "677k")
|
VideoBtn(icon = R.drawable.rider_pro_video_share, text = "677k")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// info
|
||||||
Box(modifier = Modifier.fillMaxSize(),
|
Box(
|
||||||
contentAlignment = Alignment.BottomStart){
|
modifier = Modifier.fillMaxSize(),
|
||||||
Column (modifier = Modifier.padding(start = 16.dp, bottom = 16.dp)){
|
contentAlignment = Alignment.BottomStart
|
||||||
Row (modifier = Modifier.padding(bottom = 8.dp).background(color = Color.Gray),
|
) {
|
||||||
|
Column(modifier = Modifier.padding(start = 16.dp, bottom = 16.dp)) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
|
.background(color = Color.Gray),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.Start,
|
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 = "")
|
Image(
|
||||||
Text(modifier = Modifier.padding(end = 4.dp),text = "USA",fontSize = 12.sp, color = Color.White, style = TextStyle(fontWeight = FontWeight.Bold))
|
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(
|
Text(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -279,23 +331,54 @@ fun VideoPlayer(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showCommentModal) {
|
||||||
|
ModalBottomSheet(
|
||||||
|
onDismissRequest = { showCommentModal = false },
|
||||||
|
containerColor = Color.White,
|
||||||
|
sheetState = sheetState
|
||||||
|
) {
|
||||||
|
CommentModalContent() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserAvatar(){
|
fun UserAvatar() {
|
||||||
Image(modifier = Modifier.padding(bottom = 16.dp).size(40.dp).border(width = 3.dp, color = Color.White, shape = RoundedCornerShape(40.dp)).clip(
|
Image(
|
||||||
RoundedCornerShape(40.dp)
|
modifier = Modifier
|
||||||
), painter = painterResource(id = R.drawable.default_avatar), contentDescription = "")
|
.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
|
@Composable
|
||||||
fun VideoBtn(@DrawableRes icon: Int, text: String){
|
fun VideoBtn(@DrawableRes icon: Int, text: String, onClick: (() -> Unit)? = null) {
|
||||||
Column (
|
Column(
|
||||||
modifier = Modifier.padding(bottom = 16.dp),
|
modifier = Modifier
|
||||||
|
.padding(bottom = 16.dp)
|
||||||
|
.clickable {
|
||||||
|
onClick?.invoke()
|
||||||
|
},
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
){
|
) {
|
||||||
Image(modifier = Modifier.size(36.dp), painter = painterResource(id = icon), contentDescription = "")
|
Image(
|
||||||
Text(text = text,fontSize = 11.sp, color = Color.White, style = TextStyle(fontWeight = FontWeight.Bold))
|
modifier = Modifier.size(36.dp),
|
||||||
|
painter = painterResource(id = icon),
|
||||||
|
contentDescription = ""
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
fontSize = 11.sp,
|
||||||
|
color = Color.White,
|
||||||
|
style = TextStyle(fontWeight = FontWeight.Bold)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.index.tabs.street
|
||||||
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
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.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.core.content.ContextCompat
|
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.FusedLocationProviderClient
|
||||||
import com.google.android.gms.location.LocationServices
|
import com.google.android.gms.location.LocationServices
|
||||||
import com.google.android.gms.maps.model.CameraPosition
|
import com.google.android.gms.maps.model.CameraPosition
|
||||||
@@ -80,6 +84,7 @@ fun StreetPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
when (PackageManager.PERMISSION_GRANTED) {
|
when (PackageManager.PERMISSION_GRANTED) {
|
||||||
ContextCompat.checkSelfPermission(
|
ContextCompat.checkSelfPermission(
|
||||||
@@ -88,7 +93,7 @@ fun StreetPage() {
|
|||||||
) -> {
|
) -> {
|
||||||
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
|
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
currentLocation = LatLng(location.latitude, location.longitude)
|
// currentLocation = LatLng(location.latitude, location.longitude)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hasLocationPermission = true
|
hasLocationPermission = true
|
||||||
@@ -100,11 +105,20 @@ fun StreetPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LaunchedEffect(currentLocation) {
|
LaunchedEffect(currentLocation) {
|
||||||
|
|
||||||
cameraPositionState.position =
|
cameraPositionState.position =
|
||||||
CameraPosition.fromLatLngZoom(currentLocation ?: LatLng(0.0, 0.0), 10f)
|
CameraPosition.fromLatLngZoom(
|
||||||
|
currentLocation ?: LatLng(
|
||||||
|
countries[0].lat,
|
||||||
|
countries[0].lng
|
||||||
|
), 5f
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxSize().padding(bottom = 56.dp + navigationBarHeight)
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(bottom = 56.dp + navigationBarHeight)
|
||||||
) {
|
) {
|
||||||
GoogleMap(
|
GoogleMap(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
@@ -118,14 +132,24 @@ fun StreetPage() {
|
|||||||
zoomControlsEnabled = false
|
zoomControlsEnabled = false
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
// pins
|
||||||
countries.forEach { position ->
|
countries.forEach { position ->
|
||||||
MarkerComposable(
|
MarkerComposable(
|
||||||
state = MarkerState(position = LatLng(position.lat, position.lng)),
|
state = MarkerState(position = LatLng(position.lat, position.lng)),
|
||||||
onClick = { it ->
|
onClick = {
|
||||||
navController.navigate("LocationDetail")
|
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
|
true
|
||||||
}
|
},
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.drawable.rider_pro_map_mark),
|
painter = painterResource(id = R.drawable.rider_pro_map_mark),
|
||||||
@@ -135,19 +159,20 @@ fun StreetPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.drawable.rider_pro_my_location),
|
painter = painterResource(id = R.drawable.rider_pro_my_location),
|
||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomStart)
|
.align(Alignment.BottomStart)
|
||||||
.padding(start = 16.dp, bottom = 16.dp + navigationBarHeight) .clickable(
|
.padding(start = 16.dp, bottom = 16.dp + navigationBarHeight)
|
||||||
|
.clickable(
|
||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
) {
|
) {
|
||||||
currentLocation?.let {
|
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),
|
painter = painterResource(id = R.drawable.rider_pro_new_post_add_pic),
|
||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.Center).size(36.dp),
|
.align(Alignment.Center)
|
||||||
|
.size(36.dp),
|
||||||
colorFilter = ColorFilter.tint(Color.White)
|
colorFilter = ColorFilter.tint(Color.White)
|
||||||
|
|
||||||
)
|
)
|
||||||
@@ -178,10 +204,12 @@ fun StreetPage() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.align(Alignment.TopCenter)
|
.align(Alignment.TopCenter)
|
||||||
.padding(top = 64.dp, start = 16.dp,end=16.dp)
|
.padding(top = 64.dp, start = 16.dp, end = 16.dp)
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.background(Color.White).padding(16.dp),
|
modifier = Modifier
|
||||||
|
.background(Color.White)
|
||||||
|
.padding(16.dp),
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -205,7 +233,7 @@ fun StreetPage() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
if (searchText.isEmpty()){
|
if (searchText.isEmpty()) {
|
||||||
Text(
|
Text(
|
||||||
text = "Please enter a search location",
|
text = "Please enter a search location",
|
||||||
color = Color(0xffc6c6c6),
|
color = Color(0xffc6c6c6),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.like
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun LikePage() {
|
fun LikeScreen() {
|
||||||
val model = LikePageViewModel
|
val model = LikePageViewModel
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
@@ -45,10 +49,10 @@ fun LikePage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
model.loader.loadData()
|
LikePageViewModel.loader.loadData()
|
||||||
}
|
}
|
||||||
LaunchedEffect(reachedBottom) {
|
LaunchedEffect(reachedBottom) {
|
||||||
if (reachedBottom) model.loader.loadMore()
|
if (reachedBottom) LikePageViewModel.loader.loadMore()
|
||||||
}
|
}
|
||||||
StatusBarMaskLayout(
|
StatusBarMaskLayout(
|
||||||
darkIcons = true,
|
darkIcons = true,
|
||||||
@@ -67,7 +71,7 @@ fun LikePage() {
|
|||||||
state = listState,
|
state = listState,
|
||||||
|
|
||||||
) {
|
) {
|
||||||
items(model.loader.list, key = { it.id }) {
|
items(LikePageViewModel.loader.list, key = { it.id }) {
|
||||||
LikeItem(it)
|
LikeItem(it)
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.like
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
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>() {
|
class LikeDataSource : MockDataSource<LikeItemData>() {
|
||||||
init {
|
init {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.location
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.animateContentSize
|
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.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
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.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.aiosman.riderpro.LocalNavController
|
||||||
|
import com.aiosman.riderpro.R
|
||||||
|
|
||||||
data class OfficialGalleryItem(
|
data class OfficialGalleryItem(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
@@ -109,9 +111,8 @@ fun getFeedItems(): List<FeedItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
||||||
@Preview
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LocationDetail() {
|
fun LocationDetailScreen(x: Float, y: Float) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val scaffoldState = rememberBottomSheetScaffoldState(
|
val scaffoldState = rememberBottomSheetScaffoldState(
|
||||||
SheetState(
|
SheetState(
|
||||||
@@ -137,6 +138,25 @@ fun LocationDetail() {
|
|||||||
val peekHeight = (screenHeight * 1 / 3).dp
|
val peekHeight = (screenHeight * 1 / 3).dp
|
||||||
return peekHeight
|
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 staggeredGridState = rememberLazyStaggeredGridState()
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
@@ -150,7 +170,7 @@ fun LocationDetail() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().background(Color.Transparent)
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.drawable.default_moment_img),
|
painter = painterResource(id = R.drawable.default_moment_img),
|
||||||
@@ -433,3 +453,4 @@ fun GalleryAndInfo(showGalleryAndInfo: Boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
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.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
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.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
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.layout.size
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
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.Icon
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.clip
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.vectorResource
|
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -40,6 +33,10 @@ import androidx.paging.LoadState
|
|||||||
import androidx.paging.Pager
|
import androidx.paging.Pager
|
||||||
import androidx.paging.PagingConfig
|
import androidx.paging.PagingConfig
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
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(
|
val chatNotificationData = ChatNotificationData(
|
||||||
R.drawable.default_avatar,
|
R.drawable.default_avatar,
|
||||||
@@ -49,7 +46,7 @@ val chatNotificationData = ChatNotificationData(
|
|||||||
6
|
6
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ChatData = (0..10).toList().map { chatNotificationData}
|
private val ChatData = (0..10).toList().map { chatNotificationData }
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MessagePage(){
|
fun MessagePage(){
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.message
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
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.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
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.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.navigationBars
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
@@ -27,12 +24,15 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
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 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
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
|
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.modification
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun EditModification() {
|
fun EditModificationScreen() {
|
||||||
val model = NewPostViewModel
|
val model = NewPostViewModel
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -62,9 +66,9 @@ fun EditModification() {
|
|||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 16.dp)
|
modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 16.dp)
|
||||||
) {
|
) {
|
||||||
items(model.modificationList) { mod ->
|
items(NewPostViewModel.modificationList) { mod ->
|
||||||
AddModificationItem(mod) { updatedMod ->
|
AddModificationItem(mod) { updatedMod ->
|
||||||
model.modificationList = model.modificationList.map { existingMod ->
|
NewPostViewModel.modificationList = NewPostViewModel.modificationList.map { existingMod ->
|
||||||
if (existingMod.key == updatedMod.key) updatedMod else existingMod
|
if (existingMod.key == updatedMod.key) updatedMod else existingMod
|
||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
}
|
}
|
||||||
@@ -72,7 +76,7 @@ fun EditModification() {
|
|||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
AddModificationButton {
|
AddModificationButton {
|
||||||
model.modificationList += Modification(
|
NewPostViewModel.modificationList += Modification(
|
||||||
key = Utils.generateRandomString(4),
|
key = Utils.generateRandomString(4),
|
||||||
name = "",
|
name = "",
|
||||||
price = "0.0"
|
price = "0.0"
|
||||||
@@ -17,9 +17,9 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
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 androidx.compose.ui.unit.sp
|
||||||
import com.aiosman.riderpro.BottomNavigationPlaceholder
|
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
|
||||||
import com.aiosman.riderpro.NoticeScreenHeader
|
import com.aiosman.riderpro.ui.comment.NoticeScreenHeader
|
||||||
import com.aiosman.riderpro.StatusBarMaskLayout
|
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.modifiers
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.post
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
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.text.font.FontWeight
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
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
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
|
|
||||||
|
|
||||||
@@ -62,8 +65,8 @@ fun NewPostScreen() {
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
NewPostTopBar()
|
NewPostTopBar()
|
||||||
NewPostTextField("Share your adventure…", model.textContent) {
|
NewPostTextField("Share your adventure…", NewPostViewModel.textContent) {
|
||||||
model.textContent = it
|
NewPostViewModel.textContent = it
|
||||||
}
|
}
|
||||||
AddImageGrid()
|
AddImageGrid()
|
||||||
AdditionalPostItem()
|
AdditionalPostItem()
|
||||||
@@ -223,7 +226,7 @@ fun AdditionalPostItem() {
|
|||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
isShowLocationModal = false
|
isShowLocationModal = false
|
||||||
model.searchPlaceAddressResult = it
|
NewPostViewModel.searchPlaceAddressResult = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,9 +244,9 @@ fun AdditionalPostItem() {
|
|||||||
onSelectLocationClick()
|
onSelectLocationClick()
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
model.searchPlaceAddressResult?.let {
|
NewPostViewModel.searchPlaceAddressResult?.let {
|
||||||
SelectedLocation(it) {
|
SelectedLocation(it) {
|
||||||
model.searchPlaceAddressResult = null
|
NewPostViewModel.searchPlaceAddressResult = null
|
||||||
}
|
}
|
||||||
} ?: Row(
|
} ?: Row(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.post
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.aiosman.riderpro.ui.modification.Modification
|
||||||
|
|
||||||
|
|
||||||
object NewPostViewModel : ViewModel() {
|
object NewPostViewModel : ViewModel() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.post
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
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.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
fun makeMockImages(): List<PostImage> {
|
fun makeMockImages(): List<PostImage> {
|
||||||
@@ -69,7 +74,7 @@ fun makeMockImages(): List<PostImage> {
|
|||||||
|
|
||||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PostPage(
|
fun PostScreen(
|
||||||
id: String,
|
id: String,
|
||||||
) {
|
) {
|
||||||
var showCollapseContent by remember { mutableStateOf(true) }
|
var showCollapseContent by remember { mutableStateOf(true) }
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.ui.post
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.foundation.Image
|
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.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
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.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.aiosman.riderpro.R
|
||||||
import com.google.android.gms.common.api.ApiException
|
import com.google.android.gms.common.api.ApiException
|
||||||
import com.google.android.libraries.places.api.Places
|
import com.google.android.libraries.places.api.Places
|
||||||
import com.google.android.libraries.places.api.model.Place
|
import com.google.android.libraries.places.api.model.Place
|
||||||
@@ -49,7 +48,10 @@ data class SearchPlaceAddressResult(
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SelectLocationModal(onClose:() -> Unit,onSelectedLocation: (SearchPlaceAddressResult) -> Unit) {
|
fun SelectLocationModal(
|
||||||
|
onClose: () -> Unit,
|
||||||
|
onSelectedLocation: (SearchPlaceAddressResult) -> Unit
|
||||||
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
var queryString by remember { mutableStateOf("") }
|
var queryString by remember { mutableStateOf("") }
|
||||||
var searchPlaceAddressResults by remember {
|
var searchPlaceAddressResults by remember {
|
||||||
@@ -94,9 +96,11 @@ fun SelectLocationModal(onClose:() -> Unit,onSelectedLocation: (SearchPlaceAddre
|
|||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
"Cancel",
|
"Cancel",
|
||||||
modifier = Modifier.align(Alignment.CenterEnd).clickable {
|
modifier = Modifier
|
||||||
onClose()
|
.align(Alignment.CenterEnd)
|
||||||
},
|
.clickable {
|
||||||
|
onClose()
|
||||||
|
},
|
||||||
fontSize = 16.sp
|
fontSize = 16.sp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.aiosman.riderpro
|
package com.aiosman.riderpro.utils
|
||||||
|
|
||||||
object Utils {
|
object Utils {
|
||||||
fun generateRandomString(length: Int): String {
|
fun generateRandomString(length: Int): String {
|
||||||
@@ -21,3 +21,5 @@ kotlin.code.style=official
|
|||||||
# resources declared in the library itself and none from the library's dependencies,
|
# resources declared in the library itself and none from the library's dependencies,
|
||||||
# thereby reducing the size of the R class for that library
|
# thereby reducing the size of the R class for that library
|
||||||
android.nonTransitiveRClass=true
|
android.nonTransitiveRClass=true
|
||||||
|
org.gradle.daemon=true
|
||||||
|
ja
|
||||||
Reference in New Issue
Block a user