Skip to content

Commit

Permalink
Fix #4641, #4674, #4579, #4591: Assorted beta fixes (#4685)
Browse files Browse the repository at this point in the history
## Explanation
Fixes #4641
Fixes #4674
Fixes #4579
Fixes #4591

Miscellaneous fixes for Beta MR2. Specifically:
- #4641 is addressed by updating the terms of service wording. No test
is needed here since manual verification is sufficient.
- #4674 is addressed by replacing the existing automatic topic updates
platform with a generic "all downloads" one (which will be used for all
downloads gating moving forward). Admin controls, add profile, and
profile edit pages have been updated to only show downloads-related
settings if this flag is enabled. Corresponding tests have been updated.
FAQ question 8 was also removed since it asks about how to download
lessons, and this support isn't in the app yet. Some strings referencing
downloads have also been updated.
- #4579 is addressed by properly handling the case where unpublish
topics with previous progress would cause the topic list to fail to
load. A test was added to verify the fix, but it required a new
FakeAssetRepository to be introduced.
- #4591 is addressed by fixing
FractionInputHasIntegerPartEqualToRuleClassifierProvider's input type
(which should be SIGNED_INT but was incorrectly NON_NEGATIVE_INT before;
this seems to have been wrong since the classifier was introduced).

Test exemption: FakeAssetRepository doesn't have a test added since it
uses a real production AssetRepository, and tests don't yet exist for
that). They ought to be tested together.

