Skip to content

Commit

Permalink
[UI] #16 포킷 상세 화면 구현 (#20)
Browse files Browse the repository at this point in the history
* [BASE] #16 feature:pokitdetail 모듈 생성

* [UI] #16 LinkCard에서 타이틀 이름이 길어지는 경우 우상단의 케밥 버튼이 밀려나는 현상 수정

* [FEATURE] #16 포킷 상세 화면 UI 구현

* [FEATURE] #16 링크 상세 bottomSheet UI 구현

* [FEATURE] #16 포킷 상세 화면 관련 bottomSheet UI 구현 맟 화면과 연결

* [CHORE] #16 ktlink 적용

* [CHORE] #16 코드 리뷰내용 반영
: lambda 내에서 it대신 명시적인 변수명 사용
: nullable한 변수에 null 기본값 설정
  • Loading branch information
l5x5l authored Jul 19, 2024
1 parent 0329fc6 commit ba6b1d7
Show file tree
Hide file tree
Showing 28 changed files with 1,294 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import pokitmons.pokit.core.ui.R
import pokitmons.pokit.core.ui.theme.PokitTheme
Expand Down Expand Up @@ -83,10 +84,12 @@ fun<T> LinkCard(
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
modifier = Modifier.weight(1f),
text = title,
style = PokitTheme.typography.body3Medium.copy(color = PokitTheme.colors.textPrimary),
maxLines = 2,
minLines = 2
minLines = 2,
overflow = TextOverflow.Ellipsis
)

