From 440b76d3029be79ef2761d5b1955640bcec3e10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Mon, 14 Oct 2019 15:30:34 +0200 Subject: [PATCH] [APIv2/Login] EventBus: sticky events in Service. Add first login request in fragment. --- .../edziennik/api/v2/ApiService.kt | 53 +++-- .../api/v2/events/FirstLoginFinishedEvent.kt | 6 + .../edziennik/api/v2/librus/LibrusTest.kt | 81 -------- .../edziennik/api/v2/models/ApiError.kt | 15 +- .../edziennik/api/v2/models/Data.kt | 2 +- .../ui/modules/home/HomeFragment.java | 29 ++- .../modules/login/LoginProgressFragment.java | 185 +++++------------- 7 files changed, 116 insertions(+), 255 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/FirstLoginFinishedEvent.kt delete mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusTest.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 4ffc122c..d505afc5 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 @@ -133,6 +133,7 @@ class ApiService : Service() { taskRunningObject = task if (task is ErrorReportTask) { + queueHasErrorReportTask = false notification .setCurrentTask(taskRunningId, null) .setProgressRes(R.string.edziennik_notification_api_error_report_title) @@ -210,8 +211,11 @@ class ApiService : Service() { | __\ \ / / _ \ '_ \| __| _ <| | | / __| | |___\ V / __/ | | | |_| |_) | |_| \__ \ |______\_/ \___|_| |_|\__|____/ \__,_|__*/ - @Subscribe(threadMode = ThreadMode.ASYNC) - fun onSyncRequest(syncRequest: SyncRequest) { + @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) + fun onSyncRequest(request: SyncRequest) { + EventBus.getDefault().removeStickyEvent(request) + Log.d(TAG, request.toString()) + app.db.profileDao().idsForSyncNow.forEach { id -> taskQueue += SyncProfileRequest(id, null).apply { taskId = ++taskMaximumId @@ -220,31 +224,52 @@ class ApiService : Service() { sync() } - @Subscribe(threadMode = ThreadMode.ASYNC) - fun onSyncProfileRequest(syncProfileRequest: SyncProfileRequest) { - Log.d(TAG, syncProfileRequest.toString()) - taskQueue += syncProfileRequest.apply { + @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) + fun onSyncProfileRequest(request: SyncProfileRequest) { + EventBus.getDefault().removeStickyEvent(request) + Log.d(TAG, request.toString()) + + taskQueue += request.apply { taskId = ++taskMaximumId } sync() } - @Subscribe(threadMode = ThreadMode.ASYNC) - fun onMessageGetRequest(messageGetRequest: MessageGetRequest) { - Log.d(TAG, messageGetRequest.toString()) - taskQueue += messageGetRequest.apply { + @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) + fun onMessageGetRequest(request: MessageGetRequest) { + EventBus.getDefault().removeStickyEvent(request) + Log.d(TAG, request.toString()) + + taskQueue += request.apply { taskId = ++taskMaximumId } sync() } - @Subscribe(threadMode = ThreadMode.ASYNC) - fun onTaskCancelRequest(taskCancelRequest: TaskCancelRequest) { + @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) + fun onFirstLoginRequest(request: FirstLoginRequest) { + EventBus.getDefault().removeStickyEvent(request) + Log.d(TAG, request.toString()) + + taskQueue += request.apply { + taskId = ++taskMaximumId + } + sync() + } + + @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) + fun onTaskCancelRequest(request: TaskCancelRequest) { + EventBus.getDefault().removeStickyEvent(request) + Log.d(TAG, request.toString()) + taskCancelled = true edziennikInterface?.cancel() } - @Subscribe(threadMode = ThreadMode.ASYNC) - fun onServiceCloseRequest(serviceCloseRequest: ServiceCloseRequest) { + @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) + fun onServiceCloseRequest(request: ServiceCloseRequest) { + EventBus.getDefault().removeStickyEvent(request) + Log.d(TAG, request.toString()) + serviceClosed = true taskCancelled = true edziennikInterface?.cancel() diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/FirstLoginFinishedEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/FirstLoginFinishedEvent.kt new file mode 100644 index 00000000..31fba7c9 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/FirstLoginFinishedEvent.kt @@ -0,0 +1,6 @@ +package pl.szczodrzynski.edziennik.api.v2.events + +import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile + +data class FirstLoginFinishedEvent(val profileList: List, val loginStore: LoginStore) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusTest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusTest.kt deleted file mode 100644 index 99647557..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusTest.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Kuba Szczodrzyński 2019-9-21. - */ - -package pl.szczodrzynski.edziennik.api.v2.librus - -import android.content.Intent -import com.google.gson.JsonObject -import pl.szczodrzynski.edziennik.App -import pl.szczodrzynski.edziennik.api.v2.ApiService -import pl.szczodrzynski.edziennik.api.v2.LOGIN_MODE_LIBRUS_EMAIL -import pl.szczodrzynski.edziennik.api.v2.LOGIN_TYPE_LIBRUS -import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore -import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile - -class LibrusTest(val app: App) { - companion object { - private const val TAG = "LibrusTest" - } - - val profile = Profile(1, "Profil", "xd", 1).apply { - //putStudentData("accountLogin", "1234567") - - //putStudentData("accountCode", LIBRUS_JST_DEMO_CODE) - //putStudentData("accountPin", LIBRUS_JST_DEMO_PIN) - - putStudentData("accountLogin", "1234567") - - //putStudentData("accountToken", "token") - //putStudentData("accountTokenTime", 1569458277) - } - val loginStore = LoginStore(1, LOGIN_TYPE_LIBRUS, JsonObject().apply { - addProperty("email", "test@example.com") - addProperty("password", "zaq1@WSX") - - //addProperty("accessToken", "token") - //addProperty("refreshToken", "refresh") - //addProperty("tokenExpiryTime", 1569523077) - }).also { - it.mode = LOGIN_MODE_LIBRUS_EMAIL - } - - fun go() { - - /*Librus(app, profile, loginStore, object : EdziennikCallback { - override fun onCompleted() {} - override fun onError(apiError: ApiError) {} - override fun onProgress(step: Int) {} - override fun onStartProgress(stringRes: Int) {} - }).sync(listOf(FEATURE_GRADES, FEATURE_STUDENT_INFO, FEATURE_STUDENT_NUMBER))*/ - - app.startService(Intent(app, ApiService::class.java)) - - if (false) { - - } - - /*val data = DataLibrus(app, profile, loginStore).apply { - callback = object : ProgressCallback { - override fun onProgress(progressStep: Int) { - - } - - override fun onActionStarted(stringResId: Int) { - d(TAG, app.getString(stringResId)) - } - - override fun onError(activityContext: Context?, error: AppError) { - error.changeIfCodeOther() - d(TAG, "Error "+error.getDetails(app)) - } - } - }*/ - - /*LoginLibrus(data, LOGIN_METHOD_LIBRUS_MESSAGES) { - d(TAG, "Login succeeded.") - d(TAG, "Profile data: ${data.profile?.studentData?.toString()}") - d(TAG, "LoginStore data: ${data.loginStore.data}") - }*/ - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiError.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiError.kt index 825809f9..0f5a484e 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiError.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiError.kt @@ -7,13 +7,14 @@ package pl.szczodrzynski.edziennik.api.v2.models import com.google.gson.JsonObject import im.wangchao.mhttp.Request import im.wangchao.mhttp.Response +import pl.szczodrzynski.edziennik.data.api.AppError class ApiError(val tag: String, val errorCode: Int) { var profileId: Int? = null var throwable: Throwable? = null - private var apiResponse: String? = null - private var request: Request? = null - private var response: Response? = null + var apiResponse: String? = null + var request: Request? = null + var response: Response? = null var isCritical = true fun withThrowable(throwable: Throwable?): ApiError { @@ -42,4 +43,12 @@ class ApiError(val tag: String, val errorCode: Int) { this.isCritical = isCritical return this } + + fun toAppError(): AppError { + return AppError( + tag, + -1, + errorCode, response, throwable, apiResponse + ) + } } \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt index 0f997738..ac2f1344 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt @@ -173,7 +173,7 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) open fun saveData() { if (profile == null) - return + return // return on first login db.profileDao().add(profile) db.loginStoreDao().add(loginStore) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragment.java index 8e8e1652..be65d045 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragment.java @@ -42,25 +42,25 @@ import java.util.List; import kotlin.Pair; import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.BuildConfig; -import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.MainActivity; +import pl.szczodrzynski.edziennik.R; +import pl.szczodrzynski.edziennik.api.v2.ApiService; import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncProfileRequest; -import pl.szczodrzynski.edziennik.api.v2.librus.LibrusTest; -import pl.szczodrzynski.edziennik.databinding.CardLuckyNumberBinding; -import pl.szczodrzynski.edziennik.databinding.CardUpdateBinding; -import pl.szczodrzynski.edziennik.databinding.FragmentHomeBinding; import pl.szczodrzynski.edziennik.data.db.modules.grades.GradeFull; import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull; import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile; import pl.szczodrzynski.edziennik.data.db.modules.subjects.Subject; -import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesComposeActivity; -import pl.szczodrzynski.edziennik.utils.models.Date; -import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel; -import pl.szczodrzynski.edziennik.utils.models.Time; +import pl.szczodrzynski.edziennik.databinding.CardLuckyNumberBinding; +import pl.szczodrzynski.edziennik.databinding.CardUpdateBinding; +import pl.szczodrzynski.edziennik.databinding.FragmentHomeBinding; import pl.szczodrzynski.edziennik.receivers.BootReceiver; +import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesComposeActivity; import pl.szczodrzynski.edziennik.utils.Colors; import pl.szczodrzynski.edziennik.utils.Themes; import pl.szczodrzynski.edziennik.utils.Utils; +import pl.szczodrzynski.edziennik.utils.models.Date; +import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel; +import pl.szczodrzynski.edziennik.utils.models.Time; import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem; import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem; @@ -68,7 +68,6 @@ import static pl.szczodrzynski.edziennik.App.UPDATES_ON_PLAY_STORE; import static pl.szczodrzynski.edziennik.MainActivity.DRAWER_ITEM_GRADES; import static pl.szczodrzynski.edziennik.MainActivity.DRAWER_ITEM_HOME; import static pl.szczodrzynski.edziennik.MainActivity.DRAWER_ITEM_MESSAGES; -import static pl.szczodrzynski.edziennik.api.v2.FeaturesKt.FEATURE_STUDENT_INFO; import static pl.szczodrzynski.edziennik.data.db.modules.grades.Grade.TYPE_SEMESTER1_FINAL; import static pl.szczodrzynski.edziennik.data.db.modules.grades.Grade.TYPE_SEMESTER1_PROPOSED; import static pl.szczodrzynski.edziennik.data.db.modules.grades.Grade.TYPE_SEMESTER2_FINAL; @@ -123,32 +122,30 @@ public class HomeFragment extends Fragment { startActivity(new Intent(activity, MessagesComposeActivity.class)); })); - LibrusTest librusTest = new LibrusTest(app); - b.testButton.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); b.testButton.setOnClickListener((v -> { - librusTest.go(); + app.startService(new Intent(app, ApiService.class)); })); b.test2.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); b.test2.setOnClickListener((v -> { List> list = new ArrayList<>(); list.add(new Pair<>(DRAWER_ITEM_HOME, 0)); - EventBus.getDefault().post(new SyncProfileRequest(app.profile.getId(), list)); + EventBus.getDefault().postSticky(new SyncProfileRequest(app.profile.getId(), list)); })); b.test3.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); b.test3.setOnClickListener((v -> { List> list = new ArrayList<>(); list.add(new Pair<>(DRAWER_ITEM_MESSAGES, TYPE_SENT)); - EventBus.getDefault().post(new SyncProfileRequest(app.profile.getId(), list)); + EventBus.getDefault().postSticky(new SyncProfileRequest(app.profile.getId(), list)); })); b.test4.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); b.test4.setOnClickListener((v -> { List> list = new ArrayList<>(); list.add(new Pair<>(DRAWER_ITEM_GRADES, 0)); - EventBus.getDefault().post(new SyncProfileRequest(app.profile.getId(), list)); + EventBus.getDefault().postSticky(new SyncProfileRequest(app.profile.getId(), list)); })); //((TextView)v.findViewById(R.id.nextSync)).setText(getString(R.string.next_sync_format,Time.fromMillis(app.appJobs.syncJobTime).getStringHMS())); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginProgressFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginProgressFragment.java index 93f00fa3..943a14e5 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginProgressFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginProgressFragment.java @@ -1,32 +1,33 @@ package pl.szczodrzynski.edziennik.ui.modules.login; -import androidx.databinding.DataBindingUtil; - -import android.content.Context; +import android.content.Intent; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import com.google.gson.JsonObject; - -import java.util.List; - +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; +import androidx.fragment.app.Fragment; import androidx.navigation.NavController; import androidx.navigation.Navigation; + +import com.google.gson.JsonObject; + +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.data.api.Edziennik; +import pl.szczodrzynski.edziennik.api.v2.ApiService; +import pl.szczodrzynski.edziennik.api.v2.events.FirstLoginFinishedEvent; +import pl.szczodrzynski.edziennik.api.v2.events.SyncErrorEvent; +import pl.szczodrzynski.edziennik.api.v2.events.requests.FirstLoginRequest; import pl.szczodrzynski.edziennik.data.api.AppError; -import pl.szczodrzynski.edziennik.data.api.interfaces.SyncCallback; -import pl.szczodrzynski.edziennik.databinding.FragmentLoginProgressBinding; 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.databinding.FragmentLoginProgressBinding; import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_OTHER; @@ -53,6 +54,22 @@ public class LoginProgressFragment extends Fragment { return b.getRoot(); } + @Subscribe(threadMode = ThreadMode.MAIN) + public void onFirstLoginFinishedEvent(FirstLoginFinishedEvent event) { + LoginActivity.profileObjects.add(new LoginProfileObject( + event.getLoginStore(), + event.getProfileList())); + nav.navigate(R.id.loginSummaryFragment, null, LoginActivity.navOptions); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onSyncErrorEvent(SyncErrorEvent event) { + LoginActivity.error = event.getError().toAppError(); + if (getActivity() == null) + return; + nav.navigateUp(); + } + @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { assert getContext() != null; @@ -72,131 +89,19 @@ public class LoginProgressFragment extends Fragment { LoginStore loginStore = new LoginStore(-1, loginType, new JsonObject()); loginStore.copyFrom(args); - Edziennik.getApi(app, loginType).sync(getActivity(), new SyncCallback() { - @Override - public void onLoginFirst(List profileList, LoginStore loginStore) { - // because these callbacks are always on a worker thread - if (getActivity() != null) { - getActivity().runOnUiThread(() -> { - LoginActivity.profileObjects.add(new LoginProfileObject( - loginStore, - profileList)); - nav.navigate(R.id.loginSummaryFragment, null, LoginActivity.navOptions); - }); - } - } + getContext().startService(new Intent(app, ApiService.class)); + EventBus.getDefault().postSticky(new FirstLoginRequest(loginStore)); + } - @Override - public void onSuccess(Context activityContext, ProfileFull profileFull) { + @Override + public void onStart() { + EventBus.getDefault().register(this); + super.onStart(); + } - } - - @Override - public void onError(Context activityContext, AppError error) { - LoginActivity.error = error; - // because these callbacks are always on a worker thread - if (getActivity() == null) - return; - getActivity().runOnUiThread(() -> { - nav.navigateUp(); - }); - } - - @Override - public void onProgress(int progressStep) { - - } - - @Override - public void onActionStarted(int stringResId) { - - } - }, -1, null, loginStore); - - /*if (true) - return; - JsonObject loginData = new JsonObject(); - loginData.addProperty("serverName", b.loginServerAddress.getText().toString()); - loginData.addProperty("username", b.loginUsername.getText().toString()); - loginData.addProperty("password", b.loginPassword.getText().toString()); - getApi(app, LOGIN_TYPE_MOBIDZIENNIK).sync(getActivity(), new Edziennik.DataCallback() { - @Override - public void onLoginFirst(List profileList, LoginStore loginStore) { - int profileId = app.profileLastId()+1; - if (profileList.size() == 1) { - Profile profile = profileList.get(0); - saveProfile(profile, loginStore, profileId, profileId); - finishSaving(); - return; - } - List profileNames = new ArrayList<>(); - for (Profile profile: profileList) { - profileNames.add(profile.name); - } - new MaterialDialog.Builder(getActivity()) - .title(R.string.sync_multiaccount_select_students) - .items(profileNames) - .positiveText(R.string.ok) - .negativeText(R.string.cancel) - .neutralText(R.string.help) - .autoDismiss(false) - .canceledOnTouchOutside(false) - .onNeutral((dialog, which) -> - new MaterialDialog.Builder(getActivity()) - .title(R.string.help) - .content(R.string.sync_multiaccount_select_students_text) - .positiveText(R.string.ok) - .show() - ) - .onNegative(((dialog, which) -> dialog.dismiss())) - .itemsCallbackMultiChoice(null, (dialog, which, text) -> { - // create new profiles, then restart the application or sth - if (text.length < 1 || which.length < 1) { - Toast.makeText(app, R.string.sync_multiaccount_select_students_error, Toast.LENGTH_SHORT).show(); - return false; - } - dialog.dismiss(); - int pos = 0; - for (int index: which) { - Profile profile = profileList.get(index); - saveProfile(profile, loginStore, profileId+(pos++), profileId); - } - finishSaving(); - - - String list = ""; - for (ProfileFull profileFull: app.db.profileDao().getAllFullNow()) { - d(TAG, profileFull.toString()); - list += profileFull.studentNameLong+" student ID "+profileFull.getStudentData("studentId", -1)+"\n"; - } - d(TAG, loginStore.toString()); - list += loginStore.getLoginData("username", "(NO USERNAME)")+"\n"; - new MaterialDialog.Builder(getActivity()) - .title("Znaleziono profile") - .content(list) - .positiveText("OK") - .show(); - - - return false; - }) - .show(); - } - - @Override - public void onSuccess(Context activityContext, ProfileFull profile) { - Toast.makeText(activityContext, "Zakończono", Toast.LENGTH_SHORT).show(); - } - - @Override - public void onError(Context activityContext, int errorCode, String errorText, Throwable throwable, String apiResponse) { - - } - - @Override - public void onProgress(int progressStep) { - - } - }, -1, null, new LoginStore(-1, LOGIN_TYPE_MOBIDZIENNIK, loginData));*/ + @Override + public void onStop() { + super.onStop(); + EventBus.getDefault().unregister(this); } }