From 7822810b912dbd810235361eb13ff130c125afc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Wed, 23 Oct 2019 19:13:54 +0200 Subject: [PATCH] [APIv2] Implement APIv2 in first login activity. --- .../edziennik/api/v2/ApiService.kt | 15 +- .../api/v2/events/SyncStartedEvent.kt | 4 +- .../events/requests/SyncProfileListRequest.kt | 7 + .../ui/modules/login/LoginSyncFragment.java | 227 ------------------ .../ui/modules/login/LoginSyncFragment.kt | 164 +++++++++++++ .../main/res/layout/fragment_login_sync.xml | 1 + 6 files changed, 189 insertions(+), 229 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncProfileListRequest.kt delete mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSyncFragment.java create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSyncFragment.kt diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt index d5545fb0..64086764 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt @@ -213,7 +213,7 @@ class ApiService : Service() { notification.setCurrentTask(taskRunningId, taskProfileName).post() // post an event - EventBus.getDefault().post(SyncStartedEvent(taskProfileId)) + EventBus.getDefault().post(SyncStartedEvent(taskProfileId, profile)) edziennikInterface = when (loginStore.type) { LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback) @@ -259,6 +259,19 @@ class ApiService : Service() { sync() } + @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) + fun onSyncProfileListRequest(request: SyncProfileListRequest) { + EventBus.getDefault().removeStickyEvent(request) + Log.d(TAG, request.toString()) + + request.profileList.forEach { id -> + taskQueue += SyncProfileRequest(id, null).apply { + taskId = ++taskMaximumId + } + } + sync() + } + @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) fun onSyncProfileRequest(request: SyncProfileRequest) { EventBus.getDefault().removeStickyEvent(request) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncStartedEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncStartedEvent.kt index 86e5bb9d..471dc413 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncStartedEvent.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncStartedEvent.kt @@ -4,4 +4,6 @@ package pl.szczodrzynski.edziennik.api.v2.events -class SyncStartedEvent(val profileId: Int) \ No newline at end of file +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile + +class SyncStartedEvent(val profileId: Int, val profile: Profile? = null) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncProfileListRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncProfileListRequest.kt new file mode 100644 index 00000000..9daaac63 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncProfileListRequest.kt @@ -0,0 +1,7 @@ +/* + * Copyright (c) Kuba SzczodrzyƄski 2019-10-23. + */ + +package pl.szczodrzynski.edziennik.api.v2.events.requests + +class SyncProfileListRequest(val profileList: List) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSyncFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSyncFragment.java deleted file mode 100644 index 3b8c436e..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSyncFragment.java +++ /dev/null @@ -1,227 +0,0 @@ -package pl.szczodrzynski.edziennik.ui.modules.login; - - -import android.content.Context; -import android.os.AsyncTask; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.databinding.DataBindingUtil; -import androidx.fragment.app.Fragment; - -import android.text.Html; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import java.util.ArrayList; -import java.util.List; - -import androidx.navigation.NavController; -import androidx.navigation.Navigation; -import pl.szczodrzynski.edziennik.App; -import pl.szczodrzynski.edziennik.R; -import pl.szczodrzynski.edziennik.data.api.AppError; -import pl.szczodrzynski.edziennik.data.api.interfaces.SyncCallback; -import pl.szczodrzynski.edziennik.databinding.FragmentLoginSyncBinding; -import pl.szczodrzynski.edziennik.data.db.modules.events.EventType; -import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore; -import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile; -import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull; -import pl.szczodrzynski.edziennik.sync.SyncJob; -import pl.szczodrzynski.edziennik.sync.SyncService; - -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_CLASS_EVENT; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_DEFAULT; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_EXAM; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_EXCURSION; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_HOMEWORK; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_INFORMATION; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_PROJECT; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_PT_MEETING; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_READING; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_SHORT_QUIZ; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_CLASS_EVENT; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_DEFAULT; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_ESSAY; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_EXAM; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_EXCURSION; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_HOMEWORK; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_INFORMATION; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_PROJECT; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_PT_MEETING; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_READING; -import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_SHORT_QUIZ; -import static pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile.REGISTRATION_DISABLED; -import static pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile.REGISTRATION_ENABLED; -import static pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile.REGISTRATION_UNSPECIFIED; -import static pl.szczodrzynski.edziennik.utils.Utils.d; - -public class LoginSyncFragment extends Fragment { - - private App app; - private NavController nav; - private FragmentLoginSyncBinding b; - private static final String TAG = "LoginSyncFragment"; - private List profileNameList = new ArrayList<>(); - private int profileIndex = 0; - - public LoginSyncFragment() { } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - // Inflate the layout for this fragment - if (getActivity() != null) { - app = (App) getActivity().getApplicationContext(); - nav = Navigation.findNavController(getActivity(), R.id.nav_host_fragment); - } - else { - return null; - } - b = DataBindingUtil.inflate(inflater, R.layout.fragment_login_sync, container, false); - return b.getRoot(); - } - - private void begin() { - AsyncTask.execute(() -> { - if (getActivity() == null) { - return; - } - int profileId = app.profileLastId()+1; - final int firstProfileId = profileId; - int loginStoreId = profileId; - // profileId contains the first ID free to use - - for (LoginProfileObject profileObject: LoginActivity.profileObjects) { - int subIndex = 0; - for (Profile profile: profileObject.profileList) { - if (profileObject.selectedList.get(subIndex)) { - saveProfile( - profile, - profileObject.loginStore, - profileId, - loginStoreId - ); - profileNameList.add(profile.getName()); - profileId++; - } - subIndex++; - } - loginStoreId = profileId; - } - - for (Profile profile: app.db.profileDao().getAllNow()) { - d(TAG, profile.toString()); - } - for (LoginStore loginStore: app.db.loginStoreDao().getAllNow()) { - d(TAG, loginStore.toString()); - } - - if (app.appConfig.loginFinished) { - LoginFinishFragment.firstRun = false; - } - else { - LoginFinishFragment.firstRun = true; - app.appConfig.loginFinished = true; - app.saveConfig("loginFinished"); - } - LoginFinishFragment.firstProfileId = firstProfileId; - - getActivity().runOnUiThread(() -> { - profileIndex = 0; - b.loginSyncSubtitle1.setText(Html.fromHtml(getString(R.string.login_sync_subtitle_1_format, profileNameList.size() > profileIndex ? profileNameList.get(profileIndex) : " "))); - }); - SyncJob.run(app, firstProfileId, -1); - }); - } - - private void saveProfile(Profile profile, LoginStore loginStore, int profileId, int loginStoreId) { - profile.setRegistration(REGISTRATION_UNSPECIFIED); - if (getArguments() != null) { - if (getArguments().getBoolean("registrationAllowed", false)) { - profile.setRegistration(REGISTRATION_ENABLED); - } - else { - profile.setRegistration(REGISTRATION_DISABLED); - } - } - profile.setId(profileId); - profile.setLoginStoreId(loginStoreId); - loginStore.id = loginStoreId; - List typeList = new ArrayList<>(); - typeList.add(new EventType(profileId, TYPE_HOMEWORK, getString(R.string.event_type_homework), COLOR_HOMEWORK)); - typeList.add(new EventType(profileId, TYPE_DEFAULT, getString(R.string.event_other), COLOR_DEFAULT)); - typeList.add(new EventType(profileId, TYPE_EXAM, getString(R.string.event_exam), COLOR_EXAM)); - typeList.add(new EventType(profileId, TYPE_SHORT_QUIZ, getString(R.string.event_short_quiz), COLOR_SHORT_QUIZ)); - typeList.add(new EventType(profileId, TYPE_ESSAY, getString(R.string.event_essay), COLOR_SHORT_QUIZ)); - typeList.add(new EventType(profileId, TYPE_PROJECT, getString(R.string.event_project), COLOR_PROJECT)); - typeList.add(new EventType(profileId, TYPE_PT_MEETING, getString(R.string.event_pt_meeting), COLOR_PT_MEETING)); - typeList.add(new EventType(profileId, TYPE_EXCURSION, getString(R.string.event_excursion), COLOR_EXCURSION)); - typeList.add(new EventType(profileId, TYPE_READING, getString(R.string.event_reading), COLOR_READING)); - typeList.add(new EventType(profileId, TYPE_CLASS_EVENT, getString(R.string.event_class_event), COLOR_CLASS_EVENT)); - typeList.add(new EventType(profileId, TYPE_INFORMATION, getString(R.string.event_information), COLOR_INFORMATION)); - app.db.eventTypeDao().addAll(typeList); - app.profileSaveFull(profile, loginStore); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - assert getContext() != null; - assert getActivity() != null; - - LoginActivity.error = null; - - SyncService.customCallback = new SyncCallback() { - @Override public void onLoginFirst(List profileList, LoginStore loginStore) { } - - @Override - public void onSuccess(Context activityContext, ProfileFull profileFull) { - if (getActivity() == null) - return; - getActivity().runOnUiThread(() -> { - if (profileFull != null) { - // a profile is finished - profileIndex++; - b.loginSyncSubtitle1.setText(Html.fromHtml(getString(R.string.login_sync_subtitle_1_format, profileIndex < profileNameList.size() ? profileNameList.get(profileIndex) : profileNameList.get(profileNameList.size()-1)))); - } - else { - // all profiles are finished - nav.navigate(R.id.loginFinishFragment, null , LoginActivity.navOptions); - } - }); - } - - @Override - public void onError(Context activityContext, AppError error) { - LoginActivity.error = error; - if (getActivity() != null) { - getActivity().runOnUiThread(() -> { - nav.navigate(R.id.loginSyncErrorFragment, null, LoginActivity.navOptions); - }); - } - } - - @Override - public void onProgress(int progressStep) { - if (getActivity() == null) - return; - getActivity().runOnUiThread(() -> { - b.loginSyncProgressBar.setMax(SyncService.maxProgress); - b.loginSyncProgressBar.setProgress(SyncService.progress); - }); - } - - @Override - public void onActionStarted(int stringResId) { - if (getActivity() == null) - return; - getActivity().runOnUiThread(() -> { - b.loginSyncSubtitle2.setText(getString(R.string.login_sync_subtitle_2_format, getString(stringResId))); - }); - } - }; - - begin(); - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSyncFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSyncFragment.kt new file mode 100644 index 00000000..006c8e75 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSyncFragment.kt @@ -0,0 +1,164 @@ +package pl.szczodrzynski.edziennik.ui.modules.login + + +import android.os.AsyncTask +import android.os.Bundle +import android.text.Html +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.navigation.NavController +import androidx.navigation.Navigation +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.api.v2.ApiService +import pl.szczodrzynski.edziennik.api.v2.events.SyncErrorEvent +import pl.szczodrzynski.edziennik.api.v2.events.SyncFinishedEvent +import pl.szczodrzynski.edziennik.api.v2.events.SyncProgressEvent +import pl.szczodrzynski.edziennik.api.v2.events.SyncStartedEvent +import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncProfileListRequest +import pl.szczodrzynski.edziennik.data.db.modules.events.Event.* +import pl.szczodrzynski.edziennik.data.db.modules.events.EventType +import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile.Companion.REGISTRATION_DISABLED +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile.Companion.REGISTRATION_ENABLED +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile.Companion.REGISTRATION_UNSPECIFIED +import pl.szczodrzynski.edziennik.databinding.FragmentLoginSyncBinding + +class LoginSyncFragment : Fragment() { + + private lateinit var app: App + private lateinit var activity: LoginActivity + private lateinit var b: FragmentLoginSyncBinding + private val nav: NavController by lazy { Navigation.findNavController(activity, R.id.nav_host_fragment) } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + activity = (getActivity() as LoginActivity?) ?: return null + if (context == null) + return null + app = activity.application as App + b = FragmentLoginSyncBinding.inflate(inflater) + return b.root + } + + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncStartedEvent(event: SyncStartedEvent) { + b.loginSyncSubtitle1.text = Html.fromHtml(getString(R.string.login_sync_subtitle_1_format, event.profile?.name ?: "")) + } + + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncFinishedEvent(event: SyncFinishedEvent) { + nav.navigate(R.id.loginFinishFragment, null, LoginActivity.navOptions) + } + + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncProgressEvent(event: SyncProgressEvent) { + b.loginSyncProgressBar.progress = event.progress + b.loginSyncSubtitle2.text = event.progressRes?.let { getString(it) } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncErrorEvent(event: SyncErrorEvent) { + LoginActivity.error = event.error.toAppError() + nav.navigate(R.id.loginSyncErrorFragment, null, LoginActivity.navOptions) + } + + private fun begin() { + AsyncTask.execute { + var profileId = app.profileLastId() + 1 + val firstProfileId = profileId + var loginStoreId = profileId + // profileId contains the first ID free to use + + val profileIds = mutableListOf() + + for (profileObject in LoginActivity.profileObjects) { + for ((subIndex, profile) in profileObject.profileList.withIndex()) { + if (profileObject.selectedList[subIndex]) { + saveProfile( + profile, + profileObject.loginStore, + profileId, + loginStoreId + ) + profileIds += profileId + profileId++ + } + } + loginStoreId = profileId + } + + /*for (profile in app.db.profileDao().allNow) { + d(TAG, profile.toString()) + } + for (loginStore in app.db.loginStoreDao().allNow) { + d(TAG, loginStore.toString()) + }*/ + + if (app.appConfig.loginFinished) { + LoginFinishFragment.firstRun = false + } else { + LoginFinishFragment.firstRun = true + app.appConfig.loginFinished = true + app.saveConfig("loginFinished") + } + LoginFinishFragment.firstProfileId = firstProfileId + + ApiService.start(activity) + EventBus.getDefault().postSticky(SyncProfileListRequest(profileIds)) + } + } + + private fun saveProfile(profile: Profile, loginStore: LoginStore, profileId: Int, loginStoreId: Int) { + profile.registration = REGISTRATION_UNSPECIFIED + if (arguments != null) { + if (arguments!!.getBoolean("registrationAllowed", false)) { + profile.registration = REGISTRATION_ENABLED + } else { + profile.registration = REGISTRATION_DISABLED + } + } + profile.id = profileId + profile.loginStoreId = loginStoreId + loginStore.id = loginStoreId + val typeList = listOf( + EventType(profileId, TYPE_HOMEWORK, getString(R.string.event_type_homework), COLOR_HOMEWORK), + EventType(profileId, TYPE_DEFAULT, getString(R.string.event_other), COLOR_DEFAULT), + EventType(profileId, TYPE_EXAM, getString(R.string.event_exam), COLOR_EXAM), + EventType(profileId, TYPE_SHORT_QUIZ, getString(R.string.event_short_quiz), COLOR_SHORT_QUIZ), + EventType(profileId, TYPE_ESSAY, getString(R.string.event_essay), COLOR_SHORT_QUIZ), + EventType(profileId, TYPE_PROJECT, getString(R.string.event_project), COLOR_PROJECT), + EventType(profileId, TYPE_PT_MEETING, getString(R.string.event_pt_meeting), COLOR_PT_MEETING), + EventType(profileId, TYPE_EXCURSION, getString(R.string.event_excursion), COLOR_EXCURSION), + EventType(profileId, TYPE_READING, getString(R.string.event_reading), COLOR_READING), + EventType(profileId, TYPE_CLASS_EVENT, getString(R.string.event_class_event), COLOR_CLASS_EVENT), + EventType(profileId, TYPE_INFORMATION, getString(R.string.event_information), COLOR_INFORMATION) + ) + app.db.eventTypeDao().addAll(typeList) + app.profileSaveFull(profile, loginStore) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + if (!isAdded) + return + + LoginActivity.error = null + + begin() + } + + override fun onStart() { + EventBus.getDefault().register(this) + super.onStart() + } + + override fun onStop() { + super.onStop() + EventBus.getDefault().unregister(this) + } +} diff --git a/app/src/main/res/layout/fragment_login_sync.xml b/app/src/main/res/layout/fragment_login_sync.xml index ab0cce52..a0b072c6 100644 --- a/app/src/main/res/layout/fragment_login_sync.xml +++ b/app/src/main/res/layout/fragment_login_sync.xml @@ -51,6 +51,7 @@ android:layout_marginTop="8dp" android:layout_marginRight="24dp" android:layout_marginBottom="8dp" + android:max="100" android:indeterminate="false" />