mirror of
https://github.com/kickstarter/android-oss.git
synced 2026-03-13 09:11:01 +08:00
NTV-643: Project Flagged info panel (#1726)
This commit is contained in:
@@ -68,6 +68,9 @@ fragment fullProject on Project {
|
||||
creator {
|
||||
... user
|
||||
}
|
||||
flagging {
|
||||
kind
|
||||
}
|
||||
currency
|
||||
canComment
|
||||
prelaunchActivated
|
||||
|
||||
@@ -60,7 +60,8 @@ class Project private constructor(
|
||||
private val projectFaqs: List<ProjectFaq>?,
|
||||
private val envCommitments: List<EnvironmentalCommitment>?,
|
||||
private val risks: String?,
|
||||
private val story: String?
|
||||
private val story: String?,
|
||||
private val isFlagged: Boolean?
|
||||
) : Parcelable, Relay {
|
||||
fun availableCardTypes() = this.availableCardTypes
|
||||
fun backersCount() = this.backersCount
|
||||
@@ -111,6 +112,7 @@ class Project private constructor(
|
||||
fun envCommitments() = this.envCommitments
|
||||
fun risks() = this.risks
|
||||
fun story() = this.story
|
||||
fun isFlagged() = this.isFlagged
|
||||
|
||||
@Parcelize
|
||||
data class Builder(
|
||||
@@ -163,7 +165,8 @@ class Project private constructor(
|
||||
private var projectFaqs: List<ProjectFaq>? = emptyList(),
|
||||
private var envCommitments: List<EnvironmentalCommitment>? = emptyList(),
|
||||
private var risks: String? = "",
|
||||
private var story: String? = ""
|
||||
private var story: String? = "",
|
||||
private var isFlagged: Boolean? = null
|
||||
) : Parcelable {
|
||||
fun availableCardTypes(availableCardTypes: List<String>?) = apply { this.availableCardTypes = availableCardTypes }
|
||||
fun backersCount(backersCount: Int?) = apply { this.backersCount = backersCount ?: 0 }
|
||||
@@ -214,6 +217,7 @@ class Project private constructor(
|
||||
fun envCommitments(envCommitments: List<EnvironmentalCommitment>?) = apply { this.envCommitments = envCommitments ?: emptyList() }
|
||||
fun risks(risks: String?) = apply { this.risks = risks ?: "" }
|
||||
fun story(story: String?) = apply { this.story = story ?: "" }
|
||||
fun isFlagged(isFlagged: Boolean?) = apply { this.isFlagged = isFlagged }
|
||||
fun build() = Project(
|
||||
availableCardTypes = availableCardTypes,
|
||||
backersCount = backersCount,
|
||||
@@ -263,7 +267,8 @@ class Project private constructor(
|
||||
projectFaqs = projectFaqs,
|
||||
envCommitments = envCommitments,
|
||||
risks = risks,
|
||||
story = story
|
||||
story = story,
|
||||
isFlagged = isFlagged
|
||||
)
|
||||
}
|
||||
|
||||
@@ -316,7 +321,8 @@ class Project private constructor(
|
||||
projectFaqs = projectFaqs,
|
||||
envCommitments = envCommitments,
|
||||
risks = risks,
|
||||
story = story
|
||||
story = story,
|
||||
isFlagged = isFlagged
|
||||
)
|
||||
|
||||
@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
|
||||
@@ -481,7 +487,9 @@ class Project private constructor(
|
||||
video() == other.video() &&
|
||||
projectFaqs() == other.projectFaqs() &&
|
||||
envCommitments() == other.envCommitments() &&
|
||||
risks() == other.risks()
|
||||
risks() == other.risks() &&
|
||||
story() == other.story() &&
|
||||
isFlagged() == other.isFlagged()
|
||||
}
|
||||
return equals
|
||||
}
|
||||
|
||||
@@ -311,6 +311,7 @@ fun projectTransformer(projectFragment: FullProject?): Project {
|
||||
val risks = projectFragment?.risks()
|
||||
val story = projectFragment?.story()?.toString() ?: ""
|
||||
val userCanComment = projectFragment?.canComment() ?: false
|
||||
val isFlagged = projectFragment?.flagging()?.kind()?.let { true } ?: false
|
||||
|
||||
return Project.builder()
|
||||
.availableCardTypes(availableCards.map { it.name })
|
||||
@@ -362,6 +363,7 @@ fun projectTransformer(projectFragment: FullProject?): Project {
|
||||
.envCommitments(eCommitment)
|
||||
.risks(risks)
|
||||
.story(story)
|
||||
.isFlagged(isFlagged)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
||||
@@ -366,6 +366,13 @@ class ProjectOverviewFragment : BaseFragment<ProjectOverviewViewModel.ViewModel>
|
||||
binding.projectCreatorInfoLayout.reportProject.setGone(!it)
|
||||
}
|
||||
|
||||
viewModel.outputs.shouldShowProjectFlagged()
|
||||
.compose(bindToLifecycle())
|
||||
.compose(Transformers.observeForUI())
|
||||
.subscribe {
|
||||
binding.projectCreatorInfoLayout.projectFlagged.setGone(!it)
|
||||
}
|
||||
|
||||
binding.projectCreatorDashboardHeader.projectDashboardButton.setOnClickListener {
|
||||
this.viewModel.inputs.creatorDashboardClicked()
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ interface ProjectOverviewViewModel {
|
||||
fun startReportProjectView(): Observable<ProjectData>
|
||||
fun startLoginView(): Observable<Void>
|
||||
fun shouldShowReportProject(): Observable<Boolean>
|
||||
fun shouldShowProjectFlagged(): Observable<Boolean>
|
||||
}
|
||||
|
||||
class ViewModel(environment: Environment) : FragmentViewModel<ProjectOverviewFragment?>(environment), Inputs, Outputs {
|
||||
@@ -253,6 +254,7 @@ interface ProjectOverviewViewModel {
|
||||
private val startReportProjectView: Observable<ProjectData>
|
||||
private val startLogin = PublishSubject.create<Void>()
|
||||
private val shouldShowReportProject: Observable<Boolean>
|
||||
private val shouldShowProjectFlagged: Observable<Boolean>
|
||||
|
||||
val inputs: Inputs = this
|
||||
val outputs: Outputs = this
|
||||
@@ -471,6 +473,10 @@ interface ProjectOverviewViewModel {
|
||||
return this.shouldShowReportProject
|
||||
}
|
||||
|
||||
override fun shouldShowProjectFlagged(): Observable<Boolean> {
|
||||
return this.shouldShowProjectFlagged
|
||||
}
|
||||
|
||||
init {
|
||||
val project = projectData
|
||||
.distinctUntilChanged()
|
||||
@@ -763,7 +769,16 @@ interface ProjectOverviewViewModel {
|
||||
this.startLogin.onNext(null)
|
||||
}
|
||||
|
||||
shouldShowReportProject = Observable.just(this.optimizely?.isFeatureEnabled(OptimizelyFeature.Key.ANDROID_UGC) ?: false)
|
||||
shouldShowProjectFlagged = project
|
||||
.map { it.isFlagged() ?: false }
|
||||
.withLatestFrom(Observable.just(this.optimizely?.isFeatureEnabled(OptimizelyFeature.Key.ANDROID_UGC) ?: false)) { isFlagged, isEnabled ->
|
||||
return@withLatestFrom isEnabled && isFlagged
|
||||
}
|
||||
|
||||
shouldShowReportProject = shouldShowProjectFlagged
|
||||
.withLatestFrom(Observable.just(this.optimizely?.isFeatureEnabled(OptimizelyFeature.Key.ANDROID_UGC) ?: false)) { isFlagged, isEnabled ->
|
||||
return@withLatestFrom isEnabled && !isFlagged
|
||||
}
|
||||
|
||||
projectData
|
||||
.compose(Transformers.takePairWhen(campaignClicked))
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/grid_3"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
@@ -87,7 +87,8 @@
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:paddingTop="@dimen/grid_2"
|
||||
android:paddingBottom="@dimen/grid_2">
|
||||
android:paddingBottom="@dimen/grid_2"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
@@ -111,11 +112,58 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_arrow_right" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/project_flagged"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/activity_vertical_margin"
|
||||
android:layout_marginTop="@dimen/activity_vertical_margin"
|
||||
android:layout_marginEnd="@dimen/activity_vertical_margin"
|
||||
android:layout_marginBottom="@dimen/grid_4"
|
||||
android:foreground="@drawable/click_indicator_light"
|
||||
app:cardBackgroundColor="@color/kds_support_200"
|
||||
app:cardCornerRadius="@dimen/grid_2"
|
||||
app:cardElevation="@dimen/card_no_elevation"
|
||||
android:visibility="gone">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:paddingTop="@dimen/grid_2"
|
||||
android:paddingLeft="@dimen/grid_2"
|
||||
android:paddingRight="@dimen/grid_2"
|
||||
android:paddingBottom="@dimen/grid_2">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/check_reported"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:background="@null"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/icon__info"
|
||||
app:layout_constraintBaseline_toBottomOf="@+id/text_reported"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_reported"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/FPO_Already_reported"
|
||||
android:textColor="@color/kds_support_700"
|
||||
android:textSize="@dimen/body"
|
||||
android:layout_marginStart="@dimen/grid_2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/check_reported"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/project_disclaimer_text_view"
|
||||
style="@style/Caption1Secondary"
|
||||
|
||||
@@ -86,5 +86,7 @@
|
||||
|
||||
<!-- Risks Mock String-->
|
||||
<string name="risk_description">"The largest risk comes from the creation/manufacturing of the pins at the pin factory. We are working with a vendor in China, who has lots of experience in projects for us. Still, there is a chance that something may go wrong during the manufacturing process and if that happens it could cause a delay in shipping. It can be common in the pin-making world that manus are delayed or make mistakes with an order. However, we don’t anticipate this being an issue, as our vendor has done many similar projects with us, but there is always a possibility. These items are handmade! If anything does happen, we will make sure to keep everyone informed and up to date regarding where we are in the process. The timeline for shipping is NOT solid due to these factors but we will keep all backers updated each step of the way. Also- Please be aware, there might be a delay due to the situation with the COVID-19 virus. This is causing delays all over the world as shipping gets limited, cities shutting down services and other issues arise. At this point, we do not think this will impact our project timeline. However, we cannot predict how things will go and our pin factory is located in China (they are all back at work now and we have gotten pins from them within the last month, so things appear to be going well now.) If this will affect our production, I will inform everyone through an update as soon as I know."</string>
|
||||
<string name="FPO_report_project">Report this project to Kickstarter</string>
|
||||
|
||||
<string name="FPO_Already_reported">It looks like you’ve already reported this project to us. Our Trust and Safety team will screen your report against Our Rules and Community Guidelines. Thanks for your feedback!</string>
|
||||
<string name="FPO_report_project">Report this project to Kickstarter</string>
|
||||
</resources>
|
||||
|
||||
@@ -86,6 +86,7 @@ class ProjectOverviewViewModelTest : KSRobolectricTestCase() {
|
||||
private val startReportProjectView = TestSubscriber<ProjectData>()
|
||||
private val startLoginView = TestSubscriber<Void>()
|
||||
private val shouldShowReportProject = TestSubscriber<Boolean>()
|
||||
private val shouldShowProjectFlagged = TestSubscriber<Boolean>()
|
||||
|
||||
private fun setUpEnvironment(environment: Environment, projectData: ProjectData) {
|
||||
vm = ProjectOverviewViewModel.ViewModel(environment)
|
||||
@@ -147,6 +148,7 @@ class ProjectOverviewViewModelTest : KSRobolectricTestCase() {
|
||||
vm.outputs.shouldShowReportProject().subscribe(shouldShowReportProject)
|
||||
vm.outputs.startLoginView().subscribe(startLoginView)
|
||||
vm.outputs.startReportProjectView().subscribe(startReportProjectView)
|
||||
vm.outputs.shouldShowProjectFlagged().subscribe(shouldShowProjectFlagged)
|
||||
vm.inputs.configureWith(projectData)
|
||||
}
|
||||
|
||||
@@ -689,6 +691,18 @@ class ProjectOverviewViewModelTest : KSRobolectricTestCase() {
|
||||
this.startReportProjectView.assertValue(projectData)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testProjectReported() {
|
||||
val env = environmentForFeatureFlag(true)
|
||||
val project = ProjectFactory.project().toBuilder()
|
||||
.isFlagged(true)
|
||||
.build()
|
||||
setUpEnvironment(env, project(project))
|
||||
|
||||
this.shouldShowProjectFlagged.assertValue(true)
|
||||
this.shouldShowReportProject.assertValue(false)
|
||||
}
|
||||
|
||||
private fun environmentForFeatureFlag(enabled: Boolean): Environment {
|
||||
val mockExperimentsClientType: MockExperimentsClientType =
|
||||
object : MockExperimentsClientType() {
|
||||
|
||||
Reference in New Issue
Block a user