IconButton(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pokitmons.pokit.core.ui.components.block.linkcard

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
Expand All @@ -21,7 +22,8 @@ fun LinkCardPreview() {
modifier = Modifier
.fillMaxSize()
.background(Color.LightGray)
.padding(12.dp)
.padding(12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
LinkCard(
title = "타이틀\n컴포스는 왜 이런가",
Expand All @@ -33,6 +35,17 @@ fun LinkCardPreview() {
onClickKebab = { value: Int -> },
onClickItem = { value: Int -> }
)

LinkCard(
title = "동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세",
sub = "2024.06.25. youtube.com",
badgeText = "텍스트",
painter = painterResource(id = R.drawable.icon_24_link),
notRead = true,
item = 3,
onClickKebab = { value: Int -> },
onClickItem = { value: Int -> }
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fun PokitBottomSheet(
onHideBottomSheet: () -> Unit,
content: @Composable (ColumnScope.() -> Unit),
) {
val bottomSheetState = rememberModalBottomSheetState()
val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)

ModalBottomSheet(
onDismissRequest = onHideBottomSheet,
Expand Down
1 change: 1 addition & 0 deletions feature/pokitdetail/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
64 changes: 64 additions & 0 deletions feature/pokitdetail/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
plugins {
alias(libs.plugins.com.android.library)
alias(libs.plugins.org.jetbrains.kotlin.android)
}

android {
namespace = "com.strayalpaca.pokitdetail"
compileSdk = 34

defaultConfig {
minSdk = 24

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}

dependencies {

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)

implementation(libs.orbit.compose)
implementation(libs.orbit.core)
implementation(libs.orbit.viewmodel)

implementation(project(":core:ui"))
}
Empty file.
21 changes: 21 additions & 0 deletions feature/pokitdetail/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.strayalpaca.pokitdetail

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.strayalpaca.pokitdetail.test", appContext.packageName)
}
}
4 changes: 4 additions & 0 deletions feature/pokitdetail/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package com.strayalpaca.pokitdetail

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.strayalpaca.pokitdetail.components.block.TitleArea
import com.strayalpaca.pokitdetail.components.block.Toolbar
import com.strayalpaca.pokitdetail.components.template.filterselectbottomsheet.FilterSelectBottomSheet
import com.strayalpaca.pokitdetail.components.template.linkdetailbottomsheet.LinkDetailBottomSheet
import com.strayalpaca.pokitdetail.model.BottomSheetType
import com.strayalpaca.pokitdetail.model.Filter
import com.strayalpaca.pokitdetail.model.Link
import com.strayalpaca.pokitdetail.model.Pokit
import com.strayalpaca.pokitdetail.model.PokitDetailScreenState
import pokitmons.pokit.core.ui.components.block.linkcard.LinkCard
import pokitmons.pokit.core.ui.components.block.pokitlist.PokitList
import pokitmons.pokit.core.ui.components.block.pokitlist.attributes.PokitListState
import pokitmons.pokit.core.ui.components.template.bottomsheet.PokitBottomSheet
import pokitmons.pokit.core.ui.components.template.modifybottomsheet.ModifyBottomSheetContent
import pokitmons.pokit.core.ui.components.template.removeItemBottomSheet.RemoveItemBottomSheetContent
import pokitmons.pokit.core.ui.components.template.removeItemBottomSheet.attributes.RemoveItemType
import pokitmons.pokit.core.ui.theme.PokitTheme
import pokitmons.pokit.core.ui.R.drawable as coreDrawable

@Composable
fun PokitDetailScreenContainer(
viewModel: PokitDetailViewModel,
onBackPressed: () -> Unit,
) {
val state by viewModel.state.collectAsState()
val linkList by viewModel.linkList.collectAsState()
val pokitList by viewModel.pokitList.collectAsState()

PokitDetailScreen(
onBackPressed = onBackPressed,
onClickFilter = viewModel::showFilterChangeBottomSheet,
hideFilterChangeBottomSheet = viewModel::hideFilterChangeBottomSheet,
changeFilter = viewModel::changeFilter,
showPokitSelectBottomSheet = viewModel::showPokitSelectBottomSheet,
hidePokitSelectBottomSheet = viewModel::hidePokitSelectBottomSheet,
changePokit = viewModel::changePokit,
showPokitModifyBottomSheet = viewModel::showPokitModifyBottomSheet,
showPokitRemoveBottomSheet = viewModel::showPokitRemoveBottomSheet,
hidePokitModifyBottomSheet = viewModel::hidePokitBottomSheet,
showLinkModifyBottomSheet = viewModel::showLinkModifyBottomSheet,
showLinkRemoveBottomSheet = viewModel::showLinkRemoveBottomSheet,
hideLinkModifyBottomSheet = viewModel::hideLinkBottomSheet,
hideLinkDetailBottomSheet = viewModel::hideLinkDetailBottomSheet,
state = state,
linkList = linkList,
pokitList = pokitList,
onClickLink = viewModel::showLinkDetailBottomSheet
)
}

@Composable
fun PokitDetailScreen(
onBackPressed: () -> Unit = {},
onClickFilter: () -> Unit = {},
hideFilterChangeBottomSheet: () -> Unit = {},
changeFilter: (Filter) -> Unit = {},
showPokitSelectBottomSheet: () -> Unit = {},
hidePokitSelectBottomSheet: () -> Unit = {},
changePokit: (Pokit) -> Unit = {},
showPokitModifyBottomSheet: () -> Unit = {},
showPokitRemoveBottomSheet: () -> Unit = {},
hidePokitModifyBottomSheet: () -> Unit = {},
showLinkModifyBottomSheet: (Link) -> Unit = {},
showLinkRemoveBottomSheet: () -> Unit = {},
hideLinkModifyBottomSheet: () -> Unit = {},
hideLinkDetailBottomSheet: () -> Unit = {},
state: PokitDetailScreenState = PokitDetailScreenState(),
linkList: List<Link> = emptyList(),
pokitList: List<Pokit> = emptyList(),
onClickLink: (Link) -> Unit = {},
) {
Column(
modifier = Modifier.fillMaxSize()
) {
Toolbar(
onBackPressed = onBackPressed,
onClickKebab = showPokitModifyBottomSheet
)

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

TitleArea(
title = state.currentPokit.title,
sub = stringResource(id = pokitmons.pokit.core.ui.R.string.pokit_count_format, state.currentPokit.count),
onClickSelectPokit = showPokitSelectBottomSheet,
onClickSelectFilter = onClickFilter
)

LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {
items(linkList) { link ->
LinkCard(
item = link,
title = link.title,
sub = "${link.dateString} · ${link.domainUrl}",
painter = painterResource(id = coreDrawable.icon_24_google),
notRead = link.isRead,
badgeText = stringResource(id = link.linkType.textResourceId),
onClickKebab = showLinkModifyBottomSheet,
onClickItem = onClickLink,
modifier = Modifier.padding(20.dp)
)

HorizontalDivider(
modifier = Modifier.padding(horizontal = 20.dp),
thickness = 1.dp,
color = PokitTheme.colors.borderTertiary
)
}
}

if (state.linkDetailBottomSheetVisible && state.currentLink != null) {
LinkDetailBottomSheet(link = state.currentLink, onHideBottomSheet = hideLinkDetailBottomSheet)
}

if (state.filterChangeBottomSheetVisible) {
FilterSelectBottomSheet(
filter = state.currentFilter,
onHideRequest = hideFilterChangeBottomSheet,
onFilterChange = changeFilter
)
}

if (state.pokitSelectBottomSheetVisible) {
PokitBottomSheet(onHideBottomSheet = hidePokitSelectBottomSheet) {
LazyColumn {
items(
items = pokitList
) { pokit ->
PokitList(
item = pokit,
title = pokit.title,
sub = stringResource(id = R.string.link_count_format, pokit.count),
onClickItem = changePokit,
state = PokitListState.ACTIVE
)
}
}
}
}

if (state.linkBottomSheetType != null) {
PokitBottomSheet(onHideBottomSheet = hideLinkModifyBottomSheet) {
when (state.linkBottomSheetType) {
BottomSheetType.MODIFY -> {
ModifyBottomSheetContent(
onClickShare = {},
onClickModify = {},
onClickRemove = showLinkRemoveBottomSheet
)
}
BottomSheetType.REMOVE -> {
RemoveItemBottomSheetContent(
removeItemType = RemoveItemType.LINK,
onClickCancel = hideLinkModifyBottomSheet,
onClickRemove = {}
)
}
}
}
}

if (state.pokitBottomSheetType != null) {
PokitBottomSheet(onHideBottomSheet = hidePokitModifyBottomSheet) {
when (state.pokitBottomSheetType) {
BottomSheetType.MODIFY -> {
ModifyBottomSheetContent(
onClickShare = {},
onClickModify = {},
onClickRemove = showPokitRemoveBottomSheet
)
}
BottomSheetType.REMOVE -> {
RemoveItemBottomSheetContent(
removeItemType = RemoveItemType.POKIT,
onClickCancel = hidePokitModifyBottomSheet,
onClickRemove = {}
)
}
}
}
}
}
}
Loading

0 comments on commit ba6b1d7

Please sign in to comment.