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

주요 이슈들 해결 #78

Merged
merged 12 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions frontend/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
android:theme="@style/Theme.SpeechBuddy"
android:usesCleartextTraffic="true"
android:windowSoftInputMode="adjustResize"
android:enableOnBackInvokedCallback="true"
tools:targetApi="31">
<activity
android:name=".HomeActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ import android.os.Bundle
import android.view.MotionEvent
import android.view.inputmethod.InputMethodManager
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.compose.runtime.mutableStateOf
import androidx.core.view.WindowCompat
import androidx.lifecycle.Observer
import com.example.speechbuddy.compose.SpeechBuddyHome
import com.example.speechbuddy.ui.SpeechBuddyTheme
import com.example.speechbuddy.viewmodel.DisplaySettingsViewModel
Expand Down Expand Up @@ -58,15 +54,14 @@ class HomeActivity : BaseActivity() {
private fun getInitialDarkMode(): Boolean {
return displaySettingsViewModel.getDarkMode()
}

// hides keyboard

override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_DOWN) {
val v = currentFocus
if (v != null) {
v.clearFocus()
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(v.getWindowToken(), 0)
imm.hideSoftInputFromWindow(v.windowToken, 0)
}
}
return super.dispatchTouchEvent(event)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,28 @@ import androidx.annotation.RequiresApi
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -73,9 +79,17 @@ fun SpeechBuddyHome(
)
)

val topAppBarState = rememberSaveable { mutableStateOf(true) }
val bottomNavBarState = rememberSaveable { mutableStateOf(true) }

