Skip to content

Commit c79fe1c

Browse files
committed
[feat] #62 selected video bottom sheet
1 parent a0b947b commit c79fe1c

File tree

8 files changed

+125
-69
lines changed

8 files changed

+125
-69
lines changed

core/designsystem/src/main/java/com/record/designsystem/component/bottomsheet/RecordyBottomSheet.kt

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.record.designsystem.component.bottomsheet
22

33
import androidx.compose.foundation.layout.ColumnScope
4+
import androidx.compose.foundation.layout.WindowInsets
45
import androidx.compose.material3.ExperimentalMaterial3Api
56
import androidx.compose.material3.ModalBottomSheet
67
import androidx.compose.material3.SheetState
@@ -40,6 +41,7 @@ fun RecordyBottomSheet(
4041
},
4142
containerColor = Color(0xFFE8E8E8),
4243
dragHandle = null,
44+
windowInsets = WindowInsets(0, 0, 0, 0),
4345
) {
4446
content()
4547
}

feature/upload/build.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ android {
88

99
dependencies {
1010
implementation("com.google.accompanist:accompanist-permissions:0.34.0")
11+
implementation("com.google.accompanist:accompanist-insets:0.24.13-rc")
12+
implementation("com.google.accompanist:accompanist-systemuicontroller:0.24.13-rc")
1113
implementation(projects.domain.upload)
1214
}

feature/upload/src/main/java/com/record/upload/SelectedVideoScreen.kt

-58
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,21 @@ import android.net.Uri
66
import android.provider.MediaStore
77
import android.util.Log
88
import androidx.compose.foundation.Image
9-
import androidx.compose.foundation.background
109
import androidx.compose.foundation.layout.Box
11-
import androidx.compose.foundation.layout.Column
1210
import androidx.compose.foundation.layout.PaddingValues
1311
import androidx.compose.foundation.layout.fillMaxSize
14-
import androidx.compose.foundation.layout.fillMaxWidth
1512
import androidx.compose.foundation.layout.padding
1613
import androidx.compose.foundation.layout.size
17-
import androidx.compose.foundation.lazy.grid.GridCells
18-
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
19-
import androidx.compose.foundation.lazy.grid.items
20-
import androidx.compose.material3.Text
2114
import androidx.compose.runtime.Composable
22-
import androidx.compose.ui.Alignment
2315
import androidx.compose.ui.Modifier
2416
import androidx.compose.ui.draw.clip
2517
import androidx.compose.ui.graphics.RectangleShape
2618
import androidx.compose.ui.layout.ContentScale
2719
import androidx.compose.ui.platform.LocalContext
28-
import androidx.compose.ui.text.style.TextAlign
29-
import androidx.compose.ui.tooling.preview.Preview
3020
import androidx.compose.ui.unit.dp
3121
import coil.ImageLoader
3222
import coil.compose.rememberAsyncImagePainter
3323
import coil.decode.VideoFrameDecoder
34-
import com.record.designsystem.component.button.RecordyButton
35-
import com.record.designsystem.component.navbar.TopNavigationBar
36-
import com.record.designsystem.theme.Background
37-
import com.record.designsystem.theme.Gray03
38-
import com.record.designsystem.theme.RecordyTheme
3924

4025
@Composable
4126
fun SelectedVideoRoute(
@@ -51,40 +36,6 @@ fun SelectedVideoScreen(
5136
) {
5237
Log.d("images", "${getAllVideos(10, null, LocalContext.current)}")
5338
val a = getAllVideos(10, null, LocalContext.current)
54-
Box(
55-
modifier = Modifier
56-
.fillMaxSize()
57-
.background(Background),
58-
) {
59-
Column(
60-
modifier = Modifier
61-
.align(Alignment.TopCenter),
62-
) {
63-
TopNavigationBar(title = "영상 선택", enableGradation = true)
64-
Text(
65-
text = "ⓘ 1080p 이하의 최대 15초 영상을 올려주세요.",
66-
color = Gray03,
67-
style = RecordyTheme.typography.caption2,
68-
maxLines = 1,
69-
modifier = Modifier.fillMaxWidth(),
70-
textAlign = TextAlign.Center,
71-
)
72-
LazyVerticalGrid(
73-
columns = GridCells.Fixed(4),
74-
modifier = Modifier.padding(8.dp),
75-
) {
76-
items(a) { video ->
77-
VideoThumbnail(video = video)
78-
}
79-
}
80-
}
81-
RecordyButton(
82-
modifier = Modifier.align(Alignment.BottomCenter),
83-
text = "다음",
84-
enabled = true,
85-
onClick = {},
86-
)
87-
}
8839
}
8940

9041
@Composable
@@ -117,15 +68,6 @@ fun VideoThumbnail(video: GalleryVideo) {
11768
)
11869
}
11970
}
120-
121-
@Preview
122-
@Composable
123-
fun SelectedVideoScreenPreview() {
124-
RecordyTheme {
125-
VideoPickerScreen(navigateSelectedVideo = { /*TODO*/ })
126-
}
127-
}
128-
12971
fun getAllVideos(
13072
loadSize: Int,
13173
currentLocation: String?,

feature/upload/src/main/java/com/record/upload/UploadContract.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.record.ui.base.UiState
55

66
data class UploadState(
77
val showShouldShowRationaleDialog: Boolean = false,
8+
val isSelectedVideoSheetOpen: Boolean = false,
89
) : UiState
910

10-
sealed interface UploadSideEffect : SideEffect {
11-
}
11+
sealed interface UploadSideEffect : SideEffect

feature/upload/src/main/java/com/record/upload/UploadViewModel.kt

+8
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@ class UploadViewModel @Inject constructor() :
1414
fun hideShouldShowRationaleDialog() = intent {
1515
copy(showShouldShowRationaleDialog = false)
1616
}
17+
18+
fun showIsSelectedVideoSheetOpen() = intent {
19+
copy(isSelectedVideoSheetOpen = true)
20+
}
21+
22+
fun hideIsSelectedVideoSheetOpen() = intent {
23+
copy(isSelectedVideoSheetOpen = false)
24+
}
1725
}

