diff --git a/app/build.gradle b/app/build.gradle index e509a8b027..db71d1f812 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,8 +102,8 @@ dependencies { implementation 'com.github.jeancsanchez:jcplayer:2.7.2' - implementation "com.google.dagger:hilt-android:2.48.1" - kapt "com.google.dagger:hilt-android-compiler:2.48.1" + implementation "com.google.dagger:hilt-android:2.49" + kapt "com.google.dagger:hilt-android-compiler:2.49" implementation 'com.mikepenz:crossfader:1.6.0@aar' implementation 'com.mikepenz:crossfadedrawerlayout:1.1.0@aar' @@ -132,6 +132,8 @@ dependencies { implementation 'com.github.kizitonwose:CalendarView:1.1.0' implementation "io.noties.markwon:editor:4.6.2" implementation "io.noties.markwon:image:4.6.2" + implementation "io.noties.markwon:html:4.6.2" + implementation 'com.caverock:androidsvg-aar:1.4' implementation "androidx.core:core-ktx:1.12.0" implementation "com.github.VaibhavLakhera:Circular-Progress-View:0.1.2" implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4cc8754640..08d97efe91 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,7 +30,7 @@ - + openIntent(items, TextFileViewerActivity::class.java) @@ -158,8 +158,9 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } } + @RequiresApi(Build.VERSION_CODES.O) private fun installApk(items: RealmMyLibrary) { -// currentLibrary = items + currentLibrary = items val directory = File(MainApplication.context.getExternalFilesDir(null).toString() + "/ole" + "/" + items.id) if (!directory.exists()) { if (!directory.mkdirs()) { @@ -183,22 +184,22 @@ abstract class BaseContainerFragment : BaseResourceFragment() { intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK if (intent.resolveActivity(requireActivity().packageManager) != null) { -// if (hasInstallPermission(MainApplication.context)) { + if (hasInstallPermission(MainApplication.context)) { startActivity(intent) -// } else { -// requestInstallPermission() -// } + } else { + requestInstallPermission() + } } else { Utilities.toast(activity,"No app to handle the installation") } } -// @RequiresApi(Build.VERSION_CODES.O) -// private fun requestInstallPermission() { -// val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) -// intent.data = Uri.parse("package:" + MainApplication.context.packageName) -// startActivityForResult(intent, INSTALL_UNKNOWN_SOURCES_REQUEST_CODE) -// } + @RequiresApi(Build.VERSION_CODES.O) + private fun requestInstallPermission() { + val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) + intent.data = Uri.parse("package:" + MainApplication.context.packageName) + startActivityForResult(intent, INSTALL_UNKNOWN_SOURCES_REQUEST_CODE) + } fun openFileType(items: RealmMyLibrary, videotype: String) { val mimetype = Utilities.getMimeType(items.resourceLocalAddress) @@ -298,22 +299,22 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } } -// @RequiresApi(Build.VERSION_CODES.O) -// override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { -// super.onActivityResult(requestCode, resultCode, data) -// if (requestCode == INSTALL_UNKNOWN_SOURCES_REQUEST_CODE) { -// if (resultCode == Activity.RESULT_OK) { -// if (currentLibrary != null) { -// installApk(currentLibrary!!) -// currentLibrary = null -// } -// } else { -// Utilities.toast(requireActivity(), getString(R.string.permissions_denied)) -// } -// } -// } + @RequiresApi(Build.VERSION_CODES.O) + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == INSTALL_UNKNOWN_SOURCES_REQUEST_CODE) { + if (resultCode == Activity.RESULT_OK) { + if (currentLibrary != null) { + installApk(currentLibrary!!) + currentLibrary = null + } + } else { + Utilities.toast(requireActivity(), getString(R.string.permissions_denied)) + } + } + } -// open fun handleBackPressed() { -// requireActivity().onBackPressed() -// } + open fun handleBackPressed() { + requireActivity().onBackPressed() + } } diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.java b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.java index ea3f7169ff..52d8076963 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.java +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseResourceFragment.java @@ -102,15 +102,17 @@ protected void showDownloadDialog(final List db_myLibrary) { @Override public void isAvailable() { if (!db_myLibrary.isEmpty()) { - LayoutInflater inflater = getLayoutInflater(); - convertView = inflater.inflate(R.layout.my_library_alertdialog, null); - AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity()); - alertDialogBuilder.setView(convertView).setTitle(R.string.download_suggestion); - alertDialogBuilder.setPositiveButton(R.string.download_selected, (dialogInterface, i) -> startDownload(DownloadUtils.downloadFiles(db_myLibrary, lv.getSelectedItemsList(), settings))).setNeutralButton(R.string.download_all, (dialogInterface, i) -> startDownload(DownloadUtils.downloadAllFiles(db_myLibrary, settings))).setNegativeButton(R.string.txt_cancel, null); - AlertDialog alertDialog = alertDialogBuilder.create(); - createListView(db_myLibrary, alertDialog); - alertDialog.show(); - (alertDialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(lv.getSelectedItemsList().size() > 0); + if (isAdded() && getActivity() != null) { + LayoutInflater inflater = getActivity().getLayoutInflater(); + convertView = inflater.inflate(R.layout.my_library_alertdialog, null); + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity()); + alertDialogBuilder.setView(convertView).setTitle(R.string.download_suggestion); + alertDialogBuilder.setPositiveButton(R.string.download_selected, (dialogInterface, i) -> startDownload(DownloadUtils.downloadFiles(db_myLibrary, lv.getSelectedItemsList(), settings))).setNeutralButton(R.string.download_all, (dialogInterface, i) -> startDownload(DownloadUtils.downloadAllFiles(db_myLibrary, settings))).setNegativeButton(R.string.txt_cancel, null); + AlertDialog alertDialog = alertDialogBuilder.create(); + createListView(db_myLibrary, alertDialog); + alertDialog.show(); + (alertDialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(lv.getSelectedItemsList().size() > 0); + } } else { Utilities.toast(requireContext(), getString(R.string.no_resources_to_download)); } diff --git a/app/src/main/java/org/ole/planet/myplanet/base/PermissionActivity.java b/app/src/main/java/org/ole/planet/myplanet/base/PermissionActivity.java index d66d72b49e..2d85f3fcfa 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/PermissionActivity.java +++ b/app/src/main/java/org/ole/planet/myplanet/base/PermissionActivity.java @@ -28,12 +28,12 @@ public boolean checkPermission(String strPermission) { return result == PackageManager.PERMISSION_GRANTED; } -// public static boolean hasInstallPermission(android.content.Context context) { -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { -// return context.getPackageManager().canRequestPackageInstalls(); -// } -// return true; -// } + public static boolean hasInstallPermission(android.content.Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return context.getPackageManager().canRequestPackageInstalls(); + } + return true; + } public void checkUsagesPermission() { if (!getUsagesPermission(this)) { diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseActivity.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseActivity.kt index 52f25d026c..baef96b0fc 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseActivity.kt @@ -10,6 +10,7 @@ import java.util.UUID open class RealmCourseActivity : RealmObject() { @PrimaryKey + private var id: String? = null private var _id: String? = null @JvmField var createdOn: String? = null diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/course/AdapterCourses.java b/app/src/main/java/org/ole/planet/myplanet/ui/course/AdapterCourses.java index 9b8438efca..0d322a33db 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/course/AdapterCourses.java +++ b/app/src/main/java/org/ole/planet/myplanet/ui/course/AdapterCourses.java @@ -157,9 +157,8 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int viewHolder.rowCourseBinding.title.setText(courseList.get(position).getCourseTitle()); viewHolder.rowCourseBinding.description.setText(courseList.get(position).getDescription()); markwon.setMarkdown(viewHolder.rowCourseBinding.description, courseList.get(position).getDescription()); - - viewHolder.rowCourseBinding.gradLevel.setText(context.getString(R.string.grade_level_colon) + courseList.get(position).getGradeLevel()); - viewHolder.rowCourseBinding.subjectLevel.setText(context.getString(R.string.subject_level_colon) + courseList.get(position).getSubjectLevel()); + setTextViewContent(viewHolder.rowCourseBinding.gradLevel, courseList.get(position).getGradeLevel(), viewHolder.rowCourseBinding.gradLevel, context.getString(R.string.grade_level_colon)); + setTextViewContent(viewHolder.rowCourseBinding.subjectLevel, courseList.get(position).getSubjectLevel(), viewHolder.rowCourseBinding.subjectLevel, context.getString(R.string.subject_level_colon)); viewHolder.rowCourseBinding.checkbox.setChecked(selectedItems.contains(courseList.get(position))); viewHolder.rowCourseBinding.courseProgress.setMax(courseList.get(position).getnumberOfSteps()); displayTagCloud(viewHolder.rowCourseBinding.flexboxDrawable, position); @@ -182,6 +181,14 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int } } + private void setTextViewContent(TextView textView, String content, View layout, String prefix) { + if (content.isEmpty()) { + layout.setVisibility(View.GONE); + } else { + textView.setText(prefix + content); + } + } + public boolean areAllSelected(){ if (selectedItems.size() != courseList.size()) { areAllSelected = false; diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/course/CourseDetailFragment.java b/app/src/main/java/org/ole/planet/myplanet/ui/course/CourseDetailFragment.java index bbd0aa45ee..747626fb9b 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/course/CourseDetailFragment.java +++ b/app/src/main/java/org/ole/planet/myplanet/ui/course/CourseDetailFragment.java @@ -7,6 +7,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -32,8 +33,11 @@ import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonPlugin; +import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.file.FileSchemeHandler; +import io.noties.markwon.image.network.NetworkSchemeHandler; +import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler; import io.noties.markwon.movement.MovementMethodPlugin; import io.realm.Realm; import io.realm.RealmResults; @@ -57,13 +61,17 @@ public void onCreate(@Nullable Bundle savedInstanceState) { id = getArguments().getString("courseId"); } markwon = Markwon.builder(context) + .usePlugin(HtmlPlugin.create()) .usePlugin(ImagesPlugin.create()) .usePlugin(MovementMethodPlugin.none()) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configure(@NonNull MarkwonPlugin.Registry registry) { - registry.require(ImagesPlugin.class, imagesPlugin -> - imagesPlugin.addSchemeHandler(FileSchemeHandler.create()) + registry.require(ImagesPlugin.class, imagesPlugin -> { + imagesPlugin.addSchemeHandler(FileSchemeHandler.create()); + imagesPlugin.addSchemeHandler(NetworkSchemeHandler.create()); + imagesPlugin.addSchemeHandler(OkHttpNetworkSchemeHandler.create()); + } ); } }) @@ -93,10 +101,10 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat } private void setCourseData() { - fragmentCourseDetailBinding.subjectLevel.setText(courses.getSubjectLevel()); - fragmentCourseDetailBinding.method.setText(courses.getMethod()); - fragmentCourseDetailBinding.gradeLevel.setText(courses.getGradeLevel()); - fragmentCourseDetailBinding.language.setText(courses.getLanguageOfInstruction()); + setTextViewVisibility(fragmentCourseDetailBinding.subjectLevel, courses.getSubjectLevel(), fragmentCourseDetailBinding.ltSubjectLevel); + setTextViewVisibility(fragmentCourseDetailBinding.method, courses.getMethod(), fragmentCourseDetailBinding.ltMethod); + setTextViewVisibility(fragmentCourseDetailBinding.gradeLevel, courses.getGradeLevel(), fragmentCourseDetailBinding.ltGradeLevel); + setTextViewVisibility(fragmentCourseDetailBinding.language, courses.getLanguageOfInstruction(), fragmentCourseDetailBinding.ltLanguage); String markdownContentWithLocalPaths = CourseStepFragment.prependBaseUrlToImages(courses.getDescription(), "file://" + MainApplication.context.getExternalFilesDir(null) + "/ole/"); markwon.setMarkdown(fragmentCourseDetailBinding.description, markdownContentWithLocalPaths); fragmentCourseDetailBinding.noOfExams.setText(RealmStepExam.getNoOfExam(mRealm, id) + ""); @@ -108,6 +116,14 @@ private void setCourseData() { setStepsList(); } + private void setTextViewVisibility(TextView textView, String content, View layout) { + if (content.isEmpty()) { + layout.setVisibility(View.GONE); + } else { + textView.setText(content); + } + } + private void setStepsList() { List steps = RealmCourseStep.getSteps(mRealm, courses.getCourseId()); fragmentCourseDetailBinding.stepsList.setLayoutManager(new LinearLayoutManager(getActivity())); diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/course/CourseStepFragment.java b/app/src/main/java/org/ole/planet/myplanet/ui/course/CourseStepFragment.java index a8444ef703..d2c113b440 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/course/CourseStepFragment.java +++ b/app/src/main/java/org/ole/planet/myplanet/ui/course/CourseStepFragment.java @@ -42,8 +42,11 @@ import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonPlugin; +import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.file.FileSchemeHandler; +import io.noties.markwon.image.network.NetworkSchemeHandler; +import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler; import io.noties.markwon.movement.MovementMethodPlugin; import io.realm.Case; import io.realm.Realm; @@ -73,13 +76,17 @@ public void onCreate(@Nullable Bundle savedInstanceState) { } setUserVisibleHint(false); markwon = Markwon.builder(context) + .usePlugin(HtmlPlugin.create()) .usePlugin(ImagesPlugin.create()) .usePlugin(MovementMethodPlugin.none()) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configure(@NonNull MarkwonPlugin.Registry registry) { - registry.require(ImagesPlugin.class, imagesPlugin -> - imagesPlugin.addSchemeHandler(FileSchemeHandler.create()) + registry.require(ImagesPlugin.class, imagesPlugin -> { + imagesPlugin.addSchemeHandler(FileSchemeHandler.create()); + imagesPlugin.addSchemeHandler(NetworkSchemeHandler.create()); + imagesPlugin.addSchemeHandler(OkHttpNetworkSchemeHandler.create()); + } ); } }) @@ -142,7 +149,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) { fragmentCourseStepBinding.description.setMovementMethod(LinkMovementMethod.getInstance()); if (!RealmMyCourse.isMyCourse(user.getId(), step.getCourseId(), mRealm)) { - fragmentCourseStepBinding.btnTakeTest.setVisibility(View.INVISIBLE); + fragmentCourseStepBinding.btnTakeTest.setVisibility(View.GONE); } setListeners(); @@ -164,7 +171,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) { } private void hideTestIfNoQuestion() { - fragmentCourseStepBinding.btnTakeTest.setVisibility(View.INVISIBLE); + fragmentCourseStepBinding.btnTakeTest.setVisibility(View.GONE); if (stepExams != null && stepExams.size() > 0) { String first_step_id = stepExams.get(0).getId(); RealmResults questions = mRealm.where(RealmExamQuestion.class).equalTo("examId", first_step_id).findAll(); @@ -230,7 +237,7 @@ public static String prependBaseUrlToImages(String markdownContent, String baseU String relativePath = matcher.group(1); String modifiedPath = relativePath.replaceFirst("resources/", ""); String fullUrl = baseUrl + modifiedPath; - matcher.appendReplacement(result, "![](" + fullUrl + ")"); + matcher.appendReplacement(result, ""); } matcher.appendTail(result); diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.java b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.java index 5b47bf5530..5c550230ae 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.java +++ b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.java @@ -35,6 +35,7 @@ import com.mikepenz.materialdrawer.model.interfaces.Nameable; import org.ole.planet.myplanet.R; +import org.ole.planet.myplanet.base.BaseContainerFragment; import org.ole.planet.myplanet.callback.OnHomeItemClickListener; import org.ole.planet.myplanet.databinding.ActivityDashboardBinding; import org.ole.planet.myplanet.databinding.CustomTabBinding; @@ -428,12 +429,12 @@ public void onBackPressed() { super.onBackPressed(); } -// Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); -// if (fragment instanceof BaseContainerFragment) { -// ((BaseContainerFragment) fragment).handleBackPressed(); -// } else { -// super.onBackPressed(); -// } + Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); + if (fragment instanceof BaseContainerFragment) { + ((BaseContainerFragment) fragment).handleBackPressed(); + } else { + super.onBackPressed(); + } } @Override diff --git a/app/src/main/res/layout/fragment_course_detail.xml b/app/src/main/res/layout/fragment_course_detail.xml index 103c37a36b..d9f3d0b1c5 100644 --- a/app/src/main/res/layout/fragment_course_detail.xml +++ b/app/src/main/res/layout/fragment_course_detail.xml @@ -112,6 +112,7 @@ @@ -130,6 +131,7 @@ @@ -148,6 +150,7 @@ @@ -166,6 +169,7 @@ @@ -202,6 +206,7 @@ diff --git a/app/src/main/res/layout/fragment_course_step.xml b/app/src/main/res/layout/fragment_course_step.xml index aa52cb3ee9..d93988ee11 100644 --- a/app/src/main/res/layout/fragment_course_step.xml +++ b/app/src/main/res/layout/fragment_course_step.xml @@ -13,6 +13,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="right" + android:layout_marginEnd="@dimen/_10dp" android:gravity="right">