Scaffold(
topBar = {
TopAppBar(
topAppBarState = topAppBarState,
items = navItems,
navController = navController
)
},
bottomBar = {
BottomNavigationBar(
bottomNavBarState = bottomNavBarState,
Expand All @@ -89,10 +103,55 @@ fun SpeechBuddyHome(
) { paddingValues ->
SpeechBuddyHomeNavHost(
navController = navController,
bottomPaddingValues = paddingValues,
paddingValues = paddingValues,
initialPage = initialPage,
showBottomNavBar = { bottomNavBarState.value = true },
hideBottomNavBar = { bottomNavBarState.value = false }
topAppBarState = topAppBarState,
bottomNavBarState = bottomNavBarState
)
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopAppBar(
topAppBarState: MutableState<Boolean>,
items: List<BottomNavItem>,
navController: NavController
) {
val backStackEntry = navController.currentBackStackEntryAsState()
var titleResId: Int? = null
items.forEach { item ->
if (item.route == backStackEntry.value?.destination?.route) titleResId = item.nameResId
}

AnimatedVisibility(
visible = topAppBarState.value,
enter = slideInVertically(initialOffsetY = { -it }),
exit = slideOutVertically(targetOffsetY = { -it })
) {
CenterAlignedTopAppBar(
title = {
if (titleResId != null) { // ensure that titleResId is properly initialized
Text(
text = stringResource(id = titleResId!!),
style = MaterialTheme.typography.titleLarge
)
}
},
navigationIcon = {
Image(
painter = painterResource(id = R.drawable.speechbuddy_parrot),
contentDescription = stringResource(id = R.string.app_name),
modifier = Modifier
.padding(6.dp)
.size(40.dp),
contentScale = ContentScale.Fit
)
},
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer,
titleContentColor = MaterialTheme.colorScheme.onSecondaryContainer
)
)
}
}
Expand Down Expand Up @@ -145,10 +204,10 @@ private fun BottomNavigationBar(
@Composable
private fun SpeechBuddyHomeNavHost(
navController: NavHostController,
bottomPaddingValues: PaddingValues,
paddingValues: PaddingValues,
initialPage: Boolean,
showBottomNavBar: () -> Unit,
hideBottomNavBar: () -> Unit,
topAppBarState: MutableState<Boolean>,
bottomNavBarState: MutableState<Boolean>
) {
val startDestination =
if (initialPage) {
Expand All @@ -160,24 +219,24 @@ private fun SpeechBuddyHomeNavHost(
NavHost(navController = navController, startDestination = startDestination) {
composable("symbol_selection") {
SymbolSelectionScreen(
bottomPaddingValues = bottomPaddingValues,
showBottomNavBar = showBottomNavBar,
hideBottomNavBar = hideBottomNavBar
paddingValues = paddingValues,
topAppBarState = topAppBarState,
bottomNavBarState = bottomNavBarState
)
}
composable("text_to_speech") {
TextToSpeechScreen(
bottomPaddingValues = bottomPaddingValues
paddingValues = paddingValues
)
}
composable("symbol_creation") {
SymbolCreationScreen(
bottomPaddingValues = bottomPaddingValues
paddingValues = paddingValues
)
}
composable("settings") {
SettingsScreen(
bottomPaddingValues = bottomPaddingValues
paddingValues = paddingValues
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
Expand All @@ -28,88 +26,75 @@ import com.example.speechbuddy.compose.utils.AlertDialogUi
import com.example.speechbuddy.compose.utils.ButtonLevel
import com.example.speechbuddy.compose.utils.ButtonUi
import com.example.speechbuddy.compose.utils.TitleUi
import com.example.speechbuddy.compose.utils.TopAppBarUi
import com.example.speechbuddy.ui.models.AccountSettingsAlert
import com.example.speechbuddy.viewmodel.AccountSettingsViewModel

@RequiresApi(Build.VERSION_CODES.O)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AccountSettings(
modifier: Modifier = Modifier,
onBackClick: () -> Unit,
bottomPaddingValues: PaddingValues,
paddingValues: PaddingValues,
viewModel: AccountSettingsViewModel = hiltViewModel()
) {
val uiState by viewModel.uiState.collectAsState()

/**
* Wait until user info is successfully retrieved
* in init{} of the viewmodel.
* in init{} of the view model.
*/
uiState.user?.let { user ->
Surface(
modifier = modifier.fillMaxSize()
) {
Scaffold(
topBar = {
TopAppBarUi(
title = stringResource(id = R.string.settings),
onBackClick = onBackClick,
isBackClickEnabled = true
Column(
modifier = Modifier
.fillMaxSize()
.padding(
top = paddingValues.calculateTopPadding(),
bottom = paddingValues.calculateBottomPadding()
)
.padding(24.dp),
verticalArrangement = Arrangement.Center
) {
TitleUi(title = stringResource(id = R.string.account))

Spacer(modifier = Modifier.height(20.dp))

Column(
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
SettingsRow(
label = stringResource(id = R.string.email),
content = {
SettingsRowText(text = user.email)
}
)

SettingsRow(
label = stringResource(id = R.string.nickname),
content = {
SettingsRowText(text = user.nickname)
}
)
}
) { topPaddingValues ->

Spacer(modifier = Modifier.height(80.dp))

Column(
modifier = Modifier
.fillMaxSize()
.padding(
top = topPaddingValues.calculateTopPadding(),
bottom = bottomPaddingValues.calculateBottomPadding()
)
.padding(24.dp),
verticalArrangement = Arrangement.Center
verticalArrangement = Arrangement.spacedBy(14.dp)
) {
TitleUi(title = stringResource(id = R.string.account))

Spacer(modifier = Modifier.height(20.dp))

Column(
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
SettingsRow(
label = stringResource(id = R.string.email),
content = {
SettingsRowText(text = user.email)
}
)

SettingsRow(
label = stringResource(id = R.string.nickname),
content = {
SettingsRowText(text = user.nickname)
}
)
}
ButtonUi(
text = stringResource(id = R.string.logout),
onClick = { viewModel.showAlert(AccountSettingsAlert.BACKUP) },
isEnabled = uiState.buttonEnabled
)

Spacer(modifier = Modifier.height(80.dp))

Column(
verticalArrangement = Arrangement.spacedBy(14.dp)
) {
ButtonUi(
text = stringResource(id = R.string.logout),
onClick = { viewModel.showAlert(AccountSettingsAlert.BACKUP) },
isEnabled = uiState.buttonEnabled
)

ButtonUi(
text = stringResource(id = R.string.withdraw),
onClick = { viewModel.showAlert(AccountSettingsAlert.WITHDRAW) },
level = ButtonLevel.QUATERNARY,
isEnabled = uiState.buttonEnabled
)
}
ButtonUi(
text = stringResource(id = R.string.withdraw),
onClick = { viewModel.showAlert(AccountSettingsAlert.WITHDRAW) },
level = ButtonLevel.QUATERNARY,
isEnabled = uiState.buttonEnabled
)
}
}
}
Expand Down
Loading