Skip to content
This repository has been archived by the owner on May 6, 2024. It is now read-only.

feat: added option to delete downloaded videos from AccountFragment #1849

Merged
merged 1 commit into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions OpenEdXMobile/res/layout/fragment_account.xml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,29 @@

</LinearLayout>

<TextView
android:id="@+id/lbl_delete_downloaded_videos"
style="@style/profile_field_title"
android:layout_width="match_parent"
android:layout_marginStart="@dimen/edx_default_margin"
android:layout_marginTop="@dimen/edx_default_margin"
android:layout_marginEnd="@dimen/edx_default_margin"
android:text="@string/delete_downloaded_videos_title" />

<TextView
android:id="@+id/tv_delete_downloaded_videos"
style="@style/profile_field_description"
android:text="@string/delete_downloaded_videos_description" />

<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_delete_videos"
style="@style/edX.Widget.ProfileActionBorderedButton"
android:layout_width="match_parent"
android:layout_height="@dimen/profile_view_button_height"
android:layout_marginTop="@dimen/edx_half_margin"
android:text="@string/label_delete_all_videos" />


<View
android:layout_width="match_parent"
android:layout_height="@dimen/edx_line"
Expand Down
14 changes: 14 additions & 0 deletions OpenEdXMobile/res/values/video_strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,18 @@
<item quantity="one">%d min</item>
<item quantity="other">%d mins</item>
</plurals>

