Skip to content

Commit

Permalink
Merge pull request #7 from eliekarouz/flow_id
Browse files Browse the repository at this point in the history
Flow id
  • Loading branch information
eliekarouz authored Aug 11, 2023
2 parents dfdd250 + 2e6a68c commit d90e049
Show file tree
Hide file tree
Showing 21 changed files with 205 additions and 313 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ fastlane/screenshots
fastlane/test_output
fastlane/readme.md
public
/.idea/artifacts/core_android_0_13_1.xml
/.idea/
6 changes: 0 additions & 6 deletions .idea/misc.xml

This file was deleted.

34 changes: 0 additions & 34 deletions .idea/modules.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import com.feedbacktree.tutorials.flows.counter.CounterLayoutBinder
import com.feedbacktree.tutorials.flows.login.LoginLayoutBinder
import com.feedbacktree.tutorials.flows.modals.CovidInfoLayoutBinder
import com.feedbacktree.tutorials.flows.modals.ModalsExampleLayoutBinder
import com.feedbacktree.tutorials.flows.modals.ViewModalDialogBinding
import com.feedbacktree.tutorials.flows.tutorialsroot.TutorialsLayoutBinder

private val dialogRegistry =
DialogRegistry.registry(R.style.FTDialogTheme)
DialogRegistry.registry(R.style.FTDialogTheme) + ViewModalDialogBinding()

val appViewRegistry = ViewRegistry(
ModalContainer.Binding(dialogRegistry),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,25 @@ import com.feedbacktree.flow.core.endFlow
import kotlin.math.max

val CounterFlow = Flow<Unit, State, Event, Unit, CounterScreen>(
id = "CounterFlow",
initialState = { State(counter = 0) },
stepper = { state, event ->
when (event) {
Event.Increment -> state.copy(
counter = state.counter + 1
).advance()

Event.Decrement -> state.copy(
counter = max(0, state.counter - 1)
).advance()

Event.BackPressed -> endFlow()
}
},
feedbacks = listOf(),
render = { state, context ->
CounterScreen(state, context.sink)
}
)
feedbacks = listOf()
) { state, context ->
CounterScreen(state, context.sink)
}

data class State(
val counter: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.feedbacktree.tutorials.managers.AuthenticationManager
import io.reactivex.Observable

val LoginFlow = Flow<String, State, Event, LoginFlowOutput, LoginScreen>(
id = "LoginFlow",
initialState = { lastEmailUsed -> State(email = lastEmailUsed) },
stepper = { state, event ->
when (event) {
Expand All @@ -23,14 +24,14 @@ val LoginFlow = Flow<String, State, Event, LoginFlowOutput, LoginScreen>(
state.copy(isLoggingIn = false).advance()
}
}

Event.BackPressed -> endFlowWith(LoginFlowOutput.Aborted)
}
},
feedbacks = listOf(loginFeedback()),
render = { state, context ->
return@Flow LoginScreen(state, context.sink)
}
)
feedbacks = listOf(loginFeedback())
) { state, context ->
return@Flow LoginScreen(state, context.sink)
}