feature/upload/src/main/java/com/record/upload/VideoPickerScreen.kt

+18-9
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import android.content.Intent
66
import android.net.Uri
77
import android.os.Build
88
import android.provider.Settings
9-
import android.util.Log
109
import androidx.activity.compose.rememberLauncherForActivityResult
1110
import androidx.activity.result.contract.ActivityResultContracts
1211
import androidx.annotation.RequiresApi
@@ -23,7 +22,9 @@ import androidx.compose.foundation.layout.padding
2322
import androidx.compose.foundation.rememberScrollState
2423
import androidx.compose.foundation.shape.RoundedCornerShape
2524
import androidx.compose.foundation.verticalScroll
25+
import androidx.compose.material3.ExperimentalMaterial3Api
2626
import androidx.compose.material3.Text
27+
import androidx.compose.material3.rememberModalBottomSheetState
2728
import androidx.compose.runtime.Composable
2829
import androidx.compose.runtime.getValue
2930
import androidx.compose.runtime.mutableStateOf
@@ -52,12 +53,12 @@ import com.record.designsystem.theme.Background
5253
import com.record.designsystem.theme.RecordyTheme
5354
import com.record.ui.extension.customClickable
5455
import com.record.ui.lifecycle.LaunchedEffectWithLifecycle
56+
import com.record.upload.component.bottomsheet.SelectedVideoBottomSheet
5557
import kotlinx.coroutines.flow.collectLatest
5658
import kotlinx.coroutines.launch
5759
import timber.log.Timber
5860