<!-- Title of Delete all downloaded videos -->
<string name="delete_downloaded_videos_title">Delete all downloaded videos</string>
<!-- Description of Delete all downloaded videos -->
<string name="delete_downloaded_videos_description">Remove all downloaded videos from your device.</string>
<!-- Title of Delete downloaded video dialog -->
<string name="delete_downloaded_videos_dialog_description">Are you sure you want to delete all downloaded videos from your device? This action cannot be undone.</string>
<!-- Title of Delete all videos button -->
<string name="label_delete_all_videos">Delete all videos</string>
<!-- Title of Deleting downloaded video progress dialog -->
<string name="deleting_downloaded_videos_title">Deleting downloaded videos…</string>
<!-- Message of Deleted downloaded video success snackbar -->
<string name="deleted_downloaded_videos_success">Downloaded videos deleted successfully.</string>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -902,10 +902,12 @@ interface Values {
String DO_NOT_SELL_DATA_CLICKED = "edx.bi.app.profile.do_not_sell_data.clicked";
String SUBMIT_FEEDBACK_CLICKED = "edx.bi.app.profile.submit_feedback.clicked";

// Video Download Quality
// Video Downloads & Quality
String PROFILE_VIDEO_DOWNLOAD_QUALITY_CLICKED = "edx.bi.app.profile.video_download_quality.clicked";
String COURSE_VIDEOS_VIDEO_DOWNLOAD_QUALITY_CLICKED = "edx.bi.app.course_videos.video_download_quality.clicked";
String VIDEO_DOWNLOAD_QUALITY_CHANGED = "edx.bi.app.video_download_quality.changed";
String DELETE_DOWNLOADED_VIDEOS_CLICKED = "edx.bi.app.delete_downloaded_videos.clicked";
String DELETE_DOWNLOADED_VIDEOS = "edx.bi.app.delete_downloaded_videos";
// Account Registration
String REGISTRATION_OPT_IN_TURNED_ON = "edx.bi.app.user.register.opt_in.on";
String REGISTRATION_OPT_IN_TURNED_OFF = "edx.bi.app.user.register.opt_in.off";
Expand Down Expand Up @@ -1124,10 +1126,12 @@ interface Events {
String DO_NOT_SELL_DATA_CLICKED = "Do Not Sell Data Clicked";
String SUBMIT_FEEDBACK_CLICKED = "Submit feedback clicked";

// Video Download Quality
// Video Downloads & Quality
String PROFILE_VIDEO_DOWNLOAD_QUALITY_CLICKED = "Profile: Video Download Quality Clicked";
String COURSE_VIDEOS_VIDEO_DOWNLOAD_QUALITY_CLICKED = "Course Videos: Video Download Quality Clicked";
String VIDEO_DOWNLOAD_QUALITY_CHANGED = "Video Download Quality Changed";
String DELETE_DOWNLOADED_VIDEOS_CLICKED = "Delete Downloaded Videos Clicked";
String DELETE_DOWNLOADED_VIDEOS = "Delete Downloaded Videos";
// Account Registration
String REGISTRATION_OPT_IN_TURNED_ON = "Registration: Opt-in Turned On";
String REGISTRATION_OPT_IN_TURNED_OFF = "Registration: Opt-in Turned Off";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,17 @@ Integer updateDownloadCompleteInfoByDmId(long dmId, VideoModel de,
DataCallback<Integer> callback);

/**
* Returns list of all videos from the database.
* Returns list of all videos from the database for a specific username.
*
* @return
*/
List<VideoModel> getAllVideos(String username, DataCallback<List<VideoModel>> DataCallback);

/**
* Returns list of all videos from the database.
*/
List<VideoModel> getAllVideos(DataCallback<List<VideoModel>> DataCallback);

/**
* Returns list of all videos from the database for a specific course.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,14 @@ public List<VideoModel> getAllVideos(String username,
return enqueue(op);
}

@Override
public List<VideoModel> getAllVideos(DataCallback<List<VideoModel>> callback) {
DbOperationGetVideos op = new DbOperationGetVideos(false, DbStructure.Table.DOWNLOADS, null,
null, null, null);
op.setCallback(callback);
return enqueue(op);
}

@Override
public List<VideoModel> getAllVideosByCourse(@NonNull String courseId,
@Nullable DataCallback<List<VideoModel>> callback) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.edx.mobile.module.storage;

public class DeleteAllDownloadedVideosEvent {
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,18 @@ public interface IStorage {

/**
* Removes all videos from the database as well as NativeDownloadManager.
* This method fetches all ongoing downloads from the DB; iterates through the list
* This method fetches all downloads from the DB; iterates through the list
* and then calls the {@link #removeDownload(VideoModel)} method for each video
*/
void removeAllDownloads();

/**
* Removes all videos from the database as well as NativeDownloadManager.
* This method fetches all ongoing downloads from the DB; iterates through the list
* and then calls the {@link #removeDownload(VideoModel)} method for each video
*/
void removeAllOnGoingDownloads();

/**
* This method fetches all unenrolledVideos from the DB.
* Iterates through the list and then calls the remove Download method for each video
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,23 @@ public int removeDownloads(List<VideoModel> modelList) {

@Override
public void removeAllDownloads() {
db.getAllVideos(new DataCallback<List<VideoModel>>() {
@Override
public void onResult(List<VideoModel> result) {
removeDownloadsFromApp(result, null);
FileUtil.resetAppDirectory(context);
EventBus.getDefault().post(new DeleteAllDownloadedVideosEvent());
}

@Override
public void onFail(Exception ex) {
logger.error(ex);
}
});
}

@Override
public void removeAllOnGoingDownloads() {
final String username = loginPrefs.getUsername();
final String sha1Username;
if (TextUtils.isEmpty(username)) {
Expand Down
12 changes: 12 additions & 0 deletions OpenEdXMobile/src/main/java/org/edx/mobile/util/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,16 @@ public static Uri getFileUriFromMediaStoreUri(@NonNull Context context, @NonNull
}
return null;
}

/**
* Deletes all the files and directories in the app's external storage directory.
*
* @param context The current context.
*/
public static void resetAppDirectory(@NonNull Context context) {
final File externalAppDir = getExternalAppDir(context);
if (externalAppDir != null) {
deleteRecursive(externalAppDir);
}
}
}
54 changes: 51 additions & 3 deletions OpenEdXMobile/src/main/java/org/edx/mobile/view/AccountFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.URLUtil
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.bumptech.glide.Glide
Expand Down Expand Up @@ -38,6 +40,8 @@ import org.edx.mobile.module.analytics.InAppPurchasesAnalytics
import org.edx.mobile.module.prefs.FeaturesPrefs
import org.edx.mobile.module.prefs.LoginPrefs
import org.edx.mobile.module.prefs.UserPrefs
import org.edx.mobile.module.storage.DeleteAllDownloadedVideosEvent
import org.edx.mobile.module.storage.IStorage
import org.edx.mobile.user.UserAPI.AccountDataUpdatedCallback
import org.edx.mobile.user.UserService
import org.edx.mobile.util.AgreementUrlType
Expand Down Expand Up @@ -94,6 +98,9 @@ class AccountFragment : BaseFragment() {
@Inject
lateinit var iapAnalytics: InAppPurchasesAnalytics

@Inject
lateinit var storage: IStorage

private val courseViewModel: CourseViewModel by viewModels()
private val iapViewModel: InAppPurchasesViewModel by viewModels()

Expand Down Expand Up @@ -130,6 +137,7 @@ class AccountFragment : BaseFragment() {
initPurchases()
handleIntentBundle(arguments)
initVideoQuality()
initDeleteDownloadedVideos()
updateWifiSwitch()
updateSDCardSwitch()
initHelpFields()
Expand Down Expand Up @@ -171,7 +179,7 @@ class AccountFragment : BaseFragment() {
binding.btnRestorePurchases.setOnClickListener {
iapAnalytics.reset()
iapAnalytics.trackIAPEvent(Analytics.Events.IAP_RESTORE_PURCHASE_CLICKED)
showLoader()
showLoader(R.string.title_checking_purchases)
lifecycleScope.launch {
courseViewModel.fetchEnrolledCourses(
type = CourseViewModel.CoursesRequestType.STALE,
Expand Down Expand Up @@ -266,9 +274,9 @@ class AccountFragment : BaseFragment() {
fullScreenLoader.show(childFragmentManager, FullscreenLoaderDialogFragment.TAG)
}

private fun showLoader() {
private fun showLoader(@StringRes titleResId: Int) {
loaderDialog = AlertDialogFragment.newInstance(
R.string.title_checking_purchases,
titleResId,
R.layout.alert_dialog_progress
)
loaderDialog?.isCancelable = false
Expand Down Expand Up @@ -301,6 +309,30 @@ class AccountFragment : BaseFragment() {
binding.tvVideoDownloadQuality.setText(videoQuality.titleResId)
}

private fun initDeleteDownloadedVideos() {
binding.btnDeleteVideos.setOnClickListener {
trackEvent(
Analytics.Events.DELETE_DOWNLOADED_VIDEOS_CLICKED,
Analytics.Values.DELETE_DOWNLOADED_VIDEOS_CLICKED
)
AlertDialogFragment.newInstance(
getString(R.string.delete_downloaded_videos_title),
getString(R.string.delete_downloaded_videos_dialog_description),
getString(R.string.label_delete),
{ _, _ ->
showLoader(R.string.deleting_downloaded_videos_title)
storage.removeAllDownloads()
trackEvent(
Analytics.Events.DELETE_DOWNLOADED_VIDEOS,
Analytics.Values.DELETE_DOWNLOADED_VIDEOS
)
},
getString(R.string.label_cancel),
null
).show(childFragmentManager, null)
}
}

private fun initHelpFields() {
if (URLUtil.isValidUrl(featuresPrefs.feedbackFormUrl)) {
binding.btnSubmitFeedback.setVisibility(true)
Expand Down Expand Up @@ -605,6 +637,22 @@ class AccountFragment : BaseFragment() {
environment.analyticsRegistry.trackEvent(eventName, biValue)
}

@Subscribe(sticky = true)
@Suppress("UNUSED_PARAMETER")
fun onEventMainThread(event: DeleteAllDownloadedVideosEvent) {
binding.root.postDelayed(
{
loaderDialog?.dismiss()
Toast.makeText(
requireContext(),
R.string.deleted_downloaded_videos_success,
Toast.LENGTH_LONG
).show()
}, 2000
)

}

companion object {
@JvmStatic
fun newInstance(bundle: Bundle): AccountFragment {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ public void forceLogout(Context context, AnalyticsRegistry analyticsRegistry, No
*/
public void performManualLogout(Context context, AnalyticsRegistry analyticsRegistry, NotificationDelegate delegate) {
// Remove all ongoing downloads first which requires username
storage.removeAllDownloads();
storage.removeAllOnGoingDownloads();
loginAPI.logOut();
forceLogout(context, analyticsRegistry, delegate);
SecurityUtil.clearUserData(context);
Expand Down
Loading