data class State(
val email: String = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ package com.feedbacktree.tutorials.flows.modals
import com.feedbacktree.flow.core.Flow
import com.feedbacktree.flow.core.advance
import com.feedbacktree.flow.core.endFlow
import com.feedbacktree.flow.ui.core.modals.*
import com.feedbacktree.flow.ui.core.modals.AlertModal
import com.feedbacktree.flow.ui.core.modals.ModalContainerScreen
import com.feedbacktree.tutorials.flows.login.LoginFlow

val ModalsFlow = Flow<Unit, State, Event, Unit, ModalContainerScreen<*, *>>(
id = "ModalsFlow",
initialState = { State.Idle },
stepper = { _, event ->
when (event) {
Expand All @@ -24,48 +26,51 @@ val ModalsFlow = Flow<Unit, State, Event, Unit, ModalContainerScreen<*, *>>(
Event.BackClicked -> endFlow()
}
},
feedbacks = listOf(),
render = { state, context ->
ModalContainerScreen(
baseScreen = ModalsScreen(sink = context.sink),
modal = when (state) {
State.Idle -> null
State.ShowingAlertModal -> AlertModal(context.sink) {
title = "COVID Screening"
message = "Do you have fever?"
positive("Yes", Event.DismissAlert("Yes Clicked"))
negative("No", Event.DismissAlert("No Clicked"))
cancelEvent = Event.DismissAlert("BackClicked")
}
State.ShowingAlertModalWithCustomView -> AlertModal(context.sink) {
title = "COVID Info"
positive("Dismiss", Event.DismissAlert("Dismiss Clicked"))
contentScreen = CovidInfoScreen()
cancelEvent = Event.DismissAlert("BackClicked")
}
State.ShowingFullScreenModal -> {
val contentScreen =
context.renderChild(input = "", flow = LoginFlow, onResult = {
context.sendEvent(Event.FullScreenFlowCompleted)
})
// Wrap the screen produced by the LoginFlow in a FullScreenModal
FullScreenModal(contentScreen)
}
State.ShowingCustomSizeModal -> {
val contentScreen =
context.renderChild(input = "", flow = LoginFlow, onResult = {
context.sendEvent(Event.FullScreenFlowCompleted)
})
ViewModal(
contentScreen,
widthLayout = Layout.Percentage(55),
heightLayout = Layout.Percentage(55)
)
}
feedbacks = listOf()
) { state, context ->
ModalContainerScreen(
baseScreen = ModalsScreen(sink = context.sink),
modal = when (state) {
State.Idle -> null
State.ShowingAlertModal -> AlertModal(context.sink) {
title = "COVID Screening"
message = "Do you have fever?"
positive("Yes", Event.DismissAlert("Yes Clicked"))
negative("No", Event.DismissAlert("No Clicked"))
cancelEvent = Event.DismissAlert("BackClicked")
}
)
}
)

State.ShowingAlertModalWithCustomView -> AlertModal(context.sink) {
title = "COVID Info"
positive("Dismiss", Event.DismissAlert("Dismiss Clicked"))
contentScreen = CovidInfoScreen()
cancelEvent = Event.DismissAlert("BackClicked")
}

State.ShowingFullScreenModal -> {
val contentScreen =
context.renderChild(input = "", flow = LoginFlow, onResult = {
context.sendEvent(Event.FullScreenFlowCompleted)
})
// Wrap the screen produced by the LoginFlow in a FullScreenModal
FullScreenModal(contentScreen)
}

State.ShowingCustomSizeModal -> {
val contentScreen =
context.renderChild(input = "", flow = LoginFlow, onResult = {
context.sendEvent(Event.FullScreenFlowCompleted)
})
ViewModal(
contentScreen,
widthLayout = Layout.Percentage(55),
heightLayout = Layout.Percentage(55),
roundCorners = false
)
}
}
)
}


enum class State {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
/*
* Created by eliek on 9/26/2019
* Copyright (c) 2019 eliekarouz. All rights reserved.
* Created by eliek on 8/9/2023
* Copyright (c) 2023 eliekarouz. All rights reserved.
*/

@file:Suppress("FunctionName")

package com.feedbacktree.flow.ui.core.modals
package com.feedbacktree.tutorials.flows.modals

import androidx.annotation.ColorInt
import com.feedbacktree.flow.ui.core.Compatible
import com.feedbacktree.flow.ui.core.modals.Modal

class ViewModal<ScreenT : Any>(
val content: ScreenT,
val widthLayout: Layout,
val heightLayout: Layout,
@ColorInt val backgroundColor: Int? = null
@ColorInt val backgroundColor: Int? = null,
val roundCorners: Boolean? = null
) : Modal, Compatible {
constructor(content: ScreenT) : this(
constructor(
content: ScreenT,
roundCorners: Boolean?,
) : this(
content,
widthLayout = Layout.Wrap,
heightLayout = Layout.Wrap
heightLayout = Layout.Wrap,
roundCorners = roundCorners
)

override val compatibilityKey: String
Expand All @@ -37,8 +43,8 @@ sealed class Layout {
}
}

fun <ScreenT : Any> ScreenT.asModal(): ViewModal<ScreenT> {
return ViewModal(content = this)
fun <ScreenT : Any> ScreenT.asModal(roundCorners: Boolean? = null): ViewModal<ScreenT> {
return ViewModal(content = this, roundCorners = roundCorners)
}


Expand All @@ -52,7 +58,7 @@ fun <ScreenT : Any> FullScreenModal(content: ScreenT): ViewModal<ScreenT> {
return ViewModal(
content = content,
widthLayout = Layout.FullScreen,
heightLayout = Layout.FullScreen
heightLayout = Layout.FullScreen,
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,36 @@
/*
* Created by eliek on 9/26/2019
* Copyright (c) 2019 eliekarouz. All rights reserved.
* Created by eliek on 8/11/2023
* Copyright (c) 2023 eliekarouz. All rights reserved.
*/

package com.feedbacktree.flow.ui.views.modals
package com.feedbacktree.tutorials.flows.modals

import android.app.Dialog
import android.content.Context
import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.Color
import android.graphics.Point
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable
import android.util.TypedValue
import android.view.*
import android.view.Display
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import androidx.core.content.ContextCompat
import com.feedbacktree.R
import com.feedbacktree.flow.ui.core.modals.Layout
import com.feedbacktree.flow.ui.core.modals.ViewModal
import com.feedbacktree.flow.ui.views.core.HandlesBack
import com.feedbacktree.flow.ui.views.core.ViewRegistry
import com.feedbacktree.flow.ui.views.core.disposeScreenBinding
import com.feedbacktree.flow.ui.views.core.showScreen
import com.feedbacktree.flow.utils.logAndShow
import com.feedbacktree.flow.ui.views.modals.DialogBinding
import com.feedbacktree.flow.ui.views.modals.DialogRef
import com.feedbacktree.flow.ui.views.modals.DialogRegistry
import com.feedbacktree.flow.utils.windowManager
import kotlin.reflect.KClass

Expand Down Expand Up @@ -70,7 +77,7 @@ class ViewModalDialogBinding(
}

setContentView(fullWindowPanel)
logAndShow("FullScreen")
show()

window?.setBackgroundDrawable(ColorDrawable(ContextCompat.getColor(context, R.color.dim)))

Expand All @@ -79,14 +86,28 @@ class ViewModalDialogBinding(
val contentPanel = FrameLayout(context)

// Setting backgroundColor of the panel ideally with using the windowBackground
if (viewModal.backgroundColor != null) {
contentPanel.setBackgroundColor(viewModal.backgroundColor)
val panelBackgroundColor = if (viewModal.backgroundColor != null) {
viewModal.backgroundColor
} else {
val typedValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.windowBackground, typedValue, true)
if (typedValue.type in TypedValue.TYPE_FIRST_COLOR_INT..TypedValue.TYPE_LAST_COLOR_INT) {
contentPanel.setBackgroundColor(typedValue.data)
typedValue.data
} else null
}

if (viewModal.roundCorners ?: !viewModal.hasFullScreenDimension()) {
contentPanel.background = GradientDrawable().apply {
panelBackgroundColor?.also { color = ColorStateList.valueOf(it) }
cornerRadius = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
20f,
Resources.getSystem().displayMetrics
)
}
contentPanel.clipToOutline = true
} else if (panelBackgroundColor != null) {
contentPanel.setBackgroundColor(panelBackgroundColor)
}

// Adjusting the panel size
Expand Down Expand Up @@ -168,4 +189,11 @@ private fun layoutParams(layout: Layout, screenDimension: Int, scale: Float): In
is Layout.DPs -> (layout.dps * scale).toInt()
is Layout.Percentage -> (screenDimension.toFloat() * layout.percentage.toFloat() * 0.01).toInt()
}
}

private fun <Screen : Any> ViewModal<Screen>.hasFullScreenDimension(): Boolean {
return widthLayout == Layout.FullScreen ||
heightLayout == Layout.FullScreen ||
(widthLayout is Layout.Percentage && widthLayout.percentage == 100) ||
(heightLayout is Layout.Percentage && heightLayout.percentage == 100)
}
Loading

0 comments on commit d90e049

Please sign in to comment.