package org.edx.mobile.view; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.TaskStackBuilder; import com.google.inject.Inject; import com.google.inject.Singleton; import org.edx.mobile.authentication.LoginAPI; import org.edx.mobile.course.CourseDetail; import org.edx.mobile.discussion.DiscussionComment; import org.edx.mobile.discussion.DiscussionThread; import org.edx.mobile.discussion.DiscussionTopic; import org.edx.mobile.event.LogoutEvent; import org.edx.mobile.model.api.EnrolledCoursesResponse; import org.edx.mobile.module.analytics.ISegment; import org.edx.mobile.module.notification.NotificationDelegate; import org.edx.mobile.module.prefs.LoginPrefs; import org.edx.mobile.profiles.UserProfileActivity; import org.edx.mobile.util.Config; import org.edx.mobile.util.SecurityUtil; import org.edx.mobile.view.dialog.WebViewActivity; import org.edx.mobile.view.my_videos.MyVideosActivity; import de.greenrobot.event.EventBus; @Singleton public class Router { public static final String EXTRA_ANNOUNCEMENTS = "announcements"; public static final String EXTRA_BUNDLE = "bundle"; public static final String EXTRA_COURSE_ID = "course_id"; public static final String EXTRA_COURSE_DETAIL = "course_detail"; public static final String EXTRA_COURSE_DATA = "course_data"; public static final String EXTRA_COURSE_UNIT = "course_unit"; public static final String EXTRA_COURSE_COMPONENT_ID = "course_component_id"; public static final String EXTRA_LAST_ACCESSED_ID = "last_accessed_id"; public static final String EXTRA_SEARCH_QUERY = "search_query"; public static final String EXTRA_DISCUSSION_TOPIC = "discussion_topic"; public static final String EXTRA_DISCUSSION_THREAD = "discussion_thread"; public static final String EXTRA_DISCUSSION_COMMENT = "discussion_comment"; public static final String EXTRA_DISCUSSION_TOPIC_ID = "discussion_topic_id"; @Inject Config config; @Inject private LoginAPI loginAPI; @Inject private LoginPrefs loginPrefs; public void showDownloads(Activity sourceActivity) { Intent downloadIntent = new Intent(sourceActivity, DownloadListActivity.class); sourceActivity.startActivity(downloadIntent); } public void showCourseInfo(Activity sourceActivity, String pathId) { Intent courseInfoIntent = new Intent(sourceActivity, CourseInfoActivity.class); courseInfoIntent.putExtra(CourseInfoActivity.EXTRA_PATH_ID, pathId); sourceActivity.startActivity(courseInfoIntent); } public void showMyVideos(Activity sourceActivity) { Intent myVideosIntent = new Intent(sourceActivity, MyVideosActivity.class); myVideosIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); sourceActivity.startActivity(myVideosIntent); } public void showSettings(Activity sourceActivity) { Intent settingsIntent = new Intent(sourceActivity, SettingsActivity.class); settingsIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); sourceActivity.startActivity(settingsIntent); } public void showLaunchScreen(Context context) { final Intent launchIntent = new Intent(context, config.isNewLogistrationEnabled() ? DiscoveryLaunchActivity.class : LaunchActivity.class); launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(launchIntent); } public void showSplashScreen(Context context) { final Intent launchIntent = new Intent(context, SplashActivity.class); launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(launchIntent); } @NonNull public Intent getLogInIntent() { return LoginActivity.newIntent(); } @NonNull public Intent getRegisterIntent() { return RegisterActivity.newIntent(); } public void showMyCourses(Activity sourceActivity) { sourceActivity.startActivity(MyCoursesListActivity.newIntent()); } public void showCourseDashboardTabs(Activity activity, Config config, EnrolledCoursesResponse model, boolean announcements) { showCourseDashboard(activity, model, announcements); } /** * FIXME - it will bring to different view in the future * * @param activity * @param model */ public void showCourseAnnouncement(Activity activity, EnrolledCoursesResponse model) { final Bundle courseBundle = new Bundle(); courseBundle.putSerializable(EXTRA_COURSE_DATA, model); courseBundle.putBoolean(EXTRA_ANNOUNCEMENTS, true); final Intent courseDetail = new Intent(activity, CourseAnnouncementsActivity.class); courseDetail.putExtra(EXTRA_BUNDLE, courseBundle); courseDetail.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivity(courseDetail); } public void showCourseAnnouncementFromNotification(@NonNull Context context, @NonNull String courseId) { final Bundle courseBundle = new Bundle(); courseBundle.putBoolean(Router.EXTRA_ANNOUNCEMENTS, true); courseBundle.putString(Router.EXTRA_COURSE_ID, courseId); final Intent courseDetail = new Intent(context, CourseAnnouncementsActivity.class).putExtra(EXTRA_BUNDLE, courseBundle); // TODO: It's not essential, but we may want additional activities on the back-stack (e.g. CourseDashboardActivity) TaskStackBuilder.create(context) .addNextIntent(courseDetail) .startActivities(); } public void showCourseContainerOutline(Activity activity, EnrolledCoursesResponse model) { showCourseContainerOutline(activity, model, null); } public void showCourseContainerOutline(Activity activity, EnrolledCoursesResponse model, String courseComponentId) { showCourseContainerOutline(activity, -1, model, courseComponentId, null); } public void showCourseContainerOutline(Activity activity, int requestCode, EnrolledCoursesResponse model, String courseComponentId, String lastAccessedId) { Intent courseDetail = createCourseOutlineIntent(activity, model, courseComponentId, lastAccessedId); //TODO - what's the most suitable FLAG? // courseDetail.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivityForResult(courseDetail, requestCode); } public void showCourseContainerOutline(Fragment fragment, int requestCode, EnrolledCoursesResponse model, String courseComponentId, String lastAccessedId) { Intent courseDetail = createCourseOutlineIntent(fragment.getActivity(), model, courseComponentId, lastAccessedId); //TODO - what's the most suitable FLAG? // courseDetail.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); fragment.startActivityForResult(courseDetail, requestCode); } private Intent createCourseOutlineIntent(Activity activity, EnrolledCoursesResponse model, String courseComponentId, String lastAccessedId) { Bundle courseBundle = new Bundle(); courseBundle.putSerializable(EXTRA_COURSE_DATA, model); courseBundle.putString(EXTRA_COURSE_COMPONENT_ID, courseComponentId); Intent courseDetail = new Intent(activity, CourseOutlineActivity.class); courseDetail.putExtra(EXTRA_BUNDLE, courseBundle); courseDetail.putExtra(EXTRA_LAST_ACCESSED_ID, lastAccessedId); return courseDetail; } public void showCourseUnitDetail(Fragment fragment, int requestCode, EnrolledCoursesResponse model, String courseComponentId) { Bundle courseBundle = new Bundle(); courseBundle.putSerializable(EXTRA_COURSE_DATA, model); courseBundle.putSerializable(EXTRA_COURSE_COMPONENT_ID, courseComponentId); Intent courseDetail = new Intent(fragment.getActivity(), CourseUnitNavigationActivity.class); courseDetail.putExtra(EXTRA_BUNDLE, courseBundle); courseDetail.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); fragment.startActivityForResult(courseDetail, requestCode); } public void showCourseDashboard(Activity activity, EnrolledCoursesResponse model, boolean announcements) { Bundle courseBundle = new Bundle(); courseBundle.putSerializable(EXTRA_COURSE_DATA, model); courseBundle.putBoolean(EXTRA_ANNOUNCEMENTS, announcements); Intent courseDashboard = new Intent(activity, CourseDashboardActivity.class); courseDashboard.putExtra(EXTRA_BUNDLE, courseBundle); courseDashboard.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivity(courseDashboard); } public void showCourseDiscussionTopics(Activity activity, EnrolledCoursesResponse courseData) { Intent showDiscussionsIntent = new Intent(activity, CourseDiscussionTopicsActivity.class); showDiscussionsIntent.putExtra(EXTRA_COURSE_DATA, courseData); showDiscussionsIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivity(showDiscussionsIntent); } public void showCourseDiscussionAddPost(@NonNull Activity activity, @Nullable DiscussionTopic discussionTopic, @NonNull EnrolledCoursesResponse courseData) { Intent addPostIntent = new Intent(activity, DiscussionAddPostActivity.class); addPostIntent.putExtra(EXTRA_COURSE_DATA, courseData); addPostIntent.putExtra(EXTRA_DISCUSSION_TOPIC, discussionTopic); addPostIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivity(addPostIntent); } public void showCourseDiscussionComments(Context context, DiscussionComment comment, DiscussionThread discussionThread) { Intent commentListIntent = new Intent(context, CourseDiscussionCommentsActivity.class); commentListIntent.putExtra(Router.EXTRA_DISCUSSION_COMMENT, comment); commentListIntent.putExtra(Router.EXTRA_DISCUSSION_THREAD, discussionThread); commentListIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); context.startActivity(commentListIntent); } public void showCourseDiscussionPostsForSearchQuery(Activity activity, String query, EnrolledCoursesResponse courseData) { Intent showDiscussionPostsIntent = new Intent(activity, CourseDiscussionPostsActivity.class); showDiscussionPostsIntent.putExtra(EXTRA_COURSE_DATA, courseData); showDiscussionPostsIntent.putExtra(EXTRA_SEARCH_QUERY, query); showDiscussionPostsIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivity(showDiscussionPostsIntent); } public void showCourseDiscussionPostsForDiscussionTopic(Activity activity, DiscussionTopic topic, EnrolledCoursesResponse courseData) { Intent showDiscussionPostsIntent = new Intent(activity, CourseDiscussionPostsActivity.class); showDiscussionPostsIntent.putExtra(EXTRA_COURSE_DATA, courseData); showDiscussionPostsIntent.putExtra(EXTRA_DISCUSSION_TOPIC, topic); showDiscussionPostsIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivity(showDiscussionPostsIntent); } public void showCourseDiscussionResponses(Context context, DiscussionThread discussionThread, EnrolledCoursesResponse courseData) { Intent discussionResponsesIntent = new Intent(context, CourseDiscussionResponsesActivity.class); discussionResponsesIntent.putExtra(EXTRA_DISCUSSION_THREAD, discussionThread); discussionResponsesIntent.putExtra(EXTRA_COURSE_DATA, courseData); discussionResponsesIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); context.startActivity(discussionResponsesIntent); } public void showCourseDiscussionAddResponse(Context context, DiscussionThread discussionThread) { Intent addResponseIntent = new Intent(context, DiscussionAddResponseActivity.class); addResponseIntent.putExtra(EXTRA_DISCUSSION_THREAD, discussionThread); addResponseIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); context.startActivity(addResponseIntent); } public void showCourseDiscussionAddComment(Context context, DiscussionComment discussionComment, DiscussionThread discussionThread) { Intent addResponseIntent = new Intent(context, DiscussionAddCommentActivity.class); addResponseIntent.putExtra(EXTRA_DISCUSSION_THREAD, discussionThread); addResponseIntent.putExtra(EXTRA_DISCUSSION_COMMENT, discussionComment); addResponseIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); context.startActivity(addResponseIntent); } /** * Clear the login data and exit to the splash screen. This should only be called internally; * for handling manual logout, * {@link #performManualLogout(Context, ISegment, NotificationDelegate)} should be used instead. * * @param context The context. * @param segment The segment object. * @param delegate The notification delegate. * @see #performManualLogout(Context, ISegment, NotificationDelegate) */ public void forceLogout(Context context, ISegment segment, NotificationDelegate delegate) { loginPrefs.clear(); EventBus.getDefault().post(new LogoutEvent()); segment.trackUserLogout(); segment.resetIdentifyUser(); delegate.unsubscribeAll(); showSplashScreen(context); } /** * Clears all the user data, revokes the refresh and access tokens, and exit to the splash * screen. This should only be called in response to manual logout by the user; for performing * logout internally (e.g. in response to refresh token expiration), * {@link #forceLogout(Context, ISegment, NotificationDelegate)} should be used instead. * * @param context The context. * @param segment The segment object. * @param delegate The notification delegate. * @see #forceLogout(Context, ISegment, NotificationDelegate) */ public void performManualLogout(Context context, ISegment segment, NotificationDelegate delegate) { loginAPI.logOut(); forceLogout(context, segment, delegate); SecurityUtil.clearUserData(context); } public void showHandouts(Activity activity, EnrolledCoursesResponse courseData) { Intent handoutIntent = new Intent(activity, CourseHandoutActivity.class); handoutIntent.putExtra(EXTRA_COURSE_DATA, courseData); handoutIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); activity.startActivity(handoutIntent); } public void showUserProfile(@NonNull Context context, @NonNull String username) { context.startActivity(UserProfileActivity.newIntent(context, username, false)); } public void showUserProfileWithNavigationDrawer(@NonNull Context context, @NonNull String username) { context.startActivity(UserProfileActivity.newIntent(context, username, true)); } public void showUserProfileEditor(@NonNull Context context, @NonNull String username) { context.startActivity(EditUserProfileActivity.newIntent(context, username)); } public void showCertificate(@NonNull Context context, @NonNull EnrolledCoursesResponse courseData) { context.startActivity(CertificateActivity.newIntent(context, courseData)); } public void showCourseDetail(@NonNull Context context, @NonNull CourseDetail courseDetail) { context.startActivity(CourseDetailActivity.newIntent(context, courseDetail)); } public void showFindCourses(@NonNull Context context) { if (!config.getCourseDiscoveryConfig().isCourseDiscoveryEnabled()) { throw new RuntimeException("Course discovery is not enabled"); } final Intent findCoursesIntent; if (config.getCourseDiscoveryConfig().isWebviewCourseDiscoveryEnabled()) { findCoursesIntent = new Intent(context, WebViewFindCoursesActivity.class); } else { findCoursesIntent = NativeFindCoursesActivity.newIntent(context); } //Add this flag as multiple activities need to be created findCoursesIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); context.startActivity(findCoursesIntent); } public void showExploreSubjects(@NonNull Context context) { final Intent findCoursesIntent; if (config.getCourseDiscoveryConfig().isWebviewCourseDiscoveryEnabled()) { findCoursesIntent = new Intent(context, WebViewExploreSubjectsActivity.class); } else { throw new RuntimeException("'Explore Subjects' is not implemented for native course discovery"); } //Add this flag as multiple activities need to be created findCoursesIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); context.startActivity(findCoursesIntent); } public void showWebViewActivity(@NonNull Activity activity, @NonNull String url, @Nullable String title) { activity.startActivity(WebViewActivity.newIntent(activity, url, title)); } }