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

Fix Part of #4938: Introduce Onboarding UI V2 2 of 3 #5327

Closed
wants to merge 58 commits into from
Closed
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
ec0eded
Add platform parameter for gating the new onboarding flow
adhiamboperes Oct 30, 2023
3435a08
Refactor SurveyOnboardingBackgroundView to be a generic OppiaCurveBac…
adhiamboperes Oct 30, 2023
4df3f60
Add onboarding language selection layout: wip
adhiamboperes Nov 1, 2023
0f6c4b9
sync with develop and resolve conflicts
adhiamboperes Dec 11, 2023
76120a9
Rename platform parameter to enableOnboardingFlowV2
adhiamboperes Dec 11, 2023
b76679b
Merge remote-tracking branch 'upstream/new-onboarding-platform-param'…
adhiamboperes Dec 11, 2023
4345801
Create onboarding app language selection UI portrait
adhiamboperes Dec 11, 2023
3f28f81
Complete onboarding language UI portrait light mode
adhiamboperes Dec 19, 2023
c2fa816
Add darkmode support for onboarding language UI
adhiamboperes Dec 19, 2023
ee9ff7c
Fix explanation text padding
adhiamboperes Dec 19, 2023
6f0f6e4
Revert commented out code
adhiamboperes Jan 31, 2024
52ae374
Set up new onboarding flow entry point
adhiamboperes Jan 31, 2024
b04b637
Set up onboarding fragment tests wth platform param
adhiamboperes Jan 31, 2024
a536e15
Add onboarding profile type selection UI and navigation
adhiamboperes Jan 31, 2024
91fb562
Add onboarding profile type selection UI and navigation
adhiamboperes Jan 31, 2024
7962902
merge upstream/develop
adhiamboperes Jan 31, 2024
0696b6a
Move feature flags to FeatureFlagConstants.kt
adhiamboperes Jan 31, 2024
296c4d1
Merge branch 'new-onboarding-platform-param' into new-onboarding-ui
adhiamboperes Jan 31, 2024
2e0c8b8
Added learner welcome screen
adhiamboperes Feb 1, 2024
a0a553a
Added audio language selection screen
adhiamboperes Feb 2, 2024
dd197e2
Fix bazel error
adhiamboperes Feb 2, 2024
2b6a5e2
Add create learner profile screen
adhiamboperes Feb 5, 2024
ab609dd
Complete profile type UI
adhiamboperes Feb 7, 2024
c8a6286
Merge branch 'develop' of github.com:oppia/oppia-android into new-onb…
adhiamboperes Feb 7, 2024
bddf70c
Refactor app language mobile portrait UI
adhiamboperes Feb 8, 2024
b6aaf89
Refactor profile type mobile portrait UI
adhiamboperes Feb 8, 2024
b87e423
Refactor profile creation mobile portrait UI
adhiamboperes Feb 9, 2024
2710b1f
Refactor resource names for uniformity
adhiamboperes Feb 12, 2024
2f4472f
Refactor language dropdown to show drop shadow
adhiamboperes Feb 12, 2024
57c3533
Pass correct values to string templates
adhiamboperes Feb 12, 2024
76df4f0
Fix issues from self review
adhiamboperes Feb 12, 2024
e24d9b1
Merge branch 'develop' of github.com:oppia/oppia-android into new-onb…
adhiamboperes Feb 12, 2024
db6490e
Enforce darkmode
adhiamboperes Feb 13, 2024
dbe9cf8
Fix dark mode issues
adhiamboperes Feb 13, 2024
11ce47b
Wrap up mobile portrait screens
adhiamboperes Feb 13, 2024
3ba9e0c
Complete landscape layouts
adhiamboperes Feb 16, 2024
56dd47f
Fix regex check failure for strings
adhiamboperes Feb 16, 2024
28dd2b5
Merge branch 'develop' of github.com:oppia/oppia-android into new-onb…
adhiamboperes Feb 16, 2024
edbdb11
Fix review pass issues
adhiamboperes Feb 16, 2024
6c9086b
App language tests
adhiamboperes Feb 19, 2024
5adb3e2
Create test file exemptions
adhiamboperes Feb 19, 2024
133cf98
Merge branch 'new-onboarding-ui' of github.com:oppia/oppia-android in…
adhiamboperes Feb 19, 2024
c6c0174
Wrap up activity tests
adhiamboperes Feb 20, 2024
7f861b3
Merge branch 'develop' of github.com:oppia/oppia-android into new-onb…
adhiamboperes Feb 20, 2024
8a271fa
Fix missing test configs
adhiamboperes Feb 20, 2024
dc9557b
Fragment tests
adhiamboperes Feb 21, 2024
69c1eae
Fragment tests
adhiamboperes Feb 22, 2024
6a0fd44
Fix profile type tests and display on very small devices
adhiamboperes Feb 27, 2024
cc2cce0
Fix landscape tests and display on very small devices
adhiamboperes Feb 27, 2024
6c07b96
Merge branch 'develop' into new-onboarding-ui
adhiamboperes Feb 27, 2024
f478aef
Profile picture upload success
adhiamboperes Mar 16, 2024
ee37115
refactor create profile classes
adhiamboperes Mar 16, 2024
f3e485a
Create profile and display name in next screen
adhiamboperes Mar 16, 2024
dcf35c3
Navigate to audio language fragment and show list of languages in dro…
adhiamboperes Mar 18, 2024
7e53496
Implement navigation to home screen
adhiamboperes Mar 18, 2024
cf918e9
Fix failing tests
adhiamboperes Mar 19, 2024
deacb45
Merge branch 'new-onboarding-ui' of github.com:oppia/oppia-android in…
adhiamboperes Mar 19, 2024
692e62e
Merge branch 'develop' of github.com:oppia/oppia-android into new-onb…
adhiamboperes Mar 19, 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
3 changes: 2 additions & 1 deletion app/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ VIEW_MODELS_WITH_RESOURCE_IMPORTS = [
"src/main/java/org/oppia/android/app/home/topiclist/TopicSummaryViewModel.kt",
"src/main/java/org/oppia/android/app/onboarding/OnboadingSlideViewModel.kt",
"src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt",
"src/main/java/org/oppia/android/app/onboarding/onboardingv2/CreateLearnerProfileViewModel.kt",
"src/main/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicItemViewModel.kt",
"src/main/java/org/oppia/android/app/options/OptionsReadingTextSizeViewModel.kt",
"src/main/java/org/oppia/android/app/options/TextSizeItemViewModel.kt",
Expand Down Expand Up @@ -409,9 +410,9 @@ VIEWS_WITH_RESOURCE_IMPORTS = [
"src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt",
"src/main/java/org/oppia/android/app/customview/ContinueButtonView.kt",
"src/main/java/org/oppia/android/app/customview/LessonThumbnailImageView.kt",
"src/main/java/org/oppia/android/app/customview/OppiaCurveBackgroundView.kt",
"src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt",
"src/main/java/org/oppia/android/app/customview/SegmentedCircularProgressView.kt",
"src/main/java/org/oppia/android/app/customview/SurveyOnboardingBackgroundView.kt",
"src/main/java/org/oppia/android/app/customview/VerticalDashedLineView.kt",
"src/main/java/org/oppia/android/app/survey/SurveyMultipleChoiceOptionView.kt",
"src/main/java/org/oppia/android/app/survey/SurveyNpsItemOptionView.kt",
Expand Down
17 changes: 15 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<meta-data
android:name="expiration_date"
android:value="2020-09-01" />

<activity
android:name=".app.administratorcontrols.AdministratorControlsActivity"
android:label="@string/administrator_controls_title"
Expand All @@ -43,7 +44,7 @@
<activity
android:name=".app.administratorcontrols.learneranalytics.ProfileAndDeviceIdActivity"
android:label="@string/profile_and_device_id_activity_title"
android:theme="@style/OppiaThemeWithoutActionBar"/>
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".app.completedstorylist.CompletedStoryListActivity"
android:label="@string/completed_story_list_activity_title"
Expand Down Expand Up @@ -187,9 +188,9 @@
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".app.splash.SplashActivity"
android:exported="true"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:exported="true"
android:theme="@style/SplashScreenTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down Expand Up @@ -327,6 +328,18 @@
android:label="@string/survey_activity_title"
android:theme="@style/OppiaThemeWithoutActionBar"
android:windowSoftInputMode="adjustNothing" />
<activity
android:name=".app.onboarding.onboardingv2.OnboardingProfileTypeActivity"
android:label="@string/onboarding_profile_type_activity_title"
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".app.onboarding.onboardingv2.OnboardingLearnerIntroActivity"
android:label="@string/onboarding_learner_intro_activity_title"
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".app.onboarding.onboardingv2.NewLearnerProfileActivity"
android:label="@string/create_profile_activity_title"
android:theme="@style/OppiaThemeWithoutActionBar" />

<provider
android:name="androidx.work.impl.WorkManagerInitializer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import org.oppia.android.app.home.HomeActivity
import org.oppia.android.app.home.recentlyplayed.RecentlyPlayedActivity
import org.oppia.android.app.mydownloads.MyDownloadsActivity
import org.oppia.android.app.onboarding.OnboardingActivity
import org.oppia.android.app.onboarding.onboardingv2.NewLearnerProfileActivity
import org.oppia.android.app.onboarding.onboardingv2.OnboardingLearnerIntroActivity
import org.oppia.android.app.onboarding.onboardingv2.OnboardingProfileTypeActivity
import org.oppia.android.app.ongoingtopiclist.OngoingTopicListActivity
import org.oppia.android.app.options.AppLanguageActivity
import org.oppia.android.app.options.AudioLanguageActivity
Expand Down Expand Up @@ -123,6 +126,7 @@ interface ActivityComponentImpl :
appCompatCheckBoxBindingAdaptersTestActivity:
AppCompatCheckBoxBindingAdaptersTestActivity
)

fun inject(appLanguageActivity: AppLanguageActivity)
fun inject(appVersionActivity: AppVersionActivity)
fun inject(audioFragmentTestActivity: AudioFragmentTestActivity)
Expand Down Expand Up @@ -212,4 +216,7 @@ interface ActivityComponentImpl :
fun inject(viewEventLogsTestActivity: ViewEventLogsTestActivity)
fun inject(walkthroughActivity: WalkthroughActivity)
fun inject(surveyActivity: SurveyActivity)
fun inject(onboardingProfileTypeActivity: OnboardingProfileTypeActivity)
fun inject(onboardingLearnerIntroActivity: OnboardingLearnerIntroActivity)
fun inject(newLearnerProfileActivity: NewLearnerProfileActivity)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.oppia.android.app.customview

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
Expand All @@ -18,33 +18,38 @@ import org.oppia.android.app.view.ViewComponentImpl
import javax.inject.Inject

/**
* CustomView to add a background to [SurveyWelcomeDialogFragment] and [SurveyOutroDialogFragment].
* Without chaptersFinished and totalChapters values this custom-view cannot be created.
* CustomView to add a background to views that require a bezier curve background.
*
* Reference: // https://proandroiddev.com/how-i-drew-custom-shapes-in-bottom-bar-c4539d86afd7 and
* // https://ciechanow.ski/drawing-bezier-curves/
*/
class SurveyOnboardingBackgroundView : View {
@Inject
lateinit var resourceHandler: AppLanguageResourceHandler
class OppiaCurveBackgroundView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
/**
* Used to retrieve the layout direction that should be used to mirror the direction of the
* curve based on locale.
*/
@Inject lateinit var resourceHandler: AppLanguageResourceHandler

private val isRtl by lazy {
resourceHandler.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL
}

private var customBackgroundColor = Color.WHITE // Default color

private lateinit var paint: Paint
private lateinit var path: Path
private var strokeWidth = 2f

constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)

init {
val typedArray: TypedArray =
context.obtainStyledAttributes(attrs, R.styleable.OppiaCurveBackgroundView)
customBackgroundColor =
typedArray.getColor(R.styleable.OppiaCurveBackgroundView_customBackgroundColor, Color.WHITE)
typedArray.recycle()
setupCurvePaint()
}

Expand All @@ -61,10 +66,10 @@ class SurveyOnboardingBackgroundView : View {
val width = this.width.toFloat()
val height = this.height.toFloat()

val controlPoint1X = width * 0.5f
val controlPoint1X = width * 0.55f
val controlPoint1Y = 0f

val controlPoint2X = width * 0.5f
val controlPoint2X = width * 0.52f
val controlPoint2Y = height * 0.2f

val controlPoint3X = width * 1f
Expand All @@ -91,11 +96,8 @@ class SurveyOnboardingBackgroundView : View {
paint = Paint(Paint.ANTI_ALIAS_FLAG)
paint.apply {
style = Paint.Style.FILL_AND_STROKE
strokeWidth = [email protected]
color = ContextCompat.getColor(
context,
R.color.component_color_survey_popup_background_color
)
strokeWidth = [email protected]
color = customBackgroundColor
}
setBackgroundColor(Color.TRANSPARENT)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ import org.oppia.android.app.notice.GeneralAvailabilityUpgradeNoticeDialogFragme
import org.oppia.android.app.notice.OptionalAppDeprecationNoticeDialogFragment
import org.oppia.android.app.notice.OsDeprecationNoticeDialogFragment
import org.oppia.android.app.onboarding.OnboardingFragment
import org.oppia.android.app.onboarding.onboardingv2.NewLearnerProfileFragment
import org.oppia.android.app.onboarding.onboardingv2.OnboardingLearnerIntroFragment
import org.oppia.android.app.onboarding.onboardingv2.OnboardingProfileTypeFragment
import org.oppia.android.app.ongoingtopiclist.OngoingTopicListFragment
import org.oppia.android.app.options.AppLanguageFragment
import org.oppia.android.app.options.AudioLanguageFragment
Expand Down Expand Up @@ -194,4 +197,7 @@ interface FragmentComponentImpl : FragmentComponent, ViewComponentBuilderInjecto
fun inject(exitSurveyConfirmationDialogFragment: ExitSurveyConfirmationDialogFragment)
fun inject(surveyWelcomeDialogFragment: SurveyWelcomeDialogFragment)
fun inject(surveyOutroDialogFragment: SurveyOutroDialogFragment)
fun inject(onboardingProfileTypeFragment: OnboardingProfileTypeFragment)
fun inject(onboardingLearnerIntroFragment: OnboardingLearnerIntroFragment)
fun inject(newLearnerProfileFragment: NewLearnerProfileFragment)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@ import android.view.View
import android.view.ViewGroup
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
import org.oppia.android.util.platformparameter.EnableOnboardingFlowV2
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject
import org.oppia.android.app.onboarding.onboardingv2.OnboardingFragmentPresenter as OnboardingFragmentPresenterV2

/** Fragment that contains an onboarding flow of the app. */
class OnboardingFragment : InjectableFragment() {
@Inject
lateinit var onboardingFragmentPresenter: OnboardingFragmentPresenter

@Inject
lateinit var onboardingFragmentPresenterV2: OnboardingFragmentPresenterV2

@Inject
@field:EnableOnboardingFlowV2
lateinit var enableOnboardingFlowV2: PlatformParameterValue<Boolean>

override fun onAttach(context: Context) {
super.onAttach(context)
(fragmentComponent as FragmentComponentImpl).inject(this)
Expand All @@ -24,6 +34,10 @@ class OnboardingFragment : InjectableFragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return onboardingFragmentPresenter.handleCreateView(inflater, container)
return if (enableOnboardingFlowV2.value) {
onboardingFragmentPresenterV2.handleCreateView(inflater, container)
} else {
onboardingFragmentPresenter.handleCreateView(inflater, container)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.oppia.android.app.onboarding.onboardingv2

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.google.android.material.appbar.AppBarLayout
import org.oppia.android.R
import org.oppia.android.app.model.AudioLanguage
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.databinding.AudioLanguageSelectionFragmentBinding
import javax.inject.Inject

/** The presenter for [AudioLanguageFragment] V2. */
class AudioLanguageFragmentPresenter @Inject constructor(
private val fragment: Fragment,
private val activity: AppCompatActivity,
private val appLanguageResourceHandler: AppLanguageResourceHandler
) {
private lateinit var binding: AudioLanguageSelectionFragmentBinding

/**
* Returns a newly inflated view to render the fragment with the specified [audioLanguage] as the
* initial selected language.
*/
fun handleCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
audioLanguage: AudioLanguage
): View {

activity.findViewById<AppBarLayout>(R.id.reading_list_app_bar_layout).visibility = View.GONE

binding = AudioLanguageSelectionFragmentBinding.inflate(
inflater,
container,
/* attachToRoot= */ false
)
binding.let {
it.lifecycleOwner = fragment
}

binding.audioLanguageDropdown.adapter = ArrayAdapter(
fragment.requireContext(),
R.layout.onboarding_language_dropdown_item,
R.id.onboarding_language_text_view,
arrayOf("English")
adhiamboperes marked this conversation as resolved.
Show resolved Hide resolved
)

binding.audioLanguageText.text = appLanguageResourceHandler.getStringInLocaleWithWrapping(
R.string.audio_language_fragment_text,
activity.getString(R.string.app_name)
)

binding.onboardingNavigationContinue.setOnClickListener {
}
adhiamboperes marked this conversation as resolved.
Show resolved Hide resolved

binding.onboardingNavigationBack.setOnClickListener {
activity.finish()
}

return binding.root
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.oppia.android.app.onboarding.onboardingv2

import androidx.databinding.ObservableField
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.viewmodel.ObservableViewModel
import javax.inject.Inject

/** The ViewModel for [NewLearnerProfileFragment]. */
@FragmentScope
class CreateLearnerProfileViewModel @Inject constructor() : ObservableViewModel() {
/** ObservableField that tracks whether a nickname has been entered. */
val hasName = ObservableField(true)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.oppia.android.app.onboarding.onboardingv2

import android.content.Context
import android.content.Intent
import android.os.Bundle
import org.oppia.android.app.activity.ActivityComponentImpl
import org.oppia.android.app.activity.InjectableAutoLocalizedAppCompatActivity
import org.oppia.android.app.model.ScreenName
import org.oppia.android.util.logging.CurrentAppScreenNameIntentDecorator.decorateWithScreenName
import javax.inject.Inject

/** Activity for displaying a new learner profile creation flow. */
class NewLearnerProfileActivity : InjectableAutoLocalizedAppCompatActivity() {
@Inject
lateinit var learnerProfileActivityPresenter: NewLearnerProfileActivityPresenter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
(activityComponent as ActivityComponentImpl).inject(this)

learnerProfileActivityPresenter.handleOnCreate()
}

companion object {
/** Returns a new [Intent] open a [NewLearnerProfileActivity] with the specified params. */
fun createNewLearnerProfileActivity(context: Context): Intent {
return Intent(context, NewLearnerProfileActivity::class.java).apply {
decorateWithScreenName(ScreenName.CREATE_NEW_LEARNER_PROFILE_ACTIVITY)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.oppia.android.app.onboarding.onboardingv2

import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import org.oppia.android.R
import org.oppia.android.databinding.CreateProfileActivityBinding
import javax.inject.Inject

private const val TAG_CREATE_PROFILE_ACTIVITY_FRAGMENT = "TAG_CREATE_PROFILE_ACTIVITY_FRAGMENT"

/** Presenter for [NewLearnerProfileActivity]. */
class NewLearnerProfileActivityPresenter @Inject constructor(
private val activity: AppCompatActivity
) {
private lateinit var binding: CreateProfileActivityBinding

/** Handle creation and binding of the NewLearnerProfileActivity layout. */
fun handleOnCreate() {
binding = DataBindingUtil.setContentView(activity, R.layout.create_profile_activity)
binding.apply {
lifecycleOwner = activity
}

if (getNewLearnerProfileFragment() == null) {
val createLearnerProfileFragment = NewLearnerProfileFragment()
activity.supportFragmentManager.beginTransaction().add(
R.id.profile_fragment_placeholder,
createLearnerProfileFragment,
TAG_CREATE_PROFILE_ACTIVITY_FRAGMENT
)
.commitNow()
}
}

private fun getNewLearnerProfileFragment(): NewLearnerProfileFragment? {
return activity.supportFragmentManager.findFragmentByTag(
TAG_CREATE_PROFILE_ACTIVITY_FRAGMENT
) as? NewLearnerProfileFragment
}
}
Loading
Loading