From 4c6b46784764dc0bfd138940f811ad025d0ddc9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 1 Oct 2019 21:27:09 +0200 Subject: [PATCH] [APIv2] Finalize the basic API service. Add notification. Add exported broadcast receiver. --- app/src/main/AndroidManifest.xml | 7 + .../pl/szczodrzynski/edziennik/Notifier.java | 2 +- .../edziennik/api/v2/ApiService.kt | 131 +++++++++++++--- .../edziennik/api/v2/EdziennikNotification.kt | 140 ++++++++++++++++++ .../edziennik/api/v2/Endpoints.kt | 82 +++++----- .../api/v2/events/ErrorReportTask.kt | 9 ++ .../v2/events/requests/ServiceCloseRequest.kt | 7 + .../api/v2/events/requests/SyncRequest.kt | 2 +- .../v2/events/requests/TaskCancelRequest.kt | 7 + .../api/v2/interfaces/EdziennikInterface.kt | 1 + .../edziennik/api/v2/librus/Librus.kt | 90 +++++------ .../api/v2/librus/LibrusEndpoints.kt | 52 +++++++ .../edziennik/api/v2/librus/LibrusLogin.kt | 72 +++++++++ .../edziennik/api/v2/librus/LibrusTest.kt | 10 +- .../edziennik/api/v2/models/ApiError.kt | 6 + .../edziennik/api/v2/models/Data.kt | 21 ++- .../edziennik/fragments/HomeFragment.java | 25 +++- .../edziennik/receivers/SzkolnyReceiver.kt | 23 +++ app/src/main/res/layout/fragment_home.xml | 29 +++- app/src/main/res/values/plurals.xml | 14 ++ app/src/main/res/values/strings.xml | 9 ++ 21 files changed, 615 insertions(+), 124 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/EdziennikNotification.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/ErrorReportTask.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/ServiceCloseRequest.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/TaskCancelRequest.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusEndpoints.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusLogin.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f5f02d8b..9031bd28 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -218,6 +218,13 @@ android:name=".sync.SyncService" android:icon="@mipmap/ic_launcher" android:label="@string/sync_service" /> + + + + + diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/Notifier.java b/app/src/main/java/pl/szczodrzynski/edziennik/Notifier.java index 512affed..000fc179 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/Notifier.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/Notifier.java @@ -71,7 +71,7 @@ public class Notifier { notificationColor = ContextCompat.getColor(app.getContext(), R.color.colorPrimary); notificationManager = (NotificationManager) app.getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel channelGetData = new NotificationChannel(GROUP_KEY_GET_DATA, CHANNEL_GET_DATA_NAME, NotificationManager.IMPORTANCE_LOW); + NotificationChannel channelGetData = new NotificationChannel(GROUP_KEY_GET_DATA, CHANNEL_GET_DATA_NAME, NotificationManager.IMPORTANCE_MIN); channelGetData.setDescription(CHANNEL_GET_DATA_DESC); notificationManager.createNotificationChannel(channelGetData); 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 97732a36..88710709 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 @@ -14,12 +14,10 @@ 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.events.requests.MessageGetRequest -import pl.szczodrzynski.edziennik.api.v2.events.SyncProgressEvent -import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncProfileRequest -import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest -import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncViewRequest +import pl.szczodrzynski.edziennik.api.v2.events.* +import pl.szczodrzynski.edziennik.api.v2.events.requests.* import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback +import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface import pl.szczodrzynski.edziennik.api.v2.librus.Librus import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.api.v2.models.ApiTask @@ -37,46 +35,99 @@ class ApiService : Service() { private val taskQueue = mutableListOf() private val errorList = mutableListOf() + private var queueHasErrorReportTask = false + private var taskCancelled = false private var taskRunning = false private var taskRunningId = -1 private var taskMaximumId = 0 + private var edziennikInterface: EdziennikInterface? = null private var taskProfileId = -1 private var taskProfileName: String? = null private var taskProgress = 0 private var taskProgressRes: Int? = null + private val notification by lazy { EdziennikNotification(this) } + + /* ______ _ _ _ _ _____ _ _ _ _ + | ____| | | (_) (_) | / ____| | | | | | | + | |__ __| |_____ ___ _ __ _ __ _| | __ | | __ _| | | |__ __ _ ___| | __ + | __| / _` |_ / |/ _ \ '_ \| '_ \| | |/ / | | / _` | | | '_ \ / _` |/ __| |/ / + | |___| (_| |/ /| | __/ | | | | | | | < | |___| (_| | | | |_) | (_| | (__| < + |______\__,_/___|_|\___|_| |_|_| |_|_|_|\_\ \_____\__,_|_|_|_.__/ \__,_|\___|_|\*/ private val taskCallback = object : EdziennikCallback { override fun onCompleted() { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + edziennikInterface = null + if (!taskCancelled) { + EventBus.getDefault().post(SyncProfileFinishedEvent(taskProfileId)) + } + notification.setIdle().post() + taskRunning = false + taskRunningId = -1 + sync() } override fun onError(apiError: ApiError) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + if (!queueHasErrorReportTask) { + queueHasErrorReportTask = true + taskQueue += ErrorReportTask().apply { + taskId = ++taskMaximumId + } + } + EventBus.getDefault().post(SyncErrorEvent(apiError)) + errorList.add(apiError) + if (apiError.isCritical) { + notification.setCriticalError().post() + taskRunning = false + taskRunningId = -1 + sync() + } + else { + notification.addError().post() + } } override fun onProgress(step: Int) { taskProgress += step taskProgress = min(100, taskProgress) EventBus.getDefault().post(SyncProgressEvent(taskProfileId, taskProfileName, taskProgress, taskProgressRes)) + notification.setProgress(taskProgress).post() } override fun onStartProgress(stringRes: Int) { - + taskProgressRes = stringRes + EventBus.getDefault().post(SyncProgressEvent(taskProfileId, taskProfileName, taskProgress, taskProgressRes)) + notification.setProgressRes(taskProgressRes!!).post() } } + /* _______ _ _ _ + |__ __| | | | | (_) + | | __ _ ___| | __ _____ _____ ___ _ _| |_ _ ___ _ __ + | |/ _` / __| |/ / / _ \ \/ / _ \/ __| | | | __| |/ _ \| '_ \ + | | (_| \__ \ < | __/> < __/ (__| |_| | |_| | (_) | | | | + |_|\__,_|___/_|\_\ \___/_/\_\___|\___|\__,_|\__|_|\___/|_| |*/ private fun sync() { if (taskRunning) return - if (taskQueue.size <= 0) - return // TODO stopSelf() or sth + if (taskQueue.size <= 0) { + allCompleted() + return + } val task = taskQueue.removeAt(0) + taskCancelled = false taskRunning = true taskRunningId = task.taskId + if (task is ErrorReportTask) { + notification + .setCurrentTask(taskRunningId, null) + .setProgressRes(R.string.edziennik_notification_api_error_report_title) + return + } + // get the requested profile and login store val profile: Profile? = app.db.profileDao().getByIdNow(task.profileId) if (profile == null || !profile.syncEnabled) { @@ -92,8 +143,10 @@ class ApiService : Service() { taskProgress = 0 taskProgressRes = null + // update the notification + notification.setCurrentTask(taskRunningId, taskProfileName).post() - val edziennikInterface = when (loginStore.type) { + edziennikInterface = when (loginStore.type) { LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback) else -> null } @@ -102,17 +155,29 @@ class ApiService : Service() { } when (task) { - is SyncProfileRequest -> edziennikInterface.sync(task.featureIds ?: Features.getAllIds()) - is SyncViewRequest -> edziennikInterface.sync(Features.getIdsByView(task.targetId)) - is MessageGetRequest -> edziennikInterface.getMessage(task.messageId) + is SyncProfileRequest -> edziennikInterface?.sync(task.featureIds ?: Features.getAllIds()) + is SyncViewRequest -> edziennikInterface?.sync(Features.getIdsByView(task.targetId)) + is MessageGetRequest -> edziennikInterface?.getMessage(task.messageId) } } + private fun allCompleted() { + EventBus.getDefault().post(SyncFinishedEvent()) + stopSelf() + } + /* ______ _ ____ + | ____| | | | _ \ + | |____ _____ _ __ | |_| |_) |_ _ ___ + | __\ \ / / _ \ '_ \| __| _ <| | | / __| + | |___\ V / __/ | | | |_| |_) | |_| \__ \ + |______\_/ \___|_| |_|\__|____/ \__,_|__*/ @Subscribe(threadMode = ThreadMode.ASYNC) fun onSyncRequest(syncRequest: SyncRequest) { app.db.profileDao().idsForSyncNow.forEach { id -> - taskQueue += SyncProfileRequest(id, null) + taskQueue += SyncProfileRequest(id, null).apply { + taskId = ++taskMaximumId + } } sync() } @@ -120,31 +185,49 @@ class ApiService : Service() { @Subscribe(threadMode = ThreadMode.ASYNC) fun onSyncProfileRequest(syncProfileRequest: SyncProfileRequest) { Log.d(TAG, syncProfileRequest.toString()) - taskQueue += syncProfileRequest + taskQueue += syncProfileRequest.apply { + taskId = ++taskMaximumId + } + sync() + } + + @Subscribe(threadMode = ThreadMode.ASYNC) + fun onSyncViewRequest(syncViewRequest: SyncViewRequest) { + Log.d(TAG, syncViewRequest.toString()) + taskQueue += syncViewRequest.apply { + taskId = ++taskMaximumId + } sync() } @Subscribe(threadMode = ThreadMode.ASYNC) fun onMessageGetRequest(messageGetRequest: MessageGetRequest) { Log.d(TAG, messageGetRequest.toString()) - taskQueue += messageGetRequest + taskQueue += messageGetRequest.apply { + taskId = ++taskMaximumId + } sync() } - private val notification by lazy { - NotificationCompat.Builder(this, NOTIFICATION_API_CHANNEL_ID) - .setContentTitle("API") - .setContentText("API is running") - .setSmallIcon(R.drawable.ic_notification) - .build() + @Subscribe(threadMode = ThreadMode.ASYNC) + fun onTaskCancelRequest(taskCancelRequest: TaskCancelRequest) { + taskCancelled = true + edziennikInterface?.cancel() } + /* _____ _ _ _ + / ____| (_) (_) | | + | (___ ___ _ ____ ___ ___ ___ _____ _____ _ __ _ __ _ __| | ___ ___ + \___ \ / _ \ '__\ \ / / |/ __/ _ \ / _ \ \ / / _ \ '__| '__| |/ _` |/ _ \/ __| + ____) | __/ | \ V /| | (_| __/ | (_) \ V / __/ | | | | | (_| | __/\__ \ + |_____/ \___|_| \_/ |_|\___\___| \___/ \_/ \___|_| |_| |_|\__,_|\___||__*/ override fun onCreate() { EventBus.getDefault().register(this) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - startForeground(1, notification) + startForeground(EdziennikNotification.NOTIFICATION_ID, notification.notification) + notification.setIdle().setCloseAction().post() return START_NOT_STICKY } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/EdziennikNotification.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/EdziennikNotification.kt new file mode 100644 index 00000000..eeeb1968 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/EdziennikNotification.kt @@ -0,0 +1,140 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-10-1. + */ + +package pl.szczodrzynski.edziennik.api.v2 + +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationCompat.PRIORITY_LOW +import androidx.core.app.NotificationCompat.PRIORITY_MIN +import pl.szczodrzynski.edziennik.R + + +class EdziennikNotification(val context: Context) { + companion object { + const val NOTIFICATION_ID = 20191001 + } + + private val notificationManager by lazy { context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager } + + private val notificationBuilder: NotificationCompat.Builder by lazy { + NotificationCompat.Builder(context, ApiService.NOTIFICATION_API_CHANNEL_ID) + .setSmallIcon(R.drawable.ic_notification) + .setPriority(PRIORITY_MIN) + .setOngoing(true) + .setLocalOnly(true) + } + + val notification: Notification + get() = notificationBuilder.build() + + private var errorCount = 0 + private var criticalErrorCount = 0 + + private fun cancelPendingIntent(taskId: Int): PendingIntent { + val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN") + intent.putExtra("task", "TaskCancelRequest") + intent.putExtra("taskId", taskId) + return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent + } + private val closePendingIntent: PendingIntent + get() { + val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN") + intent.putExtra("task", "ServiceCloseRequest") + return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent + } + + private fun errorCountText(): String? { + var result = "" + if (criticalErrorCount > 0) { + result += context.resources.getQuantityString(R.plurals.critical_errors_format, criticalErrorCount, criticalErrorCount) + } + if (criticalErrorCount > 0 && errorCount > 0) { + result += ", " + } + if (errorCount > 0) { + result += context.resources.getQuantityString(R.plurals.normal_errors_format, errorCount, errorCount) + } + return if (result.isEmpty()) null else result + } + + fun setIdle(): EdziennikNotification { + notificationBuilder.setContentTitle(context.getString(R.string.edziennik_notification_api_title)) + notificationBuilder.setProgress(0, 0, false) + notificationBuilder.apply { + val str = context.getString(R.string.edziennik_notification_api_text) + setStyle(NotificationCompat.BigTextStyle().bigText(str)) + setContentText(str) + } + setCloseAction() + return this + } + + fun addError(): EdziennikNotification { + errorCount++ + return this + } + fun setCriticalError(): EdziennikNotification { + criticalErrorCount++ + notificationBuilder.setContentTitle(context.getString(R.string.edziennik_notification_api_error_title)) + notificationBuilder.setProgress(0, 0, false) + notificationBuilder.apply { + val str = errorCountText() + setStyle(NotificationCompat.BigTextStyle().bigText(str)) + setContentText(str) + } + setCloseAction() + return this + } + + fun setProgress(progress: Int): EdziennikNotification { + notificationBuilder.setProgress(100, progress, false) + return this + } + fun setProgressRes(progressRes: Int): EdziennikNotification { + notificationBuilder.setContentTitle(context.getString(progressRes)) + return this + } + + fun setCurrentTask(taskId: Int, profileName: String?): EdziennikNotification { + notificationBuilder.setProgress(100, 0, false) + notificationBuilder.setContentTitle(context.getString(R.string.edziennik_notification_api_sync_title_format, profileName)) + notificationBuilder.apply { + val str = errorCountText() + setStyle(NotificationCompat.BigTextStyle().bigText(str)) + setContentText(str) + } + setCancelAction(taskId) + return this + } + + fun setCloseAction(): EdziennikNotification { + notificationBuilder.mActions.clear() + notificationBuilder.addAction( + NotificationCompat.Action( + R.drawable.ic_notification, + context.getString(R.string.edziennik_notification_api_close), + closePendingIntent + )) + return this + } + private fun setCancelAction(taskId: Int) { + notificationBuilder.mActions.clear() + notificationBuilder.addAction( + NotificationCompat.Action( + R.drawable.ic_notification, + context.getString(R.string.edziennik_notification_api_cancel), + cancelPendingIntent(taskId) + )) + } + + fun post() { + notificationManager.notify(NOTIFICATION_ID, notification) + } + +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Endpoints.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Endpoints.kt index 4279ff02..9e65ad2e 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Endpoints.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Endpoints.kt @@ -6,47 +6,47 @@ package pl.szczodrzynski.edziennik.api.v2 import pl.szczodrzynski.edziennik.api.v2.models.Endpoint -const val ENDPOINT_LIBRUS_API_ME = 101 -const val ENDPOINT_LIBRUS_API_SCHOOLS = 102 -const val ENDPOINT_LIBRUS_API_CLASSES = 103 -const val ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES = 104 -const val ENDPOINT_LIBRUS_API_UNITS = 105 -const val ENDPOINT_LIBRUS_API_USERS = 106 -const val ENDPOINT_LIBRUS_API_SUBJECTS = 107 -const val ENDPOINT_LIBRUS_API_CLASSROOMS = 108 -const val ENDPOINT_LIBRUS_API_TIMETABLES = 109 -const val ENDPOINT_LIBRUS_API_SUBSTITUTIONS = 110 -const val ENDPOINT_LIBRUS_API_NORMAL_GC = 111 -const val ENDPOINT_LIBRUS_API_POINT_GC = 112 -const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_GC = 113 -const val ENDPOINT_LIBRUS_API_TEXT_GC = 114 -const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GC = 115 -const val ENDPOINT_LIBRUS_API_BEHAVIOUR_GC = 116 -const val ENDPOINT_LIBRUS_API_NORMAL_GRADES = 117 -const val ENDPOINT_LIBRUS_API_POINT_GRADES = 118 -const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES = 119 -const val ENDPOINT_LIBRUS_API_TEXT_GRADES = 120 -const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GRADES = 121 -const val ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES = 122 -const val ENDPOINT_LIBRUS_API_EVENTS = 123 -const val ENDPOINT_LIBRUS_API_EVENT_TYPES = 124 -const val ENDPOINT_LIBRUS_API_HOMEWORK = 125 -const val ENDPOINT_LIBRUS_API_LUCKY_NUMBER = 126 -const val ENDPOINT_LIBRUS_API_NOTICES = 127 -const val ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES = 128 -const val ENDPOINT_LIBRUS_API_ATTENDANCE = 129 -const val ENDPOINT_LIBRUS_API_ANNOUNCEMENTS = 130 -const val ENDPOINT_LIBRUS_API_PT_MEETINGS = 131 -const val ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS = 132 -const val ENDPOINT_LIBRUS_API_SCHOOL_FREE_DAYS = 133 -const val ENDPOINT_LIBRUS_API_CLASS_FREE_DAYS = 134 -const val ENDPOINT_LIBRUS_SYNERGIA_INFO = 201 -const val ENDPOINT_LIBRUS_SYNERGIA_GRADES = 202 -const val ENDPOINT_LIBRUS_MESSAGES_RECEIVED = 301 -const val ENDPOINT_LIBRUS_MESSAGES_SENT = 302 -const val ENDPOINT_LIBRUS_MESSAGES_TRASH = 303 -const val ENDPOINT_LIBRUS_MESSAGES_RECEIVERS = 304 -const val ENDPOINT_LIBRUS_MESSAGES_GET = 304 +const val ENDPOINT_LIBRUS_API_ME = 1001 +const val ENDPOINT_LIBRUS_API_SCHOOLS = 1002 +const val ENDPOINT_LIBRUS_API_CLASSES = 1003 +const val ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES = 1004 +const val ENDPOINT_LIBRUS_API_UNITS = 1005 +const val ENDPOINT_LIBRUS_API_USERS = 1006 +const val ENDPOINT_LIBRUS_API_SUBJECTS = 1007 +const val ENDPOINT_LIBRUS_API_CLASSROOMS = 1008 +const val ENDPOINT_LIBRUS_API_TIMETABLES = 1015 +const val ENDPOINT_LIBRUS_API_SUBSTITUTIONS = 1016 +const val ENDPOINT_LIBRUS_API_NORMAL_GC = 1021 +const val ENDPOINT_LIBRUS_API_POINT_GC = 1022 +const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_GC = 1023 +const val ENDPOINT_LIBRUS_API_TEXT_GC = 1024 +const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GC = 1025 +const val ENDPOINT_LIBRUS_API_BEHAVIOUR_GC = 1026 +const val ENDPOINT_LIBRUS_API_NORMAL_GRADES = 1031 +const val ENDPOINT_LIBRUS_API_POINT_GRADES = 1032 +const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES = 1033 +const val ENDPOINT_LIBRUS_API_TEXT_GRADES = 1034 +const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GRADES = 1035 +const val ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES = 1036 +const val ENDPOINT_LIBRUS_API_EVENTS = 1040 +const val ENDPOINT_LIBRUS_API_EVENT_TYPES = 1041 +const val ENDPOINT_LIBRUS_API_HOMEWORK = 1050 +const val ENDPOINT_LIBRUS_API_LUCKY_NUMBER = 1060 +const val ENDPOINT_LIBRUS_API_NOTICES = 1070 +const val ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES = 1080 +const val ENDPOINT_LIBRUS_API_ATTENDANCE = 1081 +const val ENDPOINT_LIBRUS_API_ANNOUNCEMENTS = 1090 +const val ENDPOINT_LIBRUS_API_PT_MEETINGS = 1100 +const val ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS = 1110 +const val ENDPOINT_LIBRUS_API_SCHOOL_FREE_DAYS = 1120 +const val ENDPOINT_LIBRUS_API_CLASS_FREE_DAYS = 1130 +const val ENDPOINT_LIBRUS_SYNERGIA_INFO = 2010 +const val ENDPOINT_LIBRUS_SYNERGIA_GRADES = 2020 +const val ENDPOINT_LIBRUS_MESSAGES_RECEIVED = 3010 +const val ENDPOINT_LIBRUS_MESSAGES_SENT = 3020 +const val ENDPOINT_LIBRUS_MESSAGES_TRASH = 3030 +const val ENDPOINT_LIBRUS_MESSAGES_RECEIVERS = 3040 +const val ENDPOINT_LIBRUS_MESSAGES_GET = 3040 val endpoints = listOf( diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/ErrorReportTask.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/ErrorReportTask.kt new file mode 100644 index 00000000..444443d1 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/ErrorReportTask.kt @@ -0,0 +1,9 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-10-1. + */ + +package pl.szczodrzynski.edziennik.api.v2.events + +import pl.szczodrzynski.edziennik.api.v2.models.ApiTask + +class ErrorReportTask : ApiTask(-1) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/ServiceCloseRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/ServiceCloseRequest.kt new file mode 100644 index 00000000..a859301c --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/ServiceCloseRequest.kt @@ -0,0 +1,7 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-10-1. + */ + +package pl.szczodrzynski.edziennik.api.v2.events.requests + +class ServiceCloseRequest \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncRequest.kt index 4570d3a4..ef42a557 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncRequest.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncRequest.kt @@ -4,4 +4,4 @@ package pl.szczodrzynski.edziennik.api.v2.events.requests -class SyncRequest() \ No newline at end of file +class SyncRequest \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/TaskCancelRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/TaskCancelRequest.kt new file mode 100644 index 00000000..f40a9455 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/TaskCancelRequest.kt @@ -0,0 +1,7 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-10-1. + */ + +package pl.szczodrzynski.edziennik.api.v2.events.requests + +class TaskCancelRequest(val taskId: Int) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikInterface.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikInterface.kt index 8265de7e..38367b8a 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikInterface.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikInterface.kt @@ -7,4 +7,5 @@ package pl.szczodrzynski.edziennik.api.v2.interfaces interface EdziennikInterface { fun sync(featureIds: List) fun getMessage(messageId: Int) + fun cancel() } \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/Librus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/Librus.kt index 3838970b..e1db1e50 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/Librus.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/Librus.kt @@ -6,25 +6,26 @@ package pl.szczodrzynski.edziennik.api.v2.librus import android.util.Log import pl.szczodrzynski.edziennik.App -import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 -import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_NOT_NEEDED -import pl.szczodrzynski.edziennik.api.v2.endpoints +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus -import pl.szczodrzynski.edziennik.api.v2.librusLoginMethods +import pl.szczodrzynski.edziennik.api.v2.librus.login.* import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.api.v2.models.Endpoint import pl.szczodrzynski.edziennik.datamodels.LoginStore import pl.szczodrzynski.edziennik.datamodels.Profile +import pl.szczodrzynski.edziennik.utils.Utils.d class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { companion object { - const val TAG = "Librus" + private const val TAG = "Librus" } val internalErrorList = mutableListOf() val data: DataLibrus + private var cancelled = false init { data = DataLibrus(app, profile, loginStore).apply { @@ -33,6 +34,19 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va data.satisfyLoginMethods() } + private fun completed() { + data.saveData() + callback.onCompleted() + } + + /* _______ _ _ _ _ _ + |__ __| | /\ | | (_) | | | + | | | |__ ___ / \ | | __ _ ___ _ __ _| |_| |__ _ __ ___ + | | | '_ \ / _ \ / /\ \ | |/ _` |/ _ \| '__| | __| '_ \| '_ ` _ \ + | | | | | | __/ / ____ \| | (_| | (_) | | | | |_| | | | | | | | | + |_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_| + __/ | + |__*/ override fun sync(featureIds: List) { val possibleLoginMethods = data.loginMethods.toMutableList() @@ -45,8 +59,8 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va var endpointList = mutableListOf() val requiredLoginMethods = mutableListOf() - var targetEndpointIds = mutableListOf() - var targetLoginMethodIds = mutableListOf() + data.targetEndpointIds.clear() + data.targetLoginMethodIds.clear() // get all endpoints for every feature, only if possible to login for (featureId in featureIds) { @@ -72,7 +86,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va .toMutableList() // add all endpoint IDs and required login methods .onEach { endpoint -> - targetEndpointIds.addAll(endpoint.endpointIds) + data.targetEndpointIds.addAll(endpoint.endpointIds) requiredLoginMethods.addAll(endpoint.requiredLoginMethods) } @@ -82,64 +96,38 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) { librusLoginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod -> if (requiredLoginMethod != null) - targetLoginMethodIds.add(requiredLoginMethod!!) + data.targetLoginMethodIds.add(requiredLoginMethod!!) requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore) } } } // sort and distinct every login method and endpoint - targetLoginMethodIds = targetLoginMethodIds.toHashSet().toMutableList() - targetLoginMethodIds.sort() + data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList() + data.targetLoginMethodIds.sort() - targetEndpointIds = targetEndpointIds.toHashSet().toMutableList() - targetLoginMethodIds.sort() + data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList() + data.targetEndpointIds.sort() + Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}") + Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}") - - //Log.d(TAG, endpointList.toString()) - Log.d(TAG, "LoginMethod IDs: $targetLoginMethodIds") - Log.d(TAG, "Endpoint IDs: $targetEndpointIds") - - /* - - INPUT: [ - FEATURE_GRADES, - FEATURE_STUDENT_INFO, - FEATURE_STUDENT_NUMBER - ] - - OUTPUT: [ - Endpoint(loginType=2, - featureId=FEATURE_GRADES, endpointIds=[ - ENDPOINT_LIBRUS_API_NORMAL_GC, - ENDPOINT_LIBRUS_API_NORMAL_GRADES, - ENDPOINT_LIBRUS_SYNERGIA_GRADES - ], requiredLoginMethods=[ - LOGIN_METHOD_LIBRUS_API, - LOGIN_METHOD_LIBRUS_SYNERGIA - ]), - Endpoint(loginType=2, - featureId=FEATURE_STUDENT_INFO, endpointIds=[ - ENDPOINT_LIBRUS_API_ME - ], requiredLoginMethods=[ - LOGIN_METHOD_LIBRUS_API - ]), - Endpoint(loginType=2, - featureId=FEATURE_STUDENT_NUMBER, endpointIds=[ - ENDPOINT_LIBRUS_SYNERGIA_INFO - ], requiredLoginMethods=[ - LOGIN_METHOD_LIBRUS_SYNERGIA - ]) - ] - - */ + LibrusLogin(data) { + LibrusEndpoints(data) { + completed() + } + } } override fun getMessage(messageId: Int) { } + override fun cancel() { + d(TAG, "Cancelled") + cancelled = true + } + private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback { return object : EdziennikCallback { override fun onCompleted() { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusEndpoints.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusEndpoints.kt new file mode 100644 index 00000000..7d981d48 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusEndpoints.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-10-1. + */ + +package pl.szczodrzynski.edziennik.api.v2.librus + +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.api.v2.* +import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus +import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApiMe +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusApi +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusMessages +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusPortal +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusSynergia +import pl.szczodrzynski.edziennik.utils.Utils + +class LibrusEndpoints(val data: DataLibrus, val onSuccess: () -> Unit) { + companion object { + private const val TAG = "LibrusEndpoints" + } + + private var cancelled = false + + init { + nextEndpoint(onSuccess) + } + + private fun nextEndpoint(onSuccess: () -> Unit) { + if (data.targetEndpointIds.isEmpty()) { + onSuccess() + return + } + useEndpoint(data.targetEndpointIds.removeAt(0)) { + if (cancelled) { + onSuccess() + return@useEndpoint + } + nextEndpoint(onSuccess) + } + } + + private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) { + Utils.d(TAG, "Using endpoint $endpointId") + when (endpointId) { + ENDPOINT_LIBRUS_API_ME -> { + data.startProgress(R.string.edziennik_progress_endpoint_student_info) + LibrusApiMe(data) { onSuccess() } + } + else -> onSuccess() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusLogin.kt new file mode 100644 index 00000000..ce9e848a --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusLogin.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-10-1. + */ + +package pl.szczodrzynski.edziennik.api.v2.librus + +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_LIBRUS_API +import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_LIBRUS_MESSAGES +import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_LIBRUS_PORTAL +import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_LIBRUS_SYNERGIA +import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusApi +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusMessages +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusPortal +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusSynergia +import pl.szczodrzynski.edziennik.utils.Utils + +class LibrusLogin(val data: DataLibrus, val onSuccess: () -> Unit) { + companion object { + private const val TAG = "LibrusLogin" + } + + private var cancelled = false + + init { + nextLoginMethod(onSuccess) + } + + private fun nextLoginMethod(onSuccess: () -> Unit) { + if (data.targetLoginMethodIds.isEmpty()) { + onSuccess() + return + } + useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId -> + if (usedMethodId != -1) + data.loginMethods.add(usedMethodId) + if (cancelled) { + onSuccess() + return@useLoginMethod + } + nextLoginMethod(onSuccess) + } + } + + private fun useLoginMethod(loginMethodId: Int, onSuccess: (usedMethodId: Int) -> Unit) { + // this should never be true + if (data.loginMethods.contains(loginMethodId)) { + onSuccess(-1) + return + } + Utils.d(TAG, "Using login method $loginMethodId") + when (loginMethodId) { + LOGIN_METHOD_LIBRUS_PORTAL -> { + data.startProgress(R.string.edziennik_progress_login_librus_portal) + LoginLibrusPortal(data) { onSuccess(loginMethodId) } + } + LOGIN_METHOD_LIBRUS_API -> { + data.startProgress(R.string.edziennik_progress_login_librus_api) + LoginLibrusApi(data) { onSuccess(loginMethodId) } + } + LOGIN_METHOD_LIBRUS_SYNERGIA -> { + data.startProgress(R.string.edziennik_progress_login_librus_synergia) + LoginLibrusSynergia(data) { onSuccess(loginMethodId) } + } + LOGIN_METHOD_LIBRUS_MESSAGES -> { + data.startProgress(R.string.edziennik_progress_login_librus_messages) + LoginLibrusMessages(data) { onSuccess(loginMethodId) } + } + } + } +} \ 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 index c6c94b80..da637044 100644 --- 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 @@ -49,14 +49,18 @@ class LibrusTest(val app: App) { fun go() { - Librus(app, profile, loginStore, object : EdziennikCallback { + /*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)) + }).sync(listOf(FEATURE_GRADES, FEATURE_STUDENT_INFO, FEATURE_STUDENT_NUMBER))*/ - //app.startService(Intent(app, ApiService::class.java)) + app.startService(Intent(app, ApiService::class.java)) + + if (false) { + + } /*val data = DataLibrus(app, profile, loginStore).apply { callback = object : ProgressCallback { 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 d094901e..d7b21a90 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 @@ -14,6 +14,7 @@ class ApiError(val tag: String, val errorCode: Int) { private var apiResponse: String? = null private var request: Request? = null private var response: Response? = null + var isCritical = true fun withThrowable(throwable: Throwable?): ApiError { this.throwable = throwable @@ -36,4 +37,9 @@ class ApiError(val tag: String, val errorCode: Int) { this.request = response?.request() return this } + + fun setCritical(isCritical: Boolean): ApiError { + this.isCritical = isCritical + return this + } } \ 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 467c4ff9..cf0424e2 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 @@ -38,10 +38,26 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) * A method which may be overridden in child Data* classes. * * Calling it should populate [loginMethods] with all - * already available login methods (e.g. non-expired OAuth token). + * already available login methods (e.g. a non-expired OAuth token). */ open fun satisfyLoginMethods() {} + /** + * A list of Login method IDs that are still pending + * to run. + */ + var targetLoginMethodIds = mutableListOf() + /** + * A list of endpoint IDs that are still pending + * to run. + */ + var targetEndpointIds = mutableListOf() + + /** + * A map of endpoint IDs to JSON objects, specifying their arguments bundle. + */ + var endpointArgs = mutableMapOf() + val teacherList = LongSparseArray() val subjectList = LongSparseArray() val teamList = mutableListOf() @@ -106,6 +122,9 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) if (profile == null) return + db.profileDao().add(profile) + db.loginStoreDao().add(loginStore) + if (teacherList.isNotEmpty()) { val tempList: ArrayList = ArrayList() teacherList.forEach { _, teacher -> diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/fragments/HomeFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/fragments/HomeFragment.java index b4689a40..c2f660f0 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/fragments/HomeFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/fragments/HomeFragment.java @@ -35,6 +35,8 @@ import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsSize; import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial; +import org.greenrobot.eventbus.EventBus; + import java.util.ArrayList; import java.util.List; @@ -44,6 +46,8 @@ import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.api.AppError; import pl.szczodrzynski.edziennik.api.interfaces.SyncCallback; +import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncProfileRequest; +import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncViewRequest; import pl.szczodrzynski.edziennik.api.v2.librus.LibrusOld; import pl.szczodrzynski.edziennik.api.v2.librus.LibrusTest; import pl.szczodrzynski.edziennik.databinding.CardLuckyNumberBinding; @@ -67,6 +71,8 @@ import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem; import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem; import static pl.szczodrzynski.edziennik.App.UPDATES_ON_PLAY_STORE; +import static pl.szczodrzynski.edziennik.MainActivity.DRAWER_ITEM_GRADES; +import static pl.szczodrzynski.edziennik.api.v2.FeaturesKt.FEATURE_STUDENT_INFO; import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER1_FINAL; import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER1_PROPOSED; import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER2_FINAL; @@ -128,6 +134,23 @@ public class HomeFragment extends Fragment { test.go(); })); + b.test2.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); + b.test2.setOnClickListener((v -> { + List list = new ArrayList<>(); + list.add(FEATURE_STUDENT_INFO); + EventBus.getDefault().post(new SyncProfileRequest(16, list)); + })); + + b.test3.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); + b.test3.setOnClickListener((v -> { + EventBus.getDefault().post(new SyncProfileRequest(16, null)); + })); + + b.test4.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE); + b.test4.setOnClickListener((v -> { + EventBus.getDefault().post(new SyncViewRequest(16, DRAWER_ITEM_GRADES)); + })); + //((TextView)v.findViewById(R.id.nextSync)).setText(getString(R.string.next_sync_format,Time.fromMillis(app.appJobs.syncJobTime).getStringHMS())); @@ -559,7 +582,7 @@ public class HomeFragment extends Fragment { Button cardGradesButton = root.findViewById(R.id.cardGradesButton); buttonAddDrawable(c, cardGradesButton, CommunityMaterial.Icon.cmd_arrow_right); cardGradesButton.setOnClickListener((v1 -> new Handler().postDelayed(() -> a.runOnUiThread(() -> { - activity.loadTarget(MainActivity.DRAWER_ITEM_GRADES, null); + activity.loadTarget(DRAWER_ITEM_GRADES, null); }), 100))); //new Handler().postDelayed(() -> a.runOnUiThread(() -> updateCardGrades(c, a, root)), newRefreshInterval); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt b/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt new file mode 100644 index 00000000..540ea73d --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-10-1. + */ + +package pl.szczodrzynski.edziennik.receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import org.greenrobot.eventbus.EventBus +import pl.szczodrzynski.edziennik.api.v2.events.requests.ServiceCloseRequest +import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest +import pl.szczodrzynski.edziennik.api.v2.events.requests.TaskCancelRequest + +class SzkolnyReceiver : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + when (intent?.extras?.getString("task", null)) { + "ServiceCloseRequest" -> EventBus.getDefault().post(ServiceCloseRequest()) + "TaskCancelRequest" -> EventBus.getDefault().post(TaskCancelRequest(intent.extras?.getInt("taskId", -1) ?: return)) + "SyncRequest" -> EventBus.getDefault().post(SyncRequest()) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 768c0861..964ab259 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -55,7 +55,34 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" - android:text="Test Librus" + android:text="Start Service" + android:visibility="gone"/> + + + + + + diff --git a/app/src/main/res/values/plurals.xml b/app/src/main/res/values/plurals.xml index b933e932..8e7275b2 100644 --- a/app/src/main/res/values/plurals.xml +++ b/app/src/main/res/values/plurals.xml @@ -67,4 +67,18 @@ %1$s - %2$d nieprzeczytane %1$s - %2$d nieprzeczytanych + + + %d błąd krytyczny + %d błędy krytyczne + %d błędów krytycznych + %d błędów krytycznych + + + + %d błąd + %d błędy + %d błędów + %d błędów + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2559d0d9..f8cf2a36 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -912,4 +912,13 @@ Logowanie do API Logowanie do Librus Synergia Logowanie do wiadomości Librus + Usługa synchronizacji + Dzięki niej, aplikacja Szkolny.eu może synchronizować dane z e-dziennikiem. Możesz ją zamknąć, ponieważ w tej chwili nic nie robi. + Zamknij + Anuluj + Trwa synchronizacja profilu %s... + Synchronizacja przerwana + Zgłaszanie błędów... + Zgłaszanie błędów + Pobieram informacje o uczniu...