diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 820522d91e7..00eecd1848f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,7 +6,6 @@ - - - + + + + android:theme="@style/OppiaThemeWithoutActionBar" /> @@ -308,7 +312,8 @@ - + + override fun onAttach(context: Context) { super.onAttach(context) (fragmentComponent as FragmentComponentImpl).inject(this) @@ -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) + } } } diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt index 1551e6c4199..80c4940d6bb 100644 --- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt @@ -52,6 +52,7 @@ class OnboardingFragmentPresenter @Inject constructor( } setUpViewPager() addDots() + return binding.root } diff --git a/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingFragmentPresenter.kt new file mode 100644 index 00000000000..5bec327b02f --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingFragmentPresenter.kt @@ -0,0 +1,55 @@ +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 org.oppia.android.R +import org.oppia.android.app.fragment.FragmentScope +import org.oppia.android.app.onboarding.OnboardingViewModel +import org.oppia.android.app.viewmodel.ViewModelProvider +import org.oppia.android.databinding.OnboardingAppLanguageSelectionFragmentBinding +import javax.inject.Inject + +/** The presenter for [OnboardingFragment] V2. */ +@FragmentScope +class OnboardingFragmentPresenter @Inject constructor( + private val activity: AppCompatActivity, + private val fragment: Fragment, + private val viewModelProvider: ViewModelProvider +) { + private lateinit var binding: OnboardingAppLanguageSelectionFragmentBinding + + fun handleCreateView(inflater: LayoutInflater, container: ViewGroup?): View { + binding = OnboardingAppLanguageSelectionFragmentBinding.inflate( + inflater, + container, + /* attachToRoot= */ false + ) + // NB: Both the view model and lifecycle owner must be set in order to correctly bind LiveData elements to + // data-bound view models. + binding.let { + it.lifecycleOwner = fragment + } + + binding.onboardingLanguageDropdown.adapter = ArrayAdapter( + fragment.requireContext(), + R.layout.onboarding_language_dropdown_item, + R.id.onboarding_language_text_view, + arrayOf("English") + ) + + binding.onboardingLanguageLetsGoButton.setOnClickListener { + val intent = OnboardingProfileTypeActivity.createOnboardingProfileTypeActivityIntent(activity) + fragment.startActivity(intent) + } + + return binding.root + } + + private fun getOnboardingViewModel(): OnboardingViewModel { + return viewModelProvider.getForFragment(fragment, OnboardingViewModel::class.java) + } +} diff --git a/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeActivity.kt b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeActivity.kt new file mode 100644 index 00000000000..bea2bc36c83 --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeActivity.kt @@ -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 + +/** The activity for showing the profile type selection screen. */ +class OnboardingProfileTypeActivity : InjectableAutoLocalizedAppCompatActivity() { + @Inject + lateinit var onboardingProfileTypeActivityPresenter: OnboardingProfileTypeActivityPresenter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + (activityComponent as ActivityComponentImpl).inject(this) + + onboardingProfileTypeActivityPresenter.handleOnCreate() + } + + companion object { + /** Returns a new [Intent] open a [OnboardingProfileTypeActivity] with the specified params. */ + fun createOnboardingProfileTypeActivityIntent(context: Context): Intent { + return Intent(context, OnboardingProfileTypeActivity::class.java).apply { + decorateWithScreenName(ScreenName.ONBOARDING_PROFILE_TYPE_ACTIVITY) + } + } + } +} diff --git a/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeActivityPresenter.kt new file mode 100644 index 00000000000..f678ed058c3 --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeActivityPresenter.kt @@ -0,0 +1,42 @@ +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.app.activity.ActivityScope +import org.oppia.android.databinding.OnboardingProfileTypeActivityBinding +import javax.inject.Inject + +private const val TAG_PROFILE_TYPE_FRAGMENT = "TAG_PROFILE_TYPE_FRAGMENT" + +/** The Presenter for [OnboardingProfileTypeActivity]. */ +@ActivityScope +class OnboardingProfileTypeActivityPresenter @Inject constructor( + private val activity: AppCompatActivity +) { + private lateinit var binding: OnboardingProfileTypeActivityBinding + + /** Handle creation and binding of the OnboardingProfileTypeActivity layout. */ + fun handleOnCreate() { + binding = DataBindingUtil.setContentView(activity, R.layout.onboarding_profile_type_activity) + binding.apply { + lifecycleOwner = activity + } + + if (getOnboardingProfileTypeFragment() == null) { + val onboardingProfileTypeFragment = OnboardingProfileTypeFragment() + activity.supportFragmentManager.beginTransaction().add( + R.id.profile_type_fragment_placeholder, + onboardingProfileTypeFragment, + TAG_PROFILE_TYPE_FRAGMENT + ) + .commitNow() + } + } + + private fun getOnboardingProfileTypeFragment(): OnboardingProfileTypeFragment? { + return activity.supportFragmentManager.findFragmentByTag( + TAG_PROFILE_TYPE_FRAGMENT + ) as? OnboardingProfileTypeFragment + } +} diff --git a/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeFragment.kt new file mode 100644 index 00000000000..662d95c4b2c --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeFragment.kt @@ -0,0 +1,29 @@ +package org.oppia.android.app.onboarding.onboardingv2 + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import org.oppia.android.app.fragment.FragmentComponentImpl +import org.oppia.android.app.fragment.InjectableFragment +import javax.inject.Inject + +/** Fragment that contains an onboarding flow of the app. */ +class OnboardingProfileTypeFragment : InjectableFragment() { + @Inject + lateinit var onboardingProfileTypeFragmentPresenter: OnboardingProfileTypeFragmentPresenter + + override fun onAttach(context: Context) { + super.onAttach(context) + (fragmentComponent as FragmentComponentImpl).inject(this) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return onboardingProfileTypeFragmentPresenter.handleCreateView(inflater, container) + } +} diff --git a/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeFragmentPresenter.kt new file mode 100644 index 00000000000..cd23af399f3 --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/onboarding/onboardingv2/OnboardingProfileTypeFragmentPresenter.kt @@ -0,0 +1,28 @@ +package org.oppia.android.app.onboarding.onboardingv2 + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import org.oppia.android.databinding.OnboardingProfileTypeFragmentBinding +import javax.inject.Inject + +/** The presenter for [OnboardingProfileTypeFragment]. */ +class OnboardingProfileTypeFragmentPresenter @Inject constructor( + private val fragment: Fragment +) { + private lateinit var binding: OnboardingProfileTypeFragmentBinding + + /** Handle creation and binding of the OnboardingProfileTypeFragment layout. */ + fun handleCreateView(inflater: LayoutInflater, container: ViewGroup?): View { + binding = OnboardingProfileTypeFragmentBinding.inflate( + inflater, + container, + /* attachToRoot= */ false + ) + binding.let { + it.lifecycleOwner = fragment + } + return binding.root + } +} diff --git a/app/src/main/java/org/oppia/android/app/survey/SurveyActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/survey/SurveyActivityPresenter.kt index 8020dfe8796..5e670f1ca6a 100644 --- a/app/src/main/java/org/oppia/android/app/survey/SurveyActivityPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/survey/SurveyActivityPresenter.kt @@ -20,6 +20,7 @@ const val EXPLORATION_ID_ARGUMENT_KEY = "exploration_id" class SurveyActivityPresenter @Inject constructor(private val activity: AppCompatActivity) { private lateinit var binding: SurveyActivityBinding + /** Handle creation and binding of the SurveyActivity layout. */ fun handleOnCreate( profileId: ProfileId, topicId: String, diff --git a/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt b/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt index 08726cc7f49..ecb07ff3e28 100644 --- a/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt +++ b/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt @@ -6,9 +6,9 @@ import dagger.Subcomponent import org.oppia.android.app.customview.ChapterNotStartedContainerConstraintLayout import org.oppia.android.app.customview.ContinueButtonView import org.oppia.android.app.customview.LessonThumbnailImageView +import org.oppia.android.app.customview.OppiaCurveBackgroundView import org.oppia.android.app.customview.PromotedStoryCardView import org.oppia.android.app.customview.SegmentedCircularProgressView -import org.oppia.android.app.customview.SurveyOnboardingBackgroundView import org.oppia.android.app.home.promotedlist.ComingSoonTopicsListView import org.oppia.android.app.home.promotedlist.PromotedStoryListView import org.oppia.android.app.player.state.DragDropSortInteractionView @@ -42,7 +42,7 @@ interface ViewComponentImpl : ViewComponent { fun inject(promotedStoryCardView: PromotedStoryCardView) fun inject(promotedStoryListView: PromotedStoryListView) fun inject(segmentedCircularProgressView: SegmentedCircularProgressView) - fun inject(surveyOnboardingBackgroundView: SurveyOnboardingBackgroundView) + fun inject(curveBackgroundView: OppiaCurveBackgroundView) fun inject(surveyMultipleChoiceOptionView: SurveyMultipleChoiceOptionView) fun inject(surveyNpsItemOptionView: SurveyNpsItemOptionView) } diff --git a/app/src/main/res/drawable/dropdown_background.xml b/app/src/main/res/drawable/dropdown_background.xml new file mode 100644 index 00000000000..e3410cbd007 --- /dev/null +++ b/app/src/main/res/drawable/dropdown_background.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_language_icon_black_24dp.xml b/app/src/main/res/drawable/ic_language_icon_black_24dp.xml new file mode 100644 index 00000000000..e89dd7a2a58 --- /dev/null +++ b/app/src/main/res/drawable/ic_language_icon_black_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/img_onboarding_language_background.xml b/app/src/main/res/drawable/img_onboarding_language_background.xml new file mode 100644 index 00000000000..5139b28b0f9 --- /dev/null +++ b/app/src/main/res/drawable/img_onboarding_language_background.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/img_tablet_portrait_onboarding_language_background.xml b/app/src/main/res/drawable/img_tablet_portrait_onboarding_language_background.xml new file mode 100644 index 00000000000..3077059c170 --- /dev/null +++ b/app/src/main/res/drawable/img_tablet_portrait_onboarding_language_background.xml @@ -0,0 +1,135 @@ + + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/rounded_primary_button_grey_shadow_color.xml b/app/src/main/res/drawable/rounded_primary_button_grey_shadow_color.xml index 1566be1839b..a117010c34c 100644 --- a/app/src/main/res/drawable/rounded_primary_button_grey_shadow_color.xml +++ b/app/src/main/res/drawable/rounded_primary_button_grey_shadow_color.xml @@ -7,7 +7,7 @@ - + diff --git a/app/src/main/res/layout-land/survey_welcome_dialog_fragment.xml b/app/src/main/res/layout-land/survey_welcome_dialog_fragment.xml index 9a41b4cf558..86fd12d45b6 100644 --- a/app/src/main/res/layout-land/survey_welcome_dialog_fragment.xml +++ b/app/src/main/res/layout-land/survey_welcome_dialog_fragment.xml @@ -10,9 +10,10 @@ android:id="@+id/survey_onboarding_title_text" style="@style/SurveyPopupHeaderStyle" android:text="@string/survey_onboarding_title_text" + + app:layout_constraintBottom_toTopOf="@id/survey_onboarding_title_guide" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintBottom_toTopOf="@id/survey_onboarding_title_guide" app:layout_constraintTop_toTopOf="parent" /> -