[APIv2/Login] EventBus: sticky events in Service. Add first login request in fragment.

This commit is contained in:
Kuba Szczodrzyński 2019-10-14 15:30:34 +02:00
parent c433a615db
commit 440b76d302
7 changed files with 116 additions and 255 deletions

View File

@ -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()

View File

@ -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<Profile>, val loginStore: LoginStore)

View File

@ -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}")
}*/
}
}

View File

@ -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
)
}
}

View File

@ -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)

View File

@ -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<Pair<Integer, Integer>> 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<Pair<Integer, Integer>> 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<Pair<Integer, Integer>> 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()));

View File

@ -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<Profile> 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<Profile> 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<String> 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);
}
}