5961
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
60-
@OptIn(ExperimentalPermissionsApi::class)
6162
@Composable
6263
fun VideoPickerRoute(
6364
paddingValues: PaddingValues,
@@ -72,26 +73,28 @@ fun VideoPickerRoute(
7273

7374
VideoPickerScreen(
7475
state = state,
75-
navigateSelectedVideo = navigateSelectedVideo,
7676
onClickKeyword = {},
7777
showShouldShowRationaleDialog = viewModel::showShouldShowRationaleDialog,
7878
hideShouldShowRationaleDialog = viewModel::hideShouldShowRationaleDialog,
79+
showIsSelectedVideoSheetOpen = viewModel::showIsSelectedVideoSheetOpen,
80+
hideIsSelectedVideoSheetOpen = viewModel::hideIsSelectedVideoSheetOpen,
7981
)
8082
}
8183

8284
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
83-
@OptIn(ExperimentalPermissionsApi::class)
85+
@OptIn(ExperimentalPermissionsApi::class, ExperimentalMaterial3Api::class)
8486
@Composable
8587
fun VideoPickerScreen(
8688
state: UploadState = UploadState(),
87-
navigateSelectedVideo: () -> Unit,
8889
onClickKeyword: () -> Unit = {},
8990
showShouldShowRationaleDialog: () -> Unit = {},
9091
hideShouldShowRationaleDialog: () -> Unit = {},
92+
showIsSelectedVideoSheetOpen: () -> Unit = {},
93+
hideIsSelectedVideoSheetOpen: () -> Unit = {},
9194
) {
9295
val context = LocalContext.current
9396
val cameraPermissionState = rememberPermissionState(Manifest.permission.READ_MEDIA_VIDEO)
94-
97+
val exampleVideoList = getAllVideos(10, null, context)
9598
val requestPermissionLauncher = rememberLauncherForActivityResult(
9699
ActivityResultContracts.RequestPermission(),
97100
) { isGranted ->
@@ -136,7 +139,7 @@ fun VideoPickerScreen(
136139
.customClickable(
137140
onClick = {
138141
if (cameraPermissionState.status.isGranted) {
139-
navigateSelectedVideo()
142+
showIsSelectedVideoSheetOpen()
140143
return@customClickable
141144
}
142145
if (cameraPermissionState.status.shouldShowRationale) {
@@ -240,6 +243,12 @@ fun VideoPickerScreen(
240243
},
241244
)
242245
}
246+
SelectedVideoBottomSheet(
247+
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
248+
isSheetOpen = state.isSelectedVideoSheetOpen,
249+
onDismissRequest = hideIsSelectedVideoSheetOpen,
250+
galleyVideos = exampleVideoList,
251+
)
243252
}
244253
}
245254

@@ -248,7 +257,7 @@ fun VideoPickerScreen(
248257
@Composable
249258
fun VideoPickerScreenPreview() {
250259
RecordyTheme {
251-
VideoPickerScreen(navigateSelectedVideo = { /*TODO*/ })
260+
VideoPickerScreen()
252261
}
253262
}
254263

@@ -257,4 +266,4 @@ fun openAppSettings(context: Context) {
257266
data = Uri.fromParts("package", context.packageName, null)
258267
}
259268
context.startActivity(intent)
260-
}
269+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.record.upload.component.bottomsheet
2+
3+
import androidx.compose.material3.ExperimentalMaterial3Api
4+
import androidx.compose.material3.SheetState
5+
import androidx.compose.material3.rememberModalBottomSheetState
6+
import androidx.compose.runtime.Composable
7+
8+
@OptIn(ExperimentalMaterial3Api::class)
9+
@Composable
10+
fun DefinedContentBottomSheet(
11+
sheetState: SheetState = rememberModalBottomSheetState(),
12+
isSheetOpen: Boolean,
13+
onDismissRequest: () -> Unit,
14+
) {
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.record.upload.component.bottomsheet
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Box
5+
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.fillMaxSize
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.foundation.lazy.grid.GridCells
10+
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
11+
import androidx.compose.foundation.lazy.grid.items
12+
import androidx.compose.material3.ExperimentalMaterial3Api
13+
import androidx.compose.material3.SheetState
14+
import androidx.compose.material3.Text
15+
import androidx.compose.material3.rememberModalBottomSheetState
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.ui.Alignment
18+
import androidx.compose.ui.Modifier
19+
import androidx.compose.ui.text.style.TextAlign
20+
import androidx.compose.ui.unit.dp
21+
import com.record.designsystem.component.bottomsheet.RecordyBottomSheet
22+
import com.record.designsystem.component.button.RecordyButton
23+
import com.record.designsystem.component.navbar.TopNavigationBar
24+
import com.record.designsystem.theme.Background
25+
import com.record.designsystem.theme.Gray03
26+
import com.record.designsystem.theme.RecordyTheme
27+
import com.record.upload.GalleryVideo
28+
import com.record.upload.VideoThumbnail
29+
30+
@OptIn(ExperimentalMaterial3Api::class)
31+
@Composable
32+
fun SelectedVideoBottomSheet(
33+
sheetState: SheetState = rememberModalBottomSheetState(),
34+
isSheetOpen: Boolean,
35+
onDismissRequest: () -> Unit,
36+
galleyVideos: List<GalleryVideo>,
37+
) {
38+
RecordyBottomSheet(
39+
isSheetOpen = isSheetOpen,
40+
sheetState = sheetState,
41+
onDismissRequest = onDismissRequest,
42+
) {
43+
Box(
44+
modifier = Modifier
45+
.fillMaxSize()
46+
.background(Background),
47+
) {
48+
Column(
49+
modifier = Modifier
50+
.align(Alignment.TopCenter),
51+
) {
52+
TopNavigationBar(title = "영상 선택", enableGradation = true)
53+
Text(
54+
text = "ⓘ 1080p 이하의 최대 15초 영상을 올려주세요.",
55+
color = Gray03,
56+
style = RecordyTheme.typography.caption2,
57+
maxLines = 1,
58+
modifier = Modifier.fillMaxWidth(),
59+
textAlign = TextAlign.Center,
60+
)
61+
LazyVerticalGrid(
62+
columns = GridCells.Fixed(4),
63+
modifier = Modifier.padding(8.dp),
64+
) {
65+
items(galleyVideos) { video ->
66+
VideoThumbnail(video = video)
67+
}
68+
}
69+
}
70+
RecordyButton(
71+
modifier = Modifier.align(Alignment.BottomCenter),
72+
text = "다음",
73+
enabled = true,
74+
onClick = {},
75+
)
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)