From 1e96025b3b9b220bf8309877d521208d020fa819 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Wed, 15 Nov 2023 02:17:44 +0700 Subject: [PATCH 1/2] Update ios_unit_testing.yml --- .github/workflows/ios_unit_testing.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ios_unit_testing.yml b/.github/workflows/ios_unit_testing.yml index 95f659cf5e..d64c2d5bbe 100644 --- a/.github/workflows/ios_unit_testing.yml +++ b/.github/workflows/ios_unit_testing.yml @@ -16,6 +16,7 @@ defaults: jobs: test: + if: ${{ vars.IS_IOS_UNIT_TESTING_ENABLED == 'true' }} name: Run iOS unit tests runs-on: macos-13 timeout-minutes: 60 From eb45649140321a0d97074f9383a236dfc9c3275e Mon Sep 17 00:00:00 2001 From: Aleksandr Zhukov Date: Wed, 15 Nov 2023 15:01:34 +0400 Subject: [PATCH 2/2] ALTAPPS-1031: Android FillBlanks onboarding animation (#746) Implement FillBlanks onboarding animation --- ...blemOnboardingBottomSheetDialogFragment.kt | 110 ++++++++++++++++++ .../view/fragment/DefaultStepQuizFragment.kt | 32 ++--- ...QuizOnboardingBottomSheetDialogFragment.kt | 60 ---------- ...fragment_step_quiz_problem_onboarding.xml} | 4 +- ...fill_blanks_input_onboarding_animation.zip | Bin 0 -> 3919 bytes ...ill_blanks_select_onboarding_animation.zip | Bin 0 -> 3015 bytes ...fill_blanks_input_onboarding_animation.zip | Bin 0 -> 3943 bytes ...ill_blanks_select_onboarding_animation.zip | Bin 0 -> 3000 bytes .../step_quiz/presentation/StepQuizFeature.kt | 5 + 9 files changed, 128 insertions(+), 83 deletions(-) create mode 100644 androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/dialog/ProblemOnboardingBottomSheetDialogFragment.kt delete mode 100644 androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz_parsons/view/dialog/ParsonsStepQuizOnboardingBottomSheetDialogFragment.kt rename androidHyperskillApp/src/main/res/layout/{fragment_step_quiz_parsons_onboarding.xml => fragment_step_quiz_problem_onboarding.xml} (95%) create mode 100644 androidHyperskillApp/src/main/res/raw-night/fill_blanks_input_onboarding_animation.zip create mode 100644 androidHyperskillApp/src/main/res/raw-night/fill_blanks_select_onboarding_animation.zip create mode 100644 androidHyperskillApp/src/main/res/raw/fill_blanks_input_onboarding_animation.zip create mode 100644 androidHyperskillApp/src/main/res/raw/fill_blanks_select_onboarding_animation.zip diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/dialog/ProblemOnboardingBottomSheetDialogFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/dialog/ProblemOnboardingBottomSheetDialogFragment.kt new file mode 100644 index 0000000000..1815e8223a --- /dev/null +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/dialog/ProblemOnboardingBottomSheetDialogFragment.kt @@ -0,0 +1,110 @@ +package org.hyperskill.app.android.step_quiz.view.dialog + +import android.app.Dialog +import android.content.Context +import android.content.DialogInterface +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.RawRes +import by.kirich1409.viewbindingdelegate.viewBinding +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import org.hyperskill.app.android.R +import org.hyperskill.app.android.core.extensions.argument +import org.hyperskill.app.android.databinding.FragmentStepQuizProblemOnboardingBinding +import org.hyperskill.app.android.view.base.ui.extension.wrapWithTheme +import org.hyperskill.app.step_quiz.presentation.StepQuizFeature +import org.hyperskill.app.step_quiz_fill_blanks.model.FillBlanksMode + +class ProblemOnboardingBottomSheetDialogFragment : BottomSheetDialogFragment() { + + companion object { + const val TAG = "ProblemOnboardingBottomSheetDialogFragment" + + fun newInstance( + modalType: StepQuizFeature.ProblemOnboardingModal + ): ProblemOnboardingBottomSheetDialogFragment = + ProblemOnboardingBottomSheetDialogFragment().apply { + this.modalType = modalType + } + } + + private var modalType: StepQuizFeature.ProblemOnboardingModal by argument( + StepQuizFeature.ProblemOnboardingModal.serializer() + ) + + private val viewBinding: FragmentStepQuizProblemOnboardingBinding by viewBinding( + FragmentStepQuizProblemOnboardingBinding::bind + ) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setStyle(STYLE_NORMAL, R.style.TopCornersRoundedBottomSheetDialog) + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = + BottomSheetDialog(requireContext(), theme).also { dialog -> + dialog.setOnShowListener { + dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED + if (savedInstanceState == null) { + (parentFragment as? Callback)?.problemOnboardingShown(modalType) + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? = + inflater.wrapWithTheme(requireActivity()) + .inflate( + R.layout.fragment_step_quiz_problem_onboarding, + container, + false + ) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + with(viewBinding) { + parsonsOnboardingAnimation.setAnimation(getAnimation(modalType)) + parsonsOnboardingDescription.text = + getDescription(requireContext(), modalType) + } + } + + override fun onDismiss(dialog: DialogInterface) { + super.onDismiss(dialog) + (parentFragment as? Callback)?.problemOnboardingHidden(modalType) + } + + @RawRes + private fun getAnimation(modalType: StepQuizFeature.ProblemOnboardingModal): Int = + when (modalType) { + StepQuizFeature.ProblemOnboardingModal.Parsons -> R.raw.parsons_problem_onboarding_animation + is StepQuizFeature.ProblemOnboardingModal.FillBlanks -> when (modalType.mode) { + FillBlanksMode.INPUT -> R.raw.fill_blanks_input_onboarding_animation + FillBlanksMode.SELECT -> R.raw.fill_blanks_select_onboarding_animation + } + } + + private fun getDescription( + context: Context, + modalType: StepQuizFeature.ProblemOnboardingModal + ): String = + context.getString( + when (modalType) { + StepQuizFeature.ProblemOnboardingModal.Parsons -> + org.hyperskill.app.R.string.step_quiz_problem_onboarding_modal_parsons_description + is StepQuizFeature.ProblemOnboardingModal.FillBlanks -> + org.hyperskill.app.R.string.step_quiz_problem_onboarding_modal_fill_blanks_description + } + ) + + interface Callback { + fun problemOnboardingShown(modalType: StepQuizFeature.ProblemOnboardingModal) + fun problemOnboardingHidden(modalType: StepQuizFeature.ProblemOnboardingModal) + } +} \ No newline at end of file diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/fragment/DefaultStepQuizFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/fragment/DefaultStepQuizFragment.kt index 7d9bb34ad4..52be7e8312 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/fragment/DefaultStepQuizFragment.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/fragment/DefaultStepQuizFragment.kt @@ -37,11 +37,11 @@ import org.hyperskill.app.android.step.view.model.StepCompletionView import org.hyperskill.app.android.step.view.screen.StepScreen import org.hyperskill.app.android.step_quiz.view.delegate.StepQuizFeedbackBlocksDelegate import org.hyperskill.app.android.step_quiz.view.delegate.StepQuizFormDelegate +import org.hyperskill.app.android.step_quiz.view.dialog.ProblemOnboardingBottomSheetDialogFragment import org.hyperskill.app.android.step_quiz.view.factory.StepQuizViewStateDelegateFactory import org.hyperskill.app.android.step_quiz.view.mapper.StepQuizFeedbackMapper import org.hyperskill.app.android.step_quiz.view.model.StepQuizFeedbackState import org.hyperskill.app.android.step_quiz_hints.delegate.StepQuizHintsDelegate -import org.hyperskill.app.android.step_quiz_parsons.view.dialog.ParsonsStepQuizOnboardingBottomSheetDialogFragment import org.hyperskill.app.android.view.base.ui.extension.snackbar import org.hyperskill.app.step.domain.model.BlockName import org.hyperskill.app.step.domain.model.Step @@ -66,7 +66,7 @@ abstract class DefaultStepQuizFragment : ReduxView, StepCompletionView, MenuProvider, - ParsonsStepQuizOnboardingBottomSheetDialogFragment.Callback { + ProblemOnboardingBottomSheetDialogFragment.Callback { private lateinit var viewModelFactory: ViewModelProvider.Factory @@ -286,17 +286,11 @@ abstract class DefaultStepQuizFragment : .showIfNotExists(childFragmentManager, ProblemsLimitReachedBottomSheet.TAG) } is StepQuizFeature.Action.ViewAction.ShowProblemOnboardingModal -> { - when (action.modalType) { - StepQuizFeature.ProblemOnboardingModal.Parsons -> - ParsonsStepQuizOnboardingBottomSheetDialogFragment.newInstance() - .showIfNotExists( - childFragmentManager, - ParsonsStepQuizOnboardingBottomSheetDialogFragment.TAG - ) - is StepQuizFeature.ProblemOnboardingModal.FillBlanks -> { - // TODO: ALTAPPS-1031 Implement FillBlanks onboarding modal - } - } + ProblemOnboardingBottomSheetDialogFragment.newInstance(action.modalType) + .showIfNotExists( + childFragmentManager, + ProblemOnboardingBottomSheetDialogFragment.TAG + ) } is StepQuizFeature.Action.ViewAction.StepQuizHintsViewAction -> { stepQuizHintsDelegate?.onAction(action.viewAction) @@ -423,19 +417,15 @@ abstract class DefaultStepQuizFragment : } } - override fun parsonsProblemOnboardingShown() { + override fun problemOnboardingShown(modalType: StepQuizFeature.ProblemOnboardingModal) { stepQuizViewModel.onNewMessage( - StepQuizFeature.Message.ProblemOnboardingModalShownMessage( - modalType = StepQuizFeature.ProblemOnboardingModal.Parsons - ) + StepQuizFeature.Message.ProblemOnboardingModalShownMessage(modalType) ) } - override fun parsonsProblemOnboardingHidden() { + override fun problemOnboardingHidden(modalType: StepQuizFeature.ProblemOnboardingModal) { stepQuizViewModel.onNewMessage( - StepQuizFeature.Message.ProblemOnboardingModalHiddenMessage( - modalType = StepQuizFeature.ProblemOnboardingModal.Parsons - ) + StepQuizFeature.Message.ProblemOnboardingModalHiddenMessage(modalType) ) } diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz_parsons/view/dialog/ParsonsStepQuizOnboardingBottomSheetDialogFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz_parsons/view/dialog/ParsonsStepQuizOnboardingBottomSheetDialogFragment.kt deleted file mode 100644 index 9742a4cf66..0000000000 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz_parsons/view/dialog/ParsonsStepQuizOnboardingBottomSheetDialogFragment.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.hyperskill.app.android.step_quiz_parsons.view.dialog - -import android.app.Dialog -import android.content.DialogInterface -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog -import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import org.hyperskill.app.android.R -import org.hyperskill.app.android.view.base.ui.extension.wrapWithTheme - -class ParsonsStepQuizOnboardingBottomSheetDialogFragment : BottomSheetDialogFragment() { - - companion object { - const val TAG = "ParsonsStepQuizOnboardingBottomSheetDialogFragment" - - fun newInstance(): ParsonsStepQuizOnboardingBottomSheetDialogFragment = - ParsonsStepQuizOnboardingBottomSheetDialogFragment() - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setStyle(STYLE_NORMAL, R.style.TopCornersRoundedBottomSheetDialog) - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = - BottomSheetDialog(requireContext(), theme).also { dialog -> - dialog.setOnShowListener { - dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED - if (savedInstanceState == null) { - (parentFragment as? Callback)?.parsonsProblemOnboardingShown() - } - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? = - inflater.wrapWithTheme(requireActivity()) - .inflate( - R.layout.fragment_step_quiz_parsons_onboarding, - container, - false - ) - - override fun onDismiss(dialog: DialogInterface) { - super.onDismiss(dialog) - (parentFragment as? Callback)?.parsonsProblemOnboardingHidden() - } - - interface Callback { - fun parsonsProblemOnboardingShown() - fun parsonsProblemOnboardingHidden() - } -} \ No newline at end of file diff --git a/androidHyperskillApp/src/main/res/layout/fragment_step_quiz_parsons_onboarding.xml b/androidHyperskillApp/src/main/res/layout/fragment_step_quiz_problem_onboarding.xml similarity index 95% rename from androidHyperskillApp/src/main/res/layout/fragment_step_quiz_parsons_onboarding.xml rename to androidHyperskillApp/src/main/res/layout/fragment_step_quiz_problem_onboarding.xml index 2b29bf636b..57ea584b2a 100644 --- a/androidHyperskillApp/src/main/res/layout/fragment_step_quiz_parsons_onboarding.xml +++ b/androidHyperskillApp/src/main/res/layout/fragment_step_quiz_problem_onboarding.xml @@ -30,10 +30,10 @@ android:id="@+id/parsonsOnboardingAnimation" android:layout_width="match_parent" android:layout_height="wrap_content" - app:lottie_rawRes="@raw/parsons_problem_onboarding_animation" app:lottie_loop="true" app:lottie_autoPlay="true" - android:layout_marginTop="32dp"/> + android:layout_marginTop="32dp" + tools:lottie_rawRes="@raw/parsons_problem_onboarding_animation"/> 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 Q&I10azCWiI;osLk0BDpPmjD0& literal 0 HcmV?d00001 diff --git a/androidHyperskillApp/src/main/res/raw-night/fill_blanks_select_onboarding_animation.zip b/androidHyperskillApp/src/main/res/raw-night/fill_blanks_select_onboarding_animation.zip new file mode 100644 index 0000000000000000000000000000000000000000..06fb05cf8deecc0de9b25848e3df05ac1d919a54 GIT binary patch literal 3015 zcmbuBS5On^7Jx$y(jh1yU_up;5(KFtO^U=oBE80d!4(h)f=CI{>k_0RAR;A502|UF zsC1;GbV6B*gcghx0rBF@-MKsW?(EAwXU?4S&-`=F%lGghU<{0W0G5*!4)n4C{5z;8 z6E^??xQFq?xcbT8Li>6sxZm^kva;j=08OkcFzA!Ic~brl*Z_2lJ9GfR$rb=$!*R`f zN|pPk4LdHA>562}tY*apX3z03&O=_t$QYe@mdU zn|)te-(vE>cNdarEy5#LCcd*WWU2bd#4mhP@5~WUf|apkjI`G`L@iv4NNnxGN^(p) zYDa`X7$*+oOjXeR?0LplV;FGVa7ao^u1_w*G)Od ze6KO#)YoF8Mlt>a>MU!QLQS7LZT>vV3>z98D*N&R457;w-E~%r5-D~#ijm~C8^NjW zLNdNICg*tNxrHNIVpZ7bN#Fe&IG+|1Mh~8WQ{hB;qYY}OKAT*^4WmYu_N5vMIN zdS?iM`8czutPDsRWkBL#w#mvXN4?FN0iEWjM;s#oPvBQf{jU?!xF!y0%#7!B83MXp za%Cl9+HzTM$ZxWXTS_NznkjIvwJFA|^in|;qJ)P~v%>=l`eO}Srj$UtidbHIr~_v% z7BiaeDDJy>I&p1+$#w5eSvF;8zWdD1z>z3Sm5V0y;5QkI!`}M0=`(?XM7rN{@Xznd zPBwIyRs-((0_VxFm>5vEDtL`z((ak2$yqD4ZIfA16R_sF+HF^ukj^2!Q!#f*hW$~H ze5t;&pu1nKht^oeqZ`UdGzos{bGtO*neOY2m22=R20Dfe`VN=SpN|ao?1J_@B)@!$ zNfy!47~(MSS-jGES3w|;Ps42*=8D=iN0pE)UuDF9601pAD3Il`sI(N$8HN@sNjaaqiuP57Z9s90I$b&Kv@|JjOuTv~X8 zx3EkImJW!IW+}`U*_XkoX!w++P^E!puhu>N<~TTojSF-)>R}SnNkVEbOep)Q8!Vkw zUyBTM<_6h3ghhgCIiJ{w9N^wOCcp10uH~Q7h}uB~IK(@~wTaL<^E%+e zAp4Iw;c<5$J&ARM&o;Vxter0}ldHneNPiLHbE@SbFD6{X{IkNkT7XT((0FekbxYMcb~~>s8|hzGRFwgJ;Ki%NiHxAy?r%((1>H|v zR&MZeMyW}2bLY;Ph086c6KhNnrJ_Et>95s2vNu027-9H-y7Rqxv_ph!x#m}bM+~6m zFp-W@rwO4YYp3j3eHj56r&^4b;Le9(_>^!og?P=O#ue77e#3}2?a|4V7xF(AUpUD9 zP+{V9%h0EfSuAOAv(?I&yDarGuw-~fJ0D~ti=62e+6<_s_cvDPSJOqbrm&}F-;lr5kZW-Gibv!Jyr^Y+mK;*}I%zU9Y^grq{NxJ~>u{c6 z2}`1_z6(hh6nbJ-?5~*u_SaMju(wBiaC*$U+rg&{EK#jyS0ZO>y4%OA1=%Ik^vh1_ zNaM>3_APvA<1|*`*sc|z0#N3B&vyiLdkzm#-!63oL({tutVWqCeALs85V?UK)bRIl zCj(Iy+Ei65_6jCA#PxWkoqtKdN@OrgBKLgx(Sn*PvNTI><`{S0;p=WxogWW5Bwo=a z&*=Be{2vFxS-ovMsG3$f=6dYY!qpyIfjHZ`DVGv1ePg<`$+@w^_o7!QTsOP6P|vq+a*9$oI8y?4B=J1hF)=TX5bsY* zP1O4NL1^*Sh?2yC3}NJLaA7)+q*5?l!_}-?2@T?e%OHzmld7sj*RB;h`i6%t!)j*% z=^VCmapItum^a#L>U)v{*93fxrDD>JA?dcmh<7&Y5w9*^czDf+nv;AzU7MuD<+uGq zo!ePzqUhKocFg=I0|EwQnXv!XuE7ET{E`pE-)hMiJpdqdq9rI4T+hJV!d6iM^^b-U z`@e>gbVJ8`M3+w|S4VrPvH!#3JcGqW&oi)Y#5n^4YOnSmaq(5)!lE` zllK_iwA#Kj&aBQqub!`WYTR<4pvkQ64@Mk+DG*r456-`>_83SVOY6bACEwQYtzU}0 z3Ko8Md(BQ(y*<>RTwBRqvw~vv{PSosh=Nw`{sXEP8acuat~~g-3xZ~%tLsZ_M|FJ%9W;_$2!#QzU~5ilm^U(4uEvh$=;M1& literal 0 HcmV?d00001 diff --git a/androidHyperskillApp/src/main/res/raw/fill_blanks_input_onboarding_animation.zip b/androidHyperskillApp/src/main/res/raw/fill_blanks_input_onboarding_animation.zip new file mode 100644 index 0000000000000000000000000000000000000000..5aa9593d6333583048a529d9b56ac6eefcd3be25 GIT binary patch literal 3943 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 literal 0 HcmV?d00001 diff --git a/androidHyperskillApp/src/main/res/raw/fill_blanks_select_onboarding_animation.zip b/androidHyperskillApp/src/main/res/raw/fill_blanks_select_onboarding_animation.zip new file mode 100644 index 0000000000000000000000000000000000000000..d0251ec506d21134326cb55f712712923e8100c9 GIT binary patch literal 3000 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