Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

스페이스 추가 화면 Jetpack Compose로 마이그레이션하기 #323

Closed
wants to merge 57 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
c57fa02
refactor: 불필요한 코드 제거
hegleB Jan 8, 2024
7c3edde
chore(#312): kotlin version 1.9.0 -> 1.9.21로 변경
hegleB Jan 12, 2024
d6327fc
chore(#312): compose 활성화
hegleB Jan 12, 2024
0a47dd2
chore(#312): compose option 추가
hegleB Jan 12, 2024
d4be199
chore(#312): compose 관련 라이브러리 추가
hegleB Jan 12, 2024
149577c
feat(#312): Color 추가
hegleB Jan 12, 2024
651da39
feat(#312): Type 추가
hegleB Jan 12, 2024
52e772c
feat(#312): Theme 추가
hegleB Jan 12, 2024
4dab99a
feat(#312): BaseComposeActivity 구현
hegleB Jan 12, 2024
0a1be56
feat(#312): BaseComposeFragment 구현
hegleB Jan 12, 2024
a1aacf9
chore(#312): kotlinc version 1.9.0 -> 1.9.21로 변경
hegleB Jan 12, 2024
56042d0
feat(#313): ProfileTopAppBar UI Compose 구현
hegleB Jan 12, 2024
60bd82e
feat(#313): ProfileImage UI Compose 구현
hegleB Jan 12, 2024
a50e1d1
feat(#313): ProfileNickName UI Compose 구현
hegleB Jan 12, 2024
e404741
feat(#313): NickNameDialog UI Compose 구현
hegleB Jan 12, 2024
ef5fd59
feat(#313): ModifyButton UI Compose 구현
hegleB Jan 12, 2024
38cc021
design(#313): ComposeView로 수정
hegleB Jan 12, 2024
2efb88d
feat(#313): 닉네임 다이얼로그 표시 상태 업데이트
hegleB Jan 12, 2024
ad807a9
feat(#313): ProfileUiEvent None 추가
hegleB Jan 12, 2024
8bf6621
feat(#313): ProfileScreen Compose 추가
hegleB Jan 12, 2024
f615b3e
feat(#313): 뒤로가기 이벤트 상태 업데이트
hegleB Jan 12, 2024
b53430d
style(#313): kotlin 컨벤션에 맞게 수정
hegleB Jan 12, 2024
e4c82f9
refactor(#313): 불필요한 코드 제거
hegleB Jan 15, 2024
5d7eafd
fix(#313): 닉네임 수정 후 취소 버튼을 눌렀을 때 업데이트된 닉네임이 저장되지 않도록 기능 수정
hegleB Jan 15, 2024
ae0608c
feat(#313): UiEvent 추가
hegleB Jan 15, 2024
54790a1
refactor(#313): ProfileContent로 분리
hegleB Jan 15, 2024
3ca1972
refactor(#313): ProfileScreen 파라미터 수정
hegleB Jan 15, 2024
83eb52c
design(#313): 닉네임 기본 색상 및 수정버튼 Text 색상 수정
hegleB Jan 15, 2024
566a03c
Merge pull request #314 from boostcampwm2023/AOS-chore/compose
jaehan4707 Jan 17, 2024
e894877
Merge pull request #315 from boostcampwm2023/AOS-feat/profile-compose
yang1318 Jan 17, 2024
9309c89
feat(#317): BaseActivity,Fragment에 SnackBarMessage 추가하기
jaehan4707 Jan 20, 2024
ef4c678
refactor(#317): RecycleBinUiEvent 개선
jaehan4707 Jan 20, 2024
002a2bf
refactor(#317): SpaceUiEvent 개선
jaehan4707 Jan 20, 2024
962424a
refactor(#317): BoardUiEvent 개선
jaehan4707 Jan 20, 2024
093a1e6
refactor(#317): AddSpaceActivity 개선
jaehan4707 Jan 20, 2024
67b1e71
refactor(#317): BoardListFragment 개선
jaehan4707 Jan 20, 2024
53450be
refactor(#317): ConfirmInviteSpace 개선
jaehan4707 Jan 20, 2024
4308e09
refactor(#317): InputSpaceCode 개선
jaehan4707 Jan 20, 2024
e73c330
refactor(#317): SpaceList 개선
jaehan4707 Jan 20, 2024
1305072
refactor(#317): RecycleBin 개선
jaehan4707 Jan 20, 2024
5aa453d
refactor(#317): MainActivity 개선
jaehan4707 Jan 20, 2024
ebabeaf
refactor(#317): SpaceEvent 제거
jaehan4707 Jan 20, 2024
c5810a1
refactor(#322): AddSpaceUI 구현
jaehan4707 Feb 18, 2024
cc13bda
refactor(#322):Component 분리
jaehan4707 Feb 18, 2024
b042030
refactor(#322):TextField hint, 텍스트 입력 구현
jaehan4707 Feb 18, 2024
fea073d
refactor(#322): 뒤로 가기 구현
jaehan4707 Feb 18, 2024
f7bc2ea
refactor(#322):photoPicker 구현
jaehan4707 Feb 18, 2024
619c876
refactor(#322): 스페이스 추가 구현(그 외 이벤트 처리 미완성)
jaehan4707 Feb 18, 2024
cfae3e9
refactor(#322): imageLauncher 분리, Preview 활성화
jaehan4707 Feb 19, 2024
17897ab
design(#322): placeHolder image 추가
jaehan4707 Feb 19, 2024
6d3a301
refactor(#322): placeHolder,Error 이미지 추가
jaehan4707 Feb 19, 2024
db0ab7c
refactor(#322): Scaffold 적용
jaehan4707 Feb 19, 2024
60d0807
refactor(#322): TextFiled 글자수 카운트 추가
jaehan4707 Feb 19, 2024
1ce76da
refactor(#322): 스페이스 이름에 따른 버튼 enable 처리, enable에 따른 색깔 처리
jaehan4707 Feb 19, 2024
5ec655f
refactor(#322): uiEvent 연결
jaehan4707 Feb 19, 2024
639b86d
style(#322): ktlint 적용
jaehan4707 Mar 3, 2024
3f31545
chore(#322): 기존 AddSpaceActivity 코드 제
jaehan4707 Mar 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AOS/.idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions AOS/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ android {
viewBinding = true
dataBinding = true
buildConfig = true
compose = true
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
Expand All @@ -55,6 +56,9 @@ android {
kotlinOptions {
jvmTarget = "17"
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.7"
}
}

val ktlint by configurations.creating
Expand Down Expand Up @@ -99,6 +103,22 @@ dependencies {
implementation("com.google.android.flexbox:flexbox:3.0.0")
// lottie
implementation("com.airbnb.android:lottie:6.2.0")

// compose
val composePlatform = platform("androidx.compose:compose-bom:2023.10.01")
implementation(composePlatform)
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui")
implementation("androidx.activity:activity-compose:1.8.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.2")
implementation("androidx.navigation:navigation-compose:2.7.6")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.constraintlayout:constraintlayout-compose:1.0.1")
implementation("io.coil-kt:coil-compose:2.5.0")
implementation("com.google.accompanist:accompanist-permissions:0.32.0")
debugImplementation("androidx.compose.ui:ui-tooling")
}

val ktlintCheck by tasks.registering(JavaExec::class) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import boostcamp.and07.mindsync.ui.login.LoginActivity
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

Expand Down Expand Up @@ -52,6 +53,10 @@ abstract class BaseActivity<T : ViewDataBinding>(private val layoutResId: Int) :
finish()
}

fun showMessage(message: String) {
Snackbar.make(this.binding.root, message, Snackbar.LENGTH_LONG).show()
}

override fun onDestroy() {
super.onDestroy()
_binding = null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package boostcamp.and07.mindsync.ui.base

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable

abstract class BaseComposeActivity : ComponentActivity() {

@Composable
abstract fun Content()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Content()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package boostcamp.and07.mindsync.ui.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.Fragment

abstract class BaseComposeFragment : Fragment() {
@Composable
abstract fun Screen()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
Screen()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.Snackbar

abstract class BaseFragment<T : ViewDataBinding>(private val layoutResId: Int) : Fragment() {
private var _binding: T? = null
Expand Down Expand Up @@ -36,4 +38,12 @@ abstract class BaseFragment<T : ViewDataBinding>(private val layoutResId: Int) :
super.onDestroyView()
_binding = null
}

fun setupBackStack() {
findNavController().popBackStack()
}

fun showMessage(message: String) {
Snackbar.make(this.requireView(), message, Snackbar.LENGTH_LONG).show()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import boostcamp.and07.mindsync.databinding.FragmentBoardListBinding
import boostcamp.and07.mindsync.ui.base.BaseFragment
import boostcamp.and07.mindsync.ui.dialog.CreateBoardDialog
import boostcamp.and07.mindsync.ui.util.setClickEvent
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -57,17 +56,9 @@ class BoardListFragment :
repeatOnLifecycle(Lifecycle.State.STARTED) {
boardListViewModel.boardUiEvent.collectLatest { boardEvent ->
when (boardEvent) {
is BoardUiEvent.Success -> {}

is BoardUiEvent.Error -> {
Snackbar.make(
binding.root,
boardEvent.message,
Snackbar.LENGTH_SHORT,
)
.show()
is BoardUiEvent.ShowMessage -> {
showMessage(boardEvent.message)
}

else -> {}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class BoardListViewModel
private val coroutineExceptionHandler =
CoroutineExceptionHandler { _, throwable ->
viewModelScope.launch {
_boardUiEvent.emit(BoardUiEvent.Error(throwable.message.toString()))
_boardUiEvent.emit(BoardUiEvent.ShowMessage(throwable.message.toString()))
}
}

Expand All @@ -55,19 +55,18 @@ class BoardListViewModel
val newBoards = boardUiState.boards.toMutableList().apply { add(board) }
boardUiState.copy(boards = newBoards)
}
_boardUiEvent.emit(BoardUiEvent.Success)
}
}
}

fun getBoards() {
viewModelScope.launch(coroutineExceptionHandler) {
boardListRepository.getBoard(_boardUiState.value.spaceId, false).collectLatest { boards ->
_boardUiState.update { boardUiState ->
boardUiState.copy(boards = boards)
boardListRepository.getBoard(_boardUiState.value.spaceId, false)
.collectLatest { boards ->
_boardUiState.update { boardUiState ->
boardUiState.copy(boards = boards)
}
}
_boardUiEvent.emit(BoardUiEvent.Success)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package boostcamp.and07.mindsync.ui.boardlist

sealed class BoardUiEvent {
data object Success : BoardUiEvent()
data object NavigateToBack : BoardUiEvent()

data class Error(val message: String) : BoardUiEvent()
data class ShowMessage(val message: String) : BoardUiEvent()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package boostcamp.and07.mindsync.ui.dialog

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import boostcamp.and07.mindsync.R
import boostcamp.and07.mindsync.ui.profile.ProfileUiState
import boostcamp.and07.mindsync.ui.theme.Black
import boostcamp.and07.mindsync.ui.theme.Gray4
import boostcamp.and07.mindsync.ui.theme.MindSyncTheme

@Composable
fun NickNameDialog(
uiState: ProfileUiState,
editNickname: (CharSequence) -> Unit,
closeDialog: () -> Unit,
updateNickname: (CharSequence) -> Unit,
) {
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
val dialogWidth = screenWidth * 0.8f
var textFieldValue = remember {
mutableStateOf(
TextFieldValue(
text = uiState.nickname,
selection = TextRange(uiState.nickname.length),
),
)
}
val focusRequester = remember {
FocusRequester()
}

LaunchedEffect(Unit) {
focusRequester.requestFocus()
}

Dialog(
onDismissRequest = {
},
) {
Column(
modifier = Modifier
.background(Color.White, RoundedCornerShape(20.dp))
.width(dialogWidth)
.padding(start = 10.dp, top = 20.dp, end = 10.dp),
) {
Text(
text = stringResource(id = R.string.profile_nickname_modify),
modifier = Modifier,
style = MaterialTheme.typography.displaySmall,
)

OutlinedTextField(
value = textFieldValue.value,
onValueChange = { textFieldValue.value = it; editNickname(it.text) },
modifier = Modifier
.padding(5.dp)
.focusRequester(focusRequester),
placeholder = {
Text(text = stringResource(id = R.string.profile_name_limit))
},
supportingText = {
Text(
text = "${uiState.editingNickname.length}",
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.End,
)
},
textStyle = TextStyle.Default.copy(fontSize = 16.sp),
)
Row(modifier = Modifier.align(Alignment.End)) {
TextButton(
onClick = { closeDialog() },
modifier = Modifier,
) {
Text(
text = stringResource(id = R.string.cancel_message),
color = Black,
fontSize = 14.sp,
)
}

TextButton(
onClick = { updateNickname(uiState.editingNickname); closeDialog() },
modifier = Modifier,
enabled = when (uiState.editingNickname.length) {
in 1..20 -> true
else -> false
},
) {
Text(
text = stringResource(id = R.string.profile_modify),
color = if (uiState.editingNickname.isNotEmpty()) Black else Gray4,
fontSize = 12.sp,
)
}
}
}
}
}

@Preview
@Composable
private fun NickNameDialogPreview() {
MindSyncTheme {
Surface {
NickNameDialog(
uiState = ProfileUiState(),
editNickname = { },
closeDialog = { /*TODO*/ },
updateNickname = { },
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,13 @@ class MainActivity :
repeatOnLifecycle(Lifecycle.State.STARTED) {
mainViewModel.event.collectLatest { event ->
if (event is MainUiEvent.ShowMessage) {
Toast.makeText(this@MainActivity, event.message, Toast.LENGTH_SHORT).show()
showMessage(event.message)
}
if (event is MainUiEvent.GetUsers) {
mainViewModel.getSpaceUsers()
}
if (event is MainUiEvent.LeaveSpace) {
Toast.makeText(
this@MainActivity,
getString(R.string.space_leave_room_message, event.spaceName),
Toast.LENGTH_SHORT,
).show()
showMessage(getString(R.string.space_leave_room_message, event.spaceName))
navController.navigate(R.id.spaceListFragment)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class MainViewModel
}
viewModelScope.launch {
_event.emit(MainUiEvent.ShowMessage("${space.name}방에 참가했습니다."))
_event.emit(MainUiEvent.GetUsers)
getSpaceUsers()
}
}

Expand Down
Loading
Loading