Skip to content

Commit

Permalink
Merge branch 'Terms_of_Service' of https://github.com/ShubhadeepKarma…
Browse files Browse the repository at this point in the history
…kar/oppia-android into Terms_of_Service

	# the commit.
  • Loading branch information
ShubhadeepKarmakar committed Nov 2, 2023
2 parents 4e17e06 + 67efeac commit 21296ae
Show file tree
Hide file tree
Showing 159 changed files with 3,194 additions and 860 deletions.
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ If your PR includes UI-related changes, then:
- Add screenshots for portrait/landscape for both a tablet & phone of the before & after UI changes
- For the screenshots above, include both English and pseudo-localized (RTL) screenshots (see [RTL guide](https://github.com/oppia/oppia-android/wiki/RTL-Guidelines))
- Add a video showing the full UX flow with a screen reader enabled (see [accessibility guide](https://github.com/oppia/oppia-android/wiki/Accessibility-A11y-Guide))
- For PRs introducing new UI elements or color changes, both light and dark mode screenshots must be included
- Add a screenshot demonstrating that you ran affected Espresso tests locally & that they're passing
13 changes: 13 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@
android:name=".app.notice.testing.GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity"
android:label="@string/test_activity_label"
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".app.notice.testing.ForcedAppDeprecationNoticeDialogFragmentTestActivity"
android:label="@string/test_activity_label"
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".app.notice.testing.OptionalAppDeprecationNoticeDialogFragmentTestActivity"
android:label="@string/test_activity_label"
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".app.notice.testing.OsDeprecationNoticeDialogFragmentTestActivity"
android:label="@string/test_activity_label"
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".app.onboarding.OnboardingActivity"
android:label="@string/onboarding_activity_title"
Expand Down Expand Up @@ -138,6 +150,7 @@
<activity
android:name=".app.profile.AdminPinActivity"
android:label="@string/admin_pin_activity_title"
android:theme="@style/OppiaThemeWithoutActionBar"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".app.profile.PinPasswordActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.oppia.android.app.administratorcontrols.learneranalytics
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
Expand Down Expand Up @@ -228,7 +229,11 @@ class ControlButtonsViewModel private constructor(
val compressedMessage = ByteArrayOutputStream().also { byteOutputStream ->
GZIPOutputStream(byteOutputStream).use(::writeTo)
}.toByteArray()
return Base64.getEncoder().encodeToString(compressedMessage)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Base64.getEncoder().encodeToString(compressedMessage)
} else {
android.util.Base64.encodeToString(compressedMessage, 0)
}
}

private fun String.computeSha1Hash(machineLocale: OppiaLocale.MachineLocale): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatCheckBox;
import androidx.core.widget.CompoundButtonCompat;
import androidx.databinding.BindingAdapter;

/**
Expand All @@ -13,6 +14,6 @@ public final class AppCompatCheckBoxBindingAdapters {
/** Sets the button tint for the specified checkbox, via data-binding. */
@BindingAdapter("app:buttonTint")
public static void setButtonTint(@NonNull AppCompatCheckBox checkBox, @ColorInt int colorRgb) {
checkBox.setSupportButtonTintList(ColorStateList.valueOf(colorRgb));
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(colorRgb));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,21 @@ private static String getTimeAgo(View view, long lastVisitedTimestamp) {
} else if (timeDifferenceMillis < TimeUnit.MINUTES.toMillis(50)) {
return getPluralString(
resourceHandler,
R.plurals.minutes,
R.plurals.minutes_ago,
(int) TimeUnit.MILLISECONDS.toMinutes(timeDifferenceMillis)
);
} else if (timeDifferenceMillis < TimeUnit.DAYS.toMillis(1)) {
return getPluralString(
resourceHandler,
R.plurals.hours,
R.plurals.hours_ago,
(int) TimeUnit.MILLISECONDS.toHours(timeDifferenceMillis)
);
} else if (timeDifferenceMillis < TimeUnit.DAYS.toMillis(2)) {
return resourceHandler.getStringInLocale(R.string.yesterday);
}
return getPluralString(
resourceHandler,
R.plurals.days,
R.plurals.days_ago,
(int) TimeUnit.MILLISECONDS.toDays(timeDifferenceMillis)
);
}
Expand All @@ -107,13 +107,9 @@ private static String getPluralString(
@PluralsRes int pluralsResId,
int count
) {
// TODO(#3841): Combine these strings together.
return resourceHandler.getStringInLocaleWithWrapping(
R.string.time_ago,
resourceHandler.getQuantityStringInLocaleWithWrapping(
return resourceHandler.getQuantityStringInLocaleWithWrapping(
pluralsResId, count, String.valueOf(count)
)
);
);
}

private static long ensureTimestampIsInMilliseconds(long lastVisitedTimestamp) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,40 @@ class NavigationDrawerHeaderViewModel @Inject constructor(
val profile = ObservableField(Profile.getDefaultInstance())
private var ongoingTopicCount = DEFAULT_ONGOING_TOPIC_COUNT
private var completedStoryCount = DEFAULT_COMPLETED_STORY_COUNT
val profileProgressText: ObservableField<String> = ObservableField(computeProfileProgressText())
val profileTopicProgressText: ObservableField<String> =
ObservableField(computeProfileTopicProgressText())
val profileStoryProgressText: ObservableField<String> =
ObservableField(computeProfileStoryProgressText())

fun onHeaderClicked() {
routeToProfileProgressListener.routeToProfileProgress(profile.get()!!.id.internalId)
}

fun setOngoingTopicProgress(ongoingTopicCount: Int) {
this.ongoingTopicCount = ongoingTopicCount
profileProgressText.set(computeProfileProgressText())
profileTopicProgressText.set(computeProfileTopicProgressText())
}

fun setCompletedStoryProgress(completedStoryCount: Int) {
this.completedStoryCount = completedStoryCount
profileProgressText.set(computeProfileProgressText())
profileStoryProgressText.set(computeProfileStoryProgressText())
}

private fun computeProfileProgressText(): String {
// TODO(#3843): Either combine these strings into one or use separate views to display them.
val completedStoryCountText =
resourceHandler.getQuantityStringInLocaleWithWrapping(
R.plurals.completed_story_count, completedStoryCount, completedStoryCount.toString()
)
val ongoingTopicCountText =
resourceHandler.getQuantityStringInLocaleWithWrapping(
R.plurals.ongoing_topic_count, ongoingTopicCount, ongoingTopicCount.toString()
)
val barSeparator = resourceHandler.getStringInLocale(R.string.bar_separator)
return "$completedStoryCountText$barSeparator$ongoingTopicCountText"
private fun computeProfileStoryProgressText(): String {
return resourceHandler.getQuantityStringInLocaleWithWrapping(
R.plurals.completed_story_count,
completedStoryCount,
completedStoryCount.toString()
)
}

fun getBarSeparator() = resourceHandler.getStringInLocale(R.string.bar_separator)

private fun computeProfileTopicProgressText(): String {
return resourceHandler.getQuantityStringInLocaleWithWrapping(
R.plurals.ongoing_topic_count,
ongoingTopicCount,
ongoingTopicCount.toString()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ import org.oppia.android.app.mydownloads.MyDownloadsFragment
import org.oppia.android.app.mydownloads.UpdatesTabFragment
import org.oppia.android.app.notice.AutomaticAppDeprecationNoticeDialogFragment
import org.oppia.android.app.notice.BetaNoticeDialogFragment
import org.oppia.android.app.notice.ForcedAppDeprecationNoticeDialogFragment
import org.oppia.android.app.notice.GeneralAvailabilityUpgradeNoticeDialogFragment
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.ongoingtopiclist.OngoingTopicListFragment
import org.oppia.android.app.options.AppLanguageFragment
Expand Down Expand Up @@ -113,7 +116,10 @@ interface FragmentComponentImpl : FragmentComponent, ViewComponentBuilderInjecto
fun inject(appVersionFragment: AppVersionFragment)
fun inject(audioFragment: AudioFragment)
fun inject(audioLanguageFragment: AudioLanguageFragment)
fun inject(autoAppDeprecationNoticeDialogFragment: AutomaticAppDeprecationNoticeDialogFragment)
fun inject(
automaticAppDeprecationNoticeDialogFragment:
AutomaticAppDeprecationNoticeDialogFragment
)
fun inject(betaNoticeDialogFragment: BetaNoticeDialogFragment)
fun inject(cellularAudioDialogFragment: CellularAudioDialogFragment)
fun inject(completedStoryListFragment: CompletedStoryListFragment)
Expand All @@ -127,6 +133,7 @@ interface FragmentComponentImpl : FragmentComponent, ViewComponentBuilderInjecto
fun inject(explorationTestActivityTestFragment: ExplorationTestActivityPresenter.TestFragment)
fun inject(faqListFragment: FAQListFragment)
fun inject(forceNetworkTypeFragment: ForceNetworkTypeFragment)
fun inject(forcedAppDeprecationNoticeDialogFragment: ForcedAppDeprecationNoticeDialogFragment)
fun inject(fragment: GeneralAvailabilityUpgradeNoticeDialogFragment)
fun inject(helpFragment: HelpFragment)
fun inject(hintsAndSolutionDialogFragment: HintsAndSolutionDialogFragment)
Expand All @@ -146,7 +153,9 @@ interface FragmentComponentImpl : FragmentComponent, ViewComponentBuilderInjecto
fun inject(navigationDrawerFragment: NavigationDrawerFragment)
fun inject(onboardingFragment: OnboardingFragment)
fun inject(ongoingTopicListFragment: OngoingTopicListFragment)
fun inject(optionalAppDeprecationNoticeDialogFragment: OptionalAppDeprecationNoticeDialogFragment)
fun inject(optionFragment: OptionsFragment)
fun inject(osDeprecationNoticeDialogFragment: OsDeprecationNoticeDialogFragment)
fun inject(policiesFragment: PoliciesFragment)
fun inject(profileAndDeviceIdFragment: ProfileAndDeviceIdFragment)
fun inject(profileChooserFragment: ProfileChooserFragment)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.databinding.LicenseTextViewerActivityBinding
import org.oppia.android.util.accessibility.AccessibilityService
import javax.inject.Inject

/** The presenter for [LicenseTextViewerActivity]. */
Expand All @@ -14,6 +15,7 @@ class LicenseTextViewerActivityPresenter @Inject constructor(
private val activity: AppCompatActivity,
private val resourceHandler: AppLanguageResourceHandler
) {
@Inject lateinit var accessibilityService: AccessibilityService

/** Handles onCreate() method of the [LicenseTextViewerActivity]. */
fun handleOnCreate(dependencyIndex: Int, licenseIndex: Int) {
Expand Down Expand Up @@ -44,8 +46,10 @@ class LicenseTextViewerActivityPresenter @Inject constructor(
(activity as LicenseTextViewerActivity).finish()
}

binding.licenseTextViewerActivityToolbarTitle.setOnClickListener {
binding.licenseTextViewerActivityToolbarTitle.isSelected = true
if (!accessibilityService.isScreenReaderEnabled()) {
binding.licenseTextViewerActivityToolbarTitle.setOnClickListener {
binding.licenseTextViewerActivityToolbarTitle.isSelected = true
}
}

if (getLicenseTextViewerFragment() == null) {
Expand Down
15 changes: 14 additions & 1 deletion app/src/main/java/org/oppia/android/app/home/HomeViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.oppia.android.app.home

import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.ObservableField
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
Expand Down Expand Up @@ -58,6 +59,15 @@ class HomeViewModel(
R.integer.promoted_story_list_limit
)

/**
* A Boolean property indicating the visibility state of a progress bar.
* This property is used to control the visibility of a progress bar in a user interface.
* When set to true, the progress bar is made visible, indicating that an ongoing task
* or operation is in progress or pending or failed. When set to false, the progress bar is hidden, indicating
* that the operation has completed.
*/
val isProgressBarVisible = ObservableField(true)

private val profileDataProvider: DataProvider<Profile> by lazy {
profileManagementController.getProfile(profileId)
}
Expand Down Expand Up @@ -111,7 +121,10 @@ class HomeViewModel(
listOf()
}
is AsyncResult.Pending -> listOf()
is AsyncResult.Success -> itemListResult.value
is AsyncResult.Success -> {
isProgressBarVisible.set(false)
itemListResult.value
}
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions app/src/main/java/org/oppia/android/app/home/WelcomeViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ class WelcomeViewModel(
dateTimeUtil: DateTimeUtil
) : HomeItemViewModel() {

/** Text [String] to greet the learner and display on-screen when launching the home activity. */
/** Text [String] to greet the learner. */
val greeting: String = dateTimeUtil.getGreetingMessage()

/**
* Returns the user-readable portion of the welcome screen greeting that contains the user's name.
* Returns the string which contains greeting message with user's name and
* display on-screen when launching the home activity.
*/
fun computeProfileNameText(): String {
return resourceHandler.getStringInLocaleWithWrapping(R.string.welcome_profile_name, profileName)
}
fun computeWelcomeText(): String = resourceHandler.getStringInLocaleWithWrapping(
R.string.welcome_profile_name,
greeting,
profileName
)

// Overriding equals is needed so that DataProvider combine functions used in the HomeViewModel
// will only rebind when the actual data in the data list changes, rather than when the ViewModel
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.oppia.android.app.notice

import org.oppia.android.app.splash.DeprecationNoticeActionType

/** Listener for when an option on any deprecation dialog is clicked. */
interface DeprecationNoticeActionListener {
/** Called when a dialog button is clicked. */
fun onActionButtonClicked(noticeType: DeprecationNoticeActionType)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.oppia.android.app.notice

import android.app.Dialog
import android.content.Context
import android.os.Bundle
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableDialogFragment
import javax.inject.Inject

/** Dialog fragment that informs the user of an app deprecation. */
class ForcedAppDeprecationNoticeDialogFragment : InjectableDialogFragment() {
companion object {
/** Returns a new instance of [ForcedAppDeprecationNoticeDialogFragment]. */
fun newInstance(): ForcedAppDeprecationNoticeDialogFragment {
return ForcedAppDeprecationNoticeDialogFragment()
}
}

@Inject lateinit var presenter: ForcedAppDeprecationNoticeDialogFragmentPresenter

override fun onAttach(context: Context) {
super.onAttach(context)
(fragmentComponent as FragmentComponentImpl).inject(this)
}

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return presenter.handleOnCreateDialog()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.oppia.android.app.notice

import android.app.Dialog
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import org.oppia.android.R
import org.oppia.android.app.splash.DeprecationNoticeActionType
import org.oppia.android.app.translation.AppLanguageResourceHandler
import javax.inject.Inject

/** Presenter class responsible for showing an app deprecation dialog to the user. */
class ForcedAppDeprecationNoticeDialogFragmentPresenter @Inject constructor(
private val activity: AppCompatActivity,
private val resourceHandler: AppLanguageResourceHandler
) {
private val deprecationNoticeActionListener by lazy {
activity as DeprecationNoticeActionListener
}

/** Handles dialog creation for the forced app deprecation notice. */
fun handleOnCreateDialog(): Dialog {
val appName = resourceHandler.getStringInLocale(R.string.app_name)

val dialog = AlertDialog.Builder(activity, R.style.DeprecationAlertDialogTheme)
.setTitle(R.string.forced_app_update_dialog_title)
.setMessage(
resourceHandler.getStringInLocaleWithWrapping(
R.string.forced_app_update_dialog_message,
appName
)
)
.setPositiveButton(R.string.forced_app_update_dialog_update_button_text) { _, _ ->
deprecationNoticeActionListener.onActionButtonClicked(
DeprecationNoticeActionType.UPDATE
)
}
.setNegativeButton(R.string.forced_app_update_dialog_close_button_text) { _, _ ->
deprecationNoticeActionListener.onActionButtonClicked(
DeprecationNoticeActionType.CLOSE
)
}
.setCancelable(false)
.create()
dialog.setCanceledOnTouchOutside(false)
return dialog
}
}
Loading

0 comments on commit 21296ae

Please sign in to comment.