## Essential Checklist
- [x] The PR title and explanation each start with "Fix #bugnum: " (If
this PR fixes part of an issue, prefix the title with "Fix part of
#bugnum: ...".)
- [x] Any changes to
[scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets)
files have their rationale included in the PR explanation.
- [x] The PR follows the [style
guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android
Studio
([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and
is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers
([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).

## For UI-specific PRs only
Screenshots showing the before & after changes due to hiding downloads
options:
| | Without changes | With changes |

|------------------|-----------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
| Profile creation |
![image](https://user-images.githubusercontent.com/12983742/200823396-bd12d392-a2f4-4881-b12a-b4dc4168d078.png)
|
![image](https://user-images.githubusercontent.com/12983742/200821992-9ec50696-80f3-47d7-aa13-515f7317ab9a.png)
|
| Profile edit |
![image](https://user-images.githubusercontent.com/12983742/200823563-694a82e8-67e7-4568-b4f0-7a17967f82b1.png)
|
![image](https://user-images.githubusercontent.com/12983742/200822179-8fc84d83-7add-49f4-a2db-6ddb8c7150eb.png)
|
| Admin controls |
![image](https://user-images.githubusercontent.com/12983742/200823499-3e5f5e92-db98-455a-a8e6-56b26b562554.png)
|
![image](https://user-images.githubusercontent.com/12983742/200822125-7243faad-78e1-40e6-8c09-c0610c7a01f6.png)
|

Espresso test rules for affected UI tests:
| Affected Test | Test Results |

|-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| AdministratorControlsActivityTest | (Skipped since there are tablet
tests to also run, so the suite won't actually pass cleanly) |
| ProfileEditActivityTest | (Same as above) |
| AdministratorControlsFragmentTest |
![oppia_assorted_beta_fixes_passing_admin_controls_fragment_test](https://user-images.githubusercontent.com/12983742/200824315-2f54ee80-570e-45f9-85ce-a2c094bf5058.png)
|
| ProfileEditFragmentTest |
![oppia_assorted_beta_fixes_passing_profile_edit_fragment_test](https://user-images.githubusercontent.com/12983742/200824336-949122e8-f718-4a02-9f13-5559ba8a2726.png)
|

New Robolectric tests failing for corresponding regressions:
| Issue | Test Suite | Failure Specifics | Failure Results |

|-------|--------------------------------------------------------------|-------------------|---------------------------------------------------------------------------------------------------------------------------------------|
| #4579 | TopicListControllerTest | 1/36 tests fail |
![failing_topic_list_test](https://user-images.githubusercontent.com/12983742/200827182-dde7ab82-f6e2-4e58-b116-073653673441.png)
|
| #4591 | FractionInputHasIntegerPartEqualToRuleClassifierProviderTest |
22/23 tests fail |
![oppia_failing_fraction_test](https://user-images.githubusercontent.com/12983742/200826395-e0c384ab-920c-45b5-be88-82b19c3bfed0.png)
|

Missing artifacts:
- Accessibility: not particularly relevant to these changes since the
user-facing changes are either crash fixes or removing UI elements
(except in the case of terms of service, but that doesn't require
additional a11y testing coverage or demonstration here).
- RTL: nothing in this change affects RTL specifically.
- Landscape: since the main UI changes are removing elements, the
changes to tablet aren't very "interesting" to show off.
- Tablet: same rationale as for landscape.
- Internationalization: same rationale as RTL.
  • Loading branch information
BenHenning authored Nov 10, 2022
1 parent 69c9a2b commit 76bf81a
Show file tree
Hide file tree
Showing 32 changed files with 447 additions and 227 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.platformparameter.AutomaticUpdateTopicSetting
import org.oppia.android.util.platformparameter.EnableDownloadsSupport
import org.oppia.android.util.platformparameter.EnableEditAccountsOptionsUi
import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
import org.oppia.android.util.platformparameter.PlatformParameterValue
Expand All @@ -36,7 +36,7 @@ class AdministratorControlsViewModel @Inject constructor(
@EnableEditAccountsOptionsUi
private val enableEditAccountsOptionsUi: PlatformParameterValue<Boolean>,
@LearnerStudyAnalytics private val learnerStudyAnalytics: PlatformParameterValue<Boolean>,
@AutomaticUpdateTopicSetting private val automaticallyUpdateTopic: PlatformParameterValue<Boolean>
@EnableDownloadsSupport private val enableDownloadsSupport: PlatformParameterValue<Boolean>
) {
private val routeToProfileListListener = activity as RouteToProfileListListener
private val loadProfileListListener = activity as LoadProfileListListener
Expand Down Expand Up @@ -94,16 +94,17 @@ class AdministratorControlsViewModel @Inject constructor(
itemViewModelList.add(AdministratorControlsProfileAndDeviceIdViewModel(activity))
}

itemViewModelList.add(
AdministratorControlsDownloadPermissionsViewModel(
fragment,
oppiaLogger,
profileManagementController,
userProfileId,
deviceSettings,
automaticallyUpdateTopic.value
if (enableDownloadsSupport.value) {
itemViewModelList.add(
AdministratorControlsDownloadPermissionsViewModel(
fragment,
oppiaLogger,
profileManagementController,
userProfileId,
deviceSettings
)
)
)
}

itemViewModelList.add(AdministratorControlsAppInformationViewModel(activity))
itemViewModelList.add(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,8 @@ class AdministratorControlsDownloadPermissionsViewModel(
private val oppiaLogger: OppiaLogger,
private val profileManagementController: ProfileManagementController,
private val userProfileId: ProfileId,
deviceSettings: DeviceSettings,
private val automaticallyUpdateTopic: Boolean,
deviceSettings: DeviceSettings
) : AdministratorControlsItemViewModel() {

val isVisible = ObservableField(automaticallyUpdateTopic)

val isTopicWifiUpdatePermission =
ObservableField<Boolean>(deviceSettings.allowDownloadAndUpdateOnlyOnWifi)
val isTopicAutoUpdatePermission =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.utility.TextInputEditTextHelper.Companion.onTextChanged
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.AddProfileActivityBinding
import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.platformparameter.EnableDownloadsSupport
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject

const val GALLERY_INTENT_RESULT_CODE = 1
Expand All @@ -40,13 +41,11 @@ const val GALLERY_INTENT_RESULT_CODE = 1
class AddProfileActivityPresenter @Inject constructor(
private val activity: AppCompatActivity,
private val profileManagementController: ProfileManagementController,
private val viewModelProvider: ViewModelProvider<AddProfileViewModel>,
private val resourceHandler: AppLanguageResourceHandler
private val resourceHandler: AppLanguageResourceHandler,
private val profileViewModel: AddProfileViewModel,
@EnableDownloadsSupport private val enableDownloadsSupport: PlatformParameterValue<Boolean>
) {
private lateinit var uploadImageView: ImageView
private val profileViewModel by lazy {
getAddProfileViewModel()
}
private var selectedImage: Uri? = null
private var allowDownloadAccess = false
private var inputtedPin = false
Expand All @@ -55,7 +54,6 @@ class AddProfileActivityPresenter @Inject constructor(
private lateinit var alertDialog: AlertDialog

fun handleOnCreate() {

val binding = DataBindingUtil.setContentView<AddProfileActivityBinding>(
activity,
R.layout.add_profile_activity
Expand All @@ -65,9 +63,11 @@ class AddProfileActivityPresenter @Inject constructor(
lifecycleOwner = activity
viewModel = profileViewModel
}
binding.addProfileActivityAllowDownloadConstraintLayout.setOnClickListener {
allowDownloadAccess = !allowDownloadAccess
binding.addProfileActivityAllowDownloadSwitch.isChecked = allowDownloadAccess
if (!enableDownloadsSupport.value) {
binding.addProfileActivityAllowDownloadConstraintLayout.setOnClickListener {
allowDownloadAccess = !allowDownloadAccess
binding.addProfileActivityAllowDownloadSwitch.isChecked = allowDownloadAccess
}
}
binding.addProfileActivityPinCheckBox.setOnCheckedChangeListener { _, isChecked ->
profileViewModel.createPin.set(isChecked)
Expand Down Expand Up @@ -319,8 +319,4 @@ class AddProfileActivityPresenter @Inject constructor(
alertDialog.dismiss()
}
}

private fun getAddProfileViewModel(): AddProfileViewModel {
return viewModelProvider.getForActivity(activity, AddProfileViewModel::class.java)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ package org.oppia.android.app.profile
import androidx.databinding.ObservableField
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.viewmodel.ObservableViewModel
import org.oppia.android.util.platformparameter.EnableDownloadsSupport
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject

/** The ViewModel for [AddProfileActivity]. */
@ActivityScope
class AddProfileViewModel @Inject constructor() : ObservableViewModel() {
class AddProfileViewModel @Inject constructor(
@EnableDownloadsSupport private val enableDownloadsSupport: PlatformParameterValue<Boolean>
) : ObservableViewModel() {
val validPin = ObservableField(false)
val pinErrorMsg = ObservableField("")
val confirmPinErrorMsg = ObservableField("")
Expand All @@ -18,6 +22,7 @@ class AddProfileViewModel @Inject constructor() : ObservableViewModel() {
val createPin = ObservableField(false)
val isButtonActive = ObservableField(false)
val showInfoAlertPopup = ObservableField<Boolean>(false)
val showAllowDownloadAccess: Boolean by lazy { enableDownloadsSupport.value }

fun clearAllErrorMessages() {
pinErrorMsg.set("")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.platformparameter.EnableDownloadsSupport
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject

/** The ViewModel for [ProfileEditActivity]. */
@FragmentScope
class ProfileEditViewModel @Inject constructor(
private val oppiaLogger: OppiaLogger,
private val profileManagementController: ProfileManagementController
private val profileManagementController: ProfileManagementController,
@EnableDownloadsSupport private val enableDownloadsSupport: PlatformParameterValue<Boolean>
) : ObservableViewModel() {
private lateinit var profileId: ProfileId

Expand All @@ -34,6 +37,13 @@ class ProfileEditViewModel @Inject constructor(
)
}

/** Indicates whether downloads-related settings should be shown for this profile. */
val showEditDownloadAccess: LiveData<Boolean> by lazy {
Transformations.map(profile) { profile ->
enableDownloadsSupport.value && !profile.isAdmin
}
}

/** Whether the user is an admin. */
var isAdmin = false

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout-land/profile_edit_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
android:background="@color/component_color_profile_edit_activity_profile_edit_allow_download_container_color"
android:focusable="true"
android:importantForAccessibility="yes"
android:visibility="@{viewModel.profile.isAdmin ? View.GONE : View.VISIBLE}"
android:visibility="@{viewModel.showEditDownloadAccess ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/view4">
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/add_profile_activity.xml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
android:clickable="@{viewModel.validPin ? true : false}"
android:focusable="true"
android:importantForAccessibility="yes"
android:visibility="@{viewModel.showAllowDownloadAccess ? View.VISIBLE : View.GONE}"
app:layout_constraintTop_toBottomOf="@+id/add_profile_activity_confirm_pin">

<TextView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
android:background="@color/component_color_admin_controls_options_background_color"
android:clickable="true"
android:focusable="true"
android:visibility="@{viewModel.isVisible ? View.VISIBLE: View.GONE}"
android:importantForAccessibility="yes"
android:onClick="@{(view) -> viewModel.onTopicAutoUpdatePermissionChanged()}"
android:paddingStart="@dimen/administrator_controls_download_permissions_view_auto_update_topic_constraint_layout_padding_start"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/profile_edit_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
android:background="@color/component_color_profile_edit_activity_profile_edit_allow_download_container_color"
android:focusable="true"
android:importantForAccessibility="yes"
android:visibility="@{viewModel.profile.isAdmin ? View.GONE : View.VISIBLE}"
android:visibility="@{viewModel.showEditDownloadAccess ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/view4">
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,6 @@
<string name="faq_question_5">من هو المشرف؟</string>
<string name="faq_question_6">لماذا لا يتم تحميل مشغل الاستكشاف؟</string>
<string name="faq_question_7">لماذا لا يتم تشغيل الصوت الخاص بي؟</string>
<string name="faq_question_8">كيف يمكنني تنزيل موضوع؟</string>
<string name="faq_question_9">لا أجد سؤالي هنا. ماذا الان؟</string>
<string name="faq_answer_1">&lt;p&gt;إذا كانت هذه هي المرة الأولى التي تنشئ فيها ملفًا شخصيًا وليس لديك رقم تعريف شخصي: &lt;/p&gt; &lt;p&gt; 1. من منتقي الملف الشخصي ، اضغط على&lt;strong&gt; قم بإعداد ملفات تعريف متعددة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt; 2. قم بإنشاء رقم تعريف شخصي و&lt;strong&gt;احفظ&lt;/strong&gt;&lt;/p&gt; &lt;p&gt; 3. املأ جميع البيانات للملف الشخصي.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;(اختياري) قم بتحميل صورة.&lt;/li&gt; &lt;li&gt;إدخال اسم.&lt;/li&gt; &lt;li&gt;(اختياري) قم بتعيين رقم تعريف شخصي مكون من 3 أرقام.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt; 4. اضغط&lt;strong&gt;إنشاء&lt;/strong&gt; . تمت إضافة هذا الملف الشخصي إلى منتقي ملف التعريف الخاص بك!&lt;br/&gt; &lt;br/&gt; إذا قمت بإنشاء ملف تعريف من قبل ولديك رقم تعريف شخصي:&lt;/p&gt;&lt;p&gt; 1. من منتقي الملف الشخصي ، اضغط على&lt;strong&gt;إضافة الملف الشخصي&lt;/strong&gt;&lt;/p&gt; &lt;p&gt; 2. أدخل رقم التعريف الشخصي الخاص بك وانقر فوق&lt;strong&gt;إرسال&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;3. املأ جميع الحقول للملف الشخصي.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;(اختياري) قم بتحميل صورة.&lt;/li&gt; &lt;li&gt;إدخال اسم.&lt;/li&gt; &lt;li&gt;(اختياري) قم بتعيين رقم تعريف شخصي مكون من 3 أرقام.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt; 4. اضغط&lt;strong&gt;إنشاء&lt;/strong&gt; . تمت إضافة هذا الملف الشخصي إلى منتقي ملف التعريف الخاص بك!&lt;br/&gt;&lt;br/&gt; ملاحظة: فقط ال&lt;u&gt;مدير&lt;/u&gt; قادر على إدارة الملفات الشخصية.&lt;/p&gt;</string>
<string name="faq_answer_2">&lt;p&gt;بمجرد حذف ملف التعريف:&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;li&gt;لا يمكن استعادة ملف التعريف.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;سيتم حذف معلومات الملف الشخصي مثل الاسم والصور والتقدم بشكل دائم.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;لحذف ملف تعريف (باستثناء&lt;u&gt;المسؤول&lt;/u&gt;&lt;/p&gt;&lt;p&gt;1. من الصفحة الرئيسية للمسؤول ، اضغط على زر القائمة أعلى اليسار.&lt;/p&gt;&lt;p&gt;2. اضغط على&lt;strong&gt;ضوابط المسؤول&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;3. اضغط على&lt;strong&gt;تحرير ملفات التعريف&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;4. اضغط على الملف الشخصي الذي ترغب في حذفه.&lt;/p&gt;&lt;p&gt;5. في الجزء السفلي من الشاشة ، انقر فوق&lt;strong&gt;حذف الملف الشخصي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;6. اضغط&lt;strong&gt;حذف&lt;/strong&gt;لتأكيد الحذف.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;ملاحظة:&lt;u&gt;المسؤول&lt;/u&gt;فقط هو القادر على إدارة الملفات الشخصية.&lt;/p&gt;</string>
Expand All @@ -519,7 +518,6 @@
<string name="faq_answer_5">&lt;p&gt;المشرف هو المستخدم الرئيسي الذي يدير ملفات التعريف والإعدادات لكل ملف تعريف على حسابه. هم على الأرجح والدك أو معلمك أو وصي عليك الذي أنشأ هذا الملف الشخصي لك.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;يمكن للمسؤولين إدارة الملفات الشخصية وتعيين أرقام التعريف الشخصية وتغيير الإعدادات الأخرى ضمن حساباتهم. بناءً على ملف التعريف الخاص بك ، قد تكون أذونات المسؤول مطلوبة لبعض الميزات مثل تنزيل الموضوعات وتغيير رقم التعريف الشخصي وغير ذلك.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;لمعرفة من هو المسؤول لديك ، انتقل إلى منتقي الملف الشخصي. الملف الشخصي الأول المدرج ولديه \"المسؤول\" مكتوب باسمه هو المسؤول.&lt;/p&gt;</string>
<string name="faq_answer_6">&lt;p&gt;إذا لم يتم تحميل مشغل الاستكشاف&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;تحقق لمعرفة ما إذا كان التطبيق محدثًا أم لا:&lt;/p&gt;&lt;p&gt; &lt;ol&gt; &lt;li&gt; انتقل إلى متجر Play وتأكد من تحديث التطبيق إلى أحدث إصدار &lt;/li&gt; &lt;/ol&gt; &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;تحقق من اتصالك بالإنترنت:&lt;/p&gt;&lt;p&gt; &lt;li&gt; إذا كان اتصالك بالإنترنت بطيئًا ، فحاول إعادة الاتصال بشبكة Wi-Fi أو الاتصال بشبكة أخرى. &lt;/li&gt; &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;اطلب من المشرف التحقق من أجهزتهم واتصال الإنترنت:&lt;/p&gt;&lt;p&gt; &lt;li&gt; اطلب من المشرف استكشاف الأخطاء وإصلاحها باستخدام الخطوات المذكورة أعلاه &lt;/li&gt; &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;أخبرنا إذا كنت لا تزال تواجه مشكلات في التحميل:&lt;/p&gt;&lt;p&gt; &lt;li&gt; أبلغ عن مشكلة عن طريق الاتصال بنا على [email protected]. &lt;/li&gt; &lt;/p&gt;</string>
<string name="faq_answer_7">&lt;p&gt;إذا لم يتم تشغيل الصوت الخاص بك&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;تحقق لمعرفة ما إذا كان التطبيق محدثًا أم لا:&lt;/p&gt;&lt;p&gt; &lt;li&gt;انتقل إلى متجر Play وتأكد من تحديث التطبيق إلى أحدث إصدار&lt;/li&gt; &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;تحقق من اتصالك بالإنترنت:&lt;/p&gt;&lt;p&gt; &lt;li&gt;إذا كان اتصالك بالإنترنت بطيئًا ، فحاول إعادة الاتصال بشبكة Wi-Fi أو الاتصال بشبكة أخرى. قد يتسبب الإنترنت البطيء في تحميل الصوت بشكل غير منتظم ، مما يجعل من الصعب تشغيله.&lt;/li&gt; &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;اطلب من المسؤول التحقق من أجهزتهم واتصال الإنترنت:&lt;/p&gt;&lt;p&gt; &lt;li&gt;اطلب من المسؤول استكشاف الأخطاء وإصلاحها باستخدام الخطوات المذكورة أعلاه&lt;/li&gt; &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;أخبرنا إذا كنت لا تزال تواجه مشكلات في التحميل:&lt;/p&gt;&lt;p&gt; &lt;li&gt;أبلغ عن مشكلة عن طريق الاتصال بنا على [email protected].&lt;/li&gt;&lt;/p&gt;</string>
<string name="faq_answer_8">&lt;p&gt;لتنزيل استكشاف:&lt;/p&gt;&lt;p&gt;1. من الصفحة الرئيسية ، انقر فوق موضوع أو استكشاف.&lt;/p&gt;&lt;p&gt;2. من صفحة الموضوع هذه ، انقر على علامة التبويب &lt;strong&gt; معلومات &lt;/ strong&gt;.&lt;/p&gt;&lt;p&gt;3. اضغط على &lt;strong&gt; تنزيل الموضوع &lt;/ strong&gt;.&lt;/p&gt;&lt;p&gt;4. اعتمادًا على إعدادات التطبيق ، قد تحتاج إلى موافقة المسؤول أو اتصال Wifi ثابتًا لإكمال التنزيل. إذا لزم الأمر ، بمجرد استيفاء هذه المتطلبات ، يتم تنزيل الموضوع على الجهاز ويمكن استخدامه في وضع عدم الاتصال بواسطة جميع ملفات التعريف. &lt;p&gt;</string>
<string name="faq_answer_9">&lt;p&gt; إذا لم تتمكن من العثور على سؤالك أو كنت ترغب في الإبلاغ عن خطأ ، فاتصل بنا على [email protected]. &lt;/p&gt;</string>
<string name="profile_edit_fragment_test_activity_label">نشاط اختبار جزء تحرير ملف التعريف</string>
<string name="administrator_controls_fragment_test_activity_label">يتحكم المسؤول في نشاط اختبار التجزئة</string>
Expand Down
Loading

0 comments on commit 76bf81a

Please sign in to comment.