[ApiService] Refactor the service, requesting, cancelling. Make compatible with other API tasks.

This commit is contained in:
Kuba Szczodrzyński 2019-11-03 21:26:48 +01:00
parent d789d08f31
commit 22726f8566
54 changed files with 509 additions and 505 deletions

View File

@ -6,7 +6,6 @@ import android.content.*
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.os.* import android.os.*
import android.util.Log
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
@ -34,8 +33,7 @@ import pl.droidsonroids.gif.GifDrawable
import pl.szczodrzynski.edziennik.App.APP_URL import pl.szczodrzynski.edziennik.App.APP_URL
import pl.szczodrzynski.edziennik.api.v2.ApiService import pl.szczodrzynski.edziennik.api.v2.ApiService
import pl.szczodrzynski.edziennik.api.v2.events.* import pl.szczodrzynski.edziennik.api.v2.events.*
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncProfileRequest import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface.* import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface.*
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.* import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.*
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
@ -64,6 +62,7 @@ import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment
import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch
import pl.szczodrzynski.edziennik.utils.Themes import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.Utils.dpToPx import pl.szczodrzynski.edziennik.utils.Utils.dpToPx
import pl.szczodrzynski.edziennik.utils.models.NavTarget import pl.szczodrzynski.edziennik.utils.models.NavTarget
import pl.szczodrzynski.navlib.* import pl.szczodrzynski.navlib.*
@ -77,7 +76,7 @@ import pl.szczodrzynski.navlib.drawer.items.withAppTitle
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
import kotlin.math.roundToInt
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
companion object { companion object {
@ -499,7 +498,7 @@ class MainActivity : AppCompatActivity() {
profileListEmptyListener() profileListEmptyListener()
} }
DRAWER_PROFILE_SYNC_ALL -> { DRAWER_PROFILE_SYNC_ALL -> {
ApiService.startAndRequest(this, SyncRequest()) EdziennikTask.sync().enqueue(this)
} }
else -> { else -> {
loadTarget(id) loadTarget(id)
@ -525,14 +524,14 @@ class MainActivity : AppCompatActivity() {
else -> 0 else -> 0
} }
EventBus.getDefault().postSticky( EventBus.getDefault().postSticky(
SyncProfileRequest( EdziennikTask.syncProfile(
App.profileId, App.profileId,
listOf(navTargetId to fragmentParam) listOf(navTargetId to fragmentParam)
) )
) )
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncStartedEvent(event: SyncStartedEvent) { fun onSyncStartedEvent(event: ApiTaskStartedEvent) {
swipeRefreshLayout.isRefreshing = true swipeRefreshLayout.isRefreshing = true
if (event.profileId == App.profileId) { if (event.profileId == App.profileId) {
navView.toolbar.apply { navView.toolbar.apply {
@ -543,17 +542,21 @@ class MainActivity : AppCompatActivity() {
} }
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncProgressEvent(event: SyncProgressEvent) { fun onSyncProgressEvent(event: ApiTaskProgressEvent) {
if (event.profileId == App.profileId) { if (event.profileId == App.profileId) {
navView.toolbar.apply { navView.toolbar.apply {
subtitleFormat = null subtitleFormat = null
subtitleFormatWithUnread = null subtitleFormatWithUnread = null
subtitle = getString(R.string.toolbar_subtitle_syncing_format, event.progress, event.progressRes?.let { getString(it) } ?: "") subtitle = if (event.progress < 0f)
event.progressText ?: ""
else
getString(R.string.toolbar_subtitle_syncing_format, event.progress.roundToInt(), event.progressText ?: "")
} }
} }
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncProfileFinishedEvent(event: SyncProfileFinishedEvent) { fun onSyncProfileFinishedEvent(event: ApiTaskFinishedEvent) {
if (event.profileId == App.profileId) { if (event.profileId == App.profileId) {
navView.toolbar.apply { navView.toolbar.apply {
subtitleFormat = R.string.toolbar_subtitle subtitleFormat = R.string.toolbar_subtitle
@ -563,11 +566,11 @@ class MainActivity : AppCompatActivity() {
} }
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncFinishedEvent(event: SyncFinishedEvent) { fun onSyncFinishedEvent(event: ApiTaskAllFinishedEvent) {
swipeRefreshLayout.isRefreshing = false swipeRefreshLayout.isRefreshing = false
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncErrorEvent(event: SyncErrorEvent) { fun onSyncErrorEvent(event: ApiTaskErrorEvent) {
} }
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true) @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
@ -657,11 +660,11 @@ class MainActivity : AppCompatActivity() {
} }
private fun handleIntent(extras: Bundle?) { private fun handleIntent(extras: Bundle?) {
Log.d(TAG, "handleIntent() {") d(TAG, "handleIntent() {")
extras?.keySet()?.forEach { key -> extras?.keySet()?.forEach { key ->
Log.d(TAG, " \"$key\": "+extras.get(key)) d(TAG, " \"$key\": "+extras.get(key))
} }
Log.d(TAG, "}") d(TAG, "}")
if (extras?.containsKey("reloadProfileId") == true) { if (extras?.containsKey("reloadProfileId") == true) {
val reloadProfileId = extras.getInt("reloadProfileId", -1) val reloadProfileId = extras.getInt("reloadProfileId", -1)
@ -785,7 +788,7 @@ class MainActivity : AppCompatActivity() {
fun loadProfile(id: Int) = loadProfile(id, navTargetId) fun loadProfile(id: Int) = loadProfile(id, navTargetId)
fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments) fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments)
fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) { fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) {
Log.d("NavDebug", "loadProfile(id = $id, drawerSelection = $drawerSelection)") d("NavDebug", "loadProfile(id = $id, drawerSelection = $drawerSelection)")
if (app.profile != null && App.profileId == id) { if (app.profile != null && App.profileId == id) {
drawer.currentProfile = app.profile.id drawer.currentProfile = app.profile.id
loadTarget(drawerSelection, arguments) loadTarget(drawerSelection, arguments)
@ -825,7 +828,7 @@ class MainActivity : AppCompatActivity() {
} }
} }
private fun loadTarget(target: NavTarget, arguments: Bundle? = null) { private fun loadTarget(target: NavTarget, arguments: Bundle? = null) {
Log.d("NavDebug", "loadItem(id = ${target.id})") d("NavDebug", "loadItem(id = ${target.id})")
bottomSheet.close() bottomSheet.close()
bottomSheet.removeAllContextual() bottomSheet.removeAllContextual()
@ -838,7 +841,7 @@ class MainActivity : AppCompatActivity() {
navView.bottomBar.fabExtended = false navView.bottomBar.fabExtended = false
navView.bottomBar.setFabOnClickListener(null) navView.bottomBar.setFabOnClickListener(null)
Log.d("NavDebug", "Navigating from ${navTarget.fragmentClass?.java?.simpleName} to ${target.fragmentClass?.java?.simpleName}") d("NavDebug", "Navigating from ${navTarget.fragmentClass?.java?.simpleName} to ${target.fragmentClass?.java?.simpleName}")
val fragment = target.fragmentClass?.java?.newInstance() ?: return val fragment = target.fragmentClass?.java?.newInstance() ?: return
fragment.arguments = arguments fragment.arguments = arguments
@ -897,9 +900,9 @@ class MainActivity : AppCompatActivity() {
} }
} }
Log.d("NavDebug", "Current fragment ${navTarget.fragmentClass?.java?.simpleName}, pop to home ${navTarget.popToHome}, back stack:") d("NavDebug", "Current fragment ${navTarget.fragmentClass?.java?.simpleName}, pop to home ${navTarget.popToHome}, back stack:")
navBackStack.forEachIndexed { index, target2 -> navBackStack.forEachIndexed { index, target2 ->
Log.d("NavDebug", " - $index: ${target2.fragmentClass?.java?.simpleName}") d("NavDebug", " - $index: ${target2.fragmentClass?.java?.simpleName}")
} }
transaction.replace(R.id.fragment, fragment) transaction.replace(R.id.fragment, fragment)
@ -990,7 +993,7 @@ class MainActivity : AppCompatActivity() {
} }
fun setDrawerItems() { fun setDrawerItems() {
Log.d("NavDebug", "setDrawerItems() app.profile = ${app.profile ?: "null"}") d("NavDebug", "setDrawerItems() app.profile = ${app.profile ?: "null"}")
val drawerItems = arrayListOf<IDrawerItem<*>>() val drawerItems = arrayListOf<IDrawerItem<*>>()
val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>() val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>()

View File

@ -28,8 +28,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import pl.szczodrzynski.edziennik.api.v2.ApiService; import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask;
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull; import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange; import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull; import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull;
@ -67,7 +66,7 @@ public class WidgetTimetable extends AppWidgetProvider {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (ACTION_SYNC_DATA.equals(intent.getAction())) { if (ACTION_SYNC_DATA.equals(intent.getAction())) {
ApiService.Companion.startAndRequest(context, new SyncRequest()); EdziennikTask.Companion.sync().enqueue(context);
} }
super.onReceive(context, intent); super.onReceive(context, intent);
} }

View File

@ -8,29 +8,22 @@ import android.app.Service
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.IBinder import android.os.IBinder
import android.util.Log
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.events.* import pl.szczodrzynski.edziennik.api.v2.events.*
import pl.szczodrzynski.edziennik.api.v2.events.requests.* import pl.szczodrzynski.edziennik.api.v2.events.requests.ServiceCloseRequest
import pl.szczodrzynski.edziennik.api.v2.events.requests.TaskCancelRequest
import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
import pl.szczodrzynski.edziennik.api.v2.events.task.ErrorReportTask import pl.szczodrzynski.edziennik.api.v2.events.task.ErrorReportTask
import pl.szczodrzynski.edziennik.api.v2.events.task.IApiTask
import pl.szczodrzynski.edziennik.api.v2.events.task.NotifyTask import pl.szczodrzynski.edziennik.api.v2.events.task.NotifyTask
import pl.szczodrzynski.edziennik.api.v2.idziennik.Idziennik
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback 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.mobidziennik.Mobidziennik
import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.api.v2.models.ApiTask import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.api.v2.template.Template
import pl.szczodrzynski.edziennik.api.v2.vulcan.Vulcan
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import kotlin.math.roundToInt
class ApiService : Service() { class ApiService : Service() {
companion object { companion object {
@ -47,23 +40,23 @@ class ApiService : Service() {
private val app by lazy { applicationContext as App } private val app by lazy { applicationContext as App }
private val taskQueue = mutableListOf<ApiTask>() private val finishingTaskQueue = mutableListOf(
NotifyTask(),
ErrorReportTask()
)
private val taskQueue = mutableListOf<IApiTask>()
private val errorList = mutableListOf<ApiError>() private val errorList = mutableListOf<ApiError>()
private var queueHasErrorReportTask = false
private var queueHasNotifyTask = false
private var serviceClosed = false private var serviceClosed = false
private var taskCancelled = false private var taskCancelled = false
private var taskRunningObject: ApiTask? = null // for debug purposes private var taskIsRunning = false
private var taskRunning = false private var taskRunning: IApiTask? = null // for debug purposes
private var taskRunningId = -1 private var taskRunningId = -1
private var taskMaximumId = 0 private var taskMaximumId = 0
private var edziennikInterface: EdziennikInterface? = null
private var taskProfileId = -1 private var taskProfileId = -1
private var taskProfileName: String? = null private var taskProgress = -1f
private var taskProgress = 0 private var taskProgressText: String? = null
private var taskProgressRes: Int? = null
private val notification by lazy { EdziennikNotification(this) } private val notification by lazy { EdziennikNotification(this) }
@ -75,74 +68,56 @@ class ApiService : Service() {
|______\__,_/___|_|\___|_| |_|_| |_|_|_|\_\ \_____\__,_|_|_|_.__/ \__,_|\___|_|\*/ |______\__,_/___|_|\___|_| |_|_| |_|_|_|\_\ \_____\__,_|_|_|_.__/ \__,_|\___|_|\*/
private val taskCallback = object : EdziennikCallback { private val taskCallback = object : EdziennikCallback {
override fun onCompleted() { override fun onCompleted() {
edziennikInterface = null d(TAG, "Task $taskRunningId (profile $taskProfileId) - $taskProgressText - finished")
if (taskRunningObject is SyncProfileRequest) { //if (!taskCancelled) {
// post an event if this task is a sync, not e.g. first login or message getting EventBus.getDefault().post(ApiTaskFinishedEvent(taskProfileId))
if (!taskCancelled) { //}
EventBus.getDefault().post(SyncProfileFinishedEvent(taskProfileId)) taskIsRunning = false
}
// add a notifying task to create data notifications of this profile
addNotifyTask()
}
notification.setIdle().post()
taskRunningObject = null
taskRunning = false
taskRunningId = -1 taskRunningId = -1
sync() taskRunning = null
taskProfileId = -1
taskProgress = -1f
taskProgressText = null
notification.setIdle().post()
runTask()
} }
override fun onError(apiError: ApiError) { override fun onError(apiError: ApiError) {
if (!queueHasErrorReportTask) { d(TAG, "Task $taskRunningId threw an error - $apiError")
queueHasErrorReportTask = true
taskQueue += ErrorReportTask().apply {
taskId = ++taskMaximumId
}
}
apiError.profileId = taskProfileId apiError.profileId = taskProfileId
EventBus.getDefault().post(SyncErrorEvent(apiError)) EventBus.getDefault().post(ApiTaskErrorEvent(apiError))
errorList.add(apiError) errorList.add(apiError)
apiError.throwable?.printStackTrace() apiError.throwable?.printStackTrace()
if (apiError.isCritical) { if (apiError.isCritical) {
// if this error ends the sync, post an error notification
// if this is a sync task, create a notifying task
if (taskRunningObject is SyncProfileRequest) {
// add a notifying task to create data notifications of this profile
addNotifyTask()
}
notification.setCriticalError().post() notification.setCriticalError().post()
taskRunningObject = null taskRunning = null
taskRunning = false taskIsRunning = false
taskRunningId = -1 taskRunningId = -1
sync() runTask()
} }
else { else {
notification.addError().post() notification.addError().post()
} }
} }
override fun onProgress(step: Int) { override fun onProgress(step: Float) {
if (step <= 0)
return
if (taskProgress < 0)
taskProgress = 0f
taskProgress += step taskProgress += step
taskProgress = min(100, taskProgress) taskProgress = min(100f, taskProgress)
EventBus.getDefault().post(SyncProgressEvent(taskProfileId, taskProfileName, taskProgress, taskProgressRes)) d(TAG, "Task $taskRunningId progress: ${taskProgress.roundToInt()}%")
EventBus.getDefault().post(ApiTaskProgressEvent(taskProfileId, taskProgress, taskProgressText))
notification.setProgress(taskProgress).post() notification.setProgress(taskProgress).post()
} }
override fun onStartProgress(stringRes: Int) { override fun onStartProgress(stringRes: Int) {
taskProgressRes = stringRes taskProgressText = getString(stringRes)
EventBus.getDefault().post(SyncProgressEvent(taskProfileId, taskProfileName, taskProgress, taskProgressRes)) d(TAG, "Task $taskRunningId progress: $taskProgressText")
notification.setProgressRes(taskProgressRes!!).post() EventBus.getDefault().post(ApiTaskProgressEvent(taskProfileId, taskProgress, taskProgressText))
} notification.setProgressText(taskProgressText).post()
fun addNotifyTask() {
if (!queueHasNotifyTask) {
queueHasNotifyTask = true
taskQueue.add(
if (queueHasErrorReportTask) max(taskQueue.size-1, 0) else taskQueue.size,
NotifyTask().apply {
taskId = ++taskMaximumId
}
)
}
} }
} }
@ -152,98 +127,42 @@ class ApiService : Service() {
| |/ _` / __| |/ / / _ \ \/ / _ \/ __| | | | __| |/ _ \| '_ \ | |/ _` / __| |/ / / _ \ \/ / _ \/ __| | | | __| |/ _ \| '_ \
| | (_| \__ \ < | __/> < __/ (__| |_| | |_| | (_) | | | | | | (_| \__ \ < | __/> < __/ (__| |_| | |_| | (_) | | | |
|_|\__,_|___/_|\_\ \___/_/\_\___|\___|\__,_|\__|_|\___/|_| |*/ |_|\__,_|___/_|\_\ \___/_/\_\___|\___|\__,_|\__|_|\___/|_| |*/
private fun sync() { private fun runTask() {
if (taskRunning) if (taskIsRunning)
return return
if (taskQueue.size <= 0 || serviceClosed) { if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && finishingTaskQueue.isEmpty())) {
serviceClosed = false serviceClosed = false
allCompleted() allCompleted()
return return
} }
val task = taskQueue.removeAt(0) val task = if (taskQueue.isEmpty()) finishingTaskQueue.removeAt(0) else taskQueue.removeAt(0)
taskCancelled = false task.taskId = ++taskMaximumId
taskRunning = true task.prepare(app)
taskIsRunning = true
taskRunningId = task.taskId taskRunningId = task.taskId
taskRunningObject = task taskRunning = task
taskProfileId = task.profileId
taskProgress = -1f
taskProgressText = task.taskName
if (task is ErrorReportTask) { d(TAG, "Executing task $taskRunningId ($taskProgressText) - $task")
queueHasErrorReportTask = false
task.run(notification, errorList)
taskRunningObject = null
taskRunning = false
taskRunningId = -1
sync()
return
}
if (task is NotifyTask) {
queueHasNotifyTask = false
task.run(app)
taskRunningObject = null
taskRunning = false
taskRunningId = -1
sync()
return
}
val profile: Profile?
val loginStore: LoginStore
if (task is FirstLoginRequest) {
// get the requested profile and login store
profile = null
loginStore = task.loginStore
// save the profile ID and name as the current task's
taskProfileId = -1
taskProfileName = getString(R.string.edziennik_notification_api_first_login_title)
}
else {
// get the requested profile and login store
profile = app.db.profileDao().getByIdNow(task.profileId)
if (profile == null || !profile.syncEnabled) {
return
}
loginStore = app.db.loginStoreDao().getByIdNow(profile.loginStoreId)
if (loginStore == null) {
return
}
// save the profile ID and name as the current task's
taskProfileId = profile.id
taskProfileName = profile.name
}
taskProgress = 0
taskProgressRes = null
// update the notification // update the notification
notification.setCurrentTask(taskRunningId, taskProfileName).post() notification.setCurrentTask(taskRunningId, taskProgressText).post()
// post an event // post an event
EventBus.getDefault().post(SyncStartedEvent(taskProfileId, profile)) EventBus.getDefault().post(ApiTaskStartedEvent(taskProfileId, task.profile))
edziennikInterface = when (loginStore.type) {
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
LOGIN_TYPE_IDZIENNIK -> Idziennik(app, profile, loginStore, taskCallback)
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
else -> null
}
if (edziennikInterface == null) {
return
}
when (task) { when (task) {
is SyncProfileRequest -> edziennikInterface?.sync( is EdziennikTask -> task.run(app, taskCallback)
featureIds = task.viewIds?.flatMap { Features.getIdsByView(it.first, it.second) } ?: Features.getAllIds(), is NotifyTask -> task.run(app, taskCallback)
viewId = task.viewIds?.get(0)?.first) is ErrorReportTask -> task.run(app, taskCallback, notification, errorList)
is MessageGetRequest -> edziennikInterface?.getMessage(task.messageId)
is FirstLoginRequest -> edziennikInterface?.firstLogin()
is AnnouncementsReadRequest -> edziennikInterface?.markAllAnnouncementsAsRead()
} }
} }
private fun allCompleted() { private fun allCompleted() {
EventBus.getDefault().post(SyncFinishedEvent()) EventBus.getDefault().post(ApiTaskAllFinishedEvent())
stopSelf() stopSelf()
} }
@ -254,91 +173,50 @@ class ApiService : Service() {
| |___\ V / __/ | | | |_| |_) | |_| \__ \ | |___\ V / __/ | | | |_| |_) | |_| \__ \
|______\_/ \___|_| |_|\__|____/ \__,_|__*/ |______\_/ \___|_| |_|\__|____/ \__,_|__*/
@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
fun onSyncRequest(request: SyncRequest) { fun onApiTask(task: IApiTask) {
EventBus.getDefault().removeStickyEvent(request) EventBus.getDefault().removeStickyEvent(task)
Log.d(TAG, request.toString()) d(TAG, task.toString())
app.db.profileDao().idsForSyncNow.forEach { id -> if (task is EdziennikTask) {
taskQueue += SyncProfileRequest(id, null).apply { when (task.request) {
taskId = ++taskMaximumId is EdziennikTask.SyncRequest -> app.db.profileDao().idsForSyncNow.forEach {
taskQueue += EdziennikTask.syncProfile(it)
}
is EdziennikTask.SyncProfileListRequest -> task.request.profileList.forEach {
taskQueue += EdziennikTask.syncProfile(it)
}
else -> {
taskQueue += task
}
} }
} }
sync() else {
} taskQueue += task
@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() d(TAG, "EventBus received an IApiTask: $task")
} d(TAG, "Current queue:")
taskQueue.forEach {
@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) d(TAG, " - $it")
fun onSyncProfileRequest(request: SyncProfileRequest) {
EventBus.getDefault().removeStickyEvent(request)
Log.d(TAG, request.toString())
taskQueue += request.apply {
taskId = ++taskMaximumId
} }
sync() runTask()
}
@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(sticky = true, threadMode = ThreadMode.ASYNC)
fun onAnnouncementsReadRequest(request: AnnouncementsReadRequest) {
EventBus.getDefault().removeStickyEvent(request)
Log.d(TAG, request.toString())
taskQueue += request.apply {
taskId = ++taskMaximumId
}
sync()
}
@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) @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
fun onTaskCancelRequest(request: TaskCancelRequest) { fun onTaskCancelRequest(request: TaskCancelRequest) {
EventBus.getDefault().removeStickyEvent(request) EventBus.getDefault().removeStickyEvent(request)
Log.d(TAG, request.toString()) d(TAG, request.toString())
taskCancelled = true taskCancelled = true
edziennikInterface?.cancel() taskRunning?.cancel()
} }
@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
fun onServiceCloseRequest(request: ServiceCloseRequest) { fun onServiceCloseRequest(request: ServiceCloseRequest) {
EventBus.getDefault().removeStickyEvent(request) EventBus.getDefault().removeStickyEvent(request)
Log.d(TAG, request.toString()) d(TAG, request.toString())
serviceClosed = true serviceClosed = true
taskCancelled = true taskCancelled = true
edziennikInterface?.cancel() taskRunning?.cancel()
stopSelf() stopSelf()
} }

View File

@ -10,9 +10,9 @@ import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.PRIORITY_LOW
import androidx.core.app.NotificationCompat.PRIORITY_MIN import androidx.core.app.NotificationCompat.PRIORITY_MIN
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import kotlin.math.roundToInt
class EdziennikNotification(val context: Context) { class EdziennikNotification(val context: Context) {
@ -92,18 +92,18 @@ class EdziennikNotification(val context: Context) {
return this return this
} }
fun setProgress(progress: Int): EdziennikNotification { fun setProgress(progress: Float): EdziennikNotification {
notificationBuilder.setProgress(100, progress, false) notificationBuilder.setProgress(100, progress.roundToInt(), progress < 0f)
return this return this
} }
fun setProgressRes(progressRes: Int): EdziennikNotification { fun setProgressText(progressText: String?): EdziennikNotification {
notificationBuilder.setContentTitle(context.getString(progressRes)) notificationBuilder.setContentTitle(progressText)
return this return this
} }
fun setCurrentTask(taskId: Int, profileName: String?): EdziennikNotification { fun setCurrentTask(taskId: Int, progressText: String?): EdziennikNotification {
notificationBuilder.setProgress(100, 0, false) notificationBuilder.setProgress(100, 0, true)
notificationBuilder.setContentTitle(context.getString(R.string.edziennik_notification_api_sync_title_format, profileName)) notificationBuilder.setContentTitle(progressText)
notificationBuilder.apply { notificationBuilder.apply {
val str = errorCountText() val str = errorCountText()
setStyle(NotificationCompat.BigTextStyle().bigText(str)) setStyle(NotificationCompat.BigTextStyle().bigText(str))

View File

@ -77,4 +77,7 @@ fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featu
data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList() data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
data.targetEndpointIds.sort() data.targetEndpointIds.sort()
progressCount = targetLoginMethodIds.size + targetEndpointIds.size
progressStep = if (progressCount <= 0) 0f else 100f / progressCount.toFloat()
} }

View File

@ -4,4 +4,4 @@
package pl.szczodrzynski.edziennik.api.v2.events package pl.szczodrzynski.edziennik.api.v2.events
class SyncFinishedEvent class ApiTaskAllFinishedEvent

View File

@ -6,4 +6,4 @@ package pl.szczodrzynski.edziennik.api.v2.events
import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.api.v2.models.ApiError
class SyncErrorEvent(val error: ApiError) class ApiTaskErrorEvent(val error: ApiError)

View File

@ -4,4 +4,4 @@
package pl.szczodrzynski.edziennik.api.v2.events package pl.szczodrzynski.edziennik.api.v2.events
class SyncProfileFinishedEvent(val profileId: Int) class ApiTaskFinishedEvent(val profileId: Int)

View File

@ -0,0 +1,7 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
*/
package pl.szczodrzynski.edziennik.api.v2.events
class ApiTaskProgressEvent(val profileId: Int, val progress: Float, val progressText: String?)

View File

@ -6,4 +6,4 @@ package pl.szczodrzynski.edziennik.api.v2.events
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
class SyncStartedEvent(val profileId: Int, val profile: Profile? = null) class ApiTaskStartedEvent(val profileId: Int, val profile: Profile? = null)

View File

@ -1,7 +0,0 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
*/
package pl.szczodrzynski.edziennik.api.v2.events
class SyncProgressEvent(val profileId: Int, val profileName: String?, val progress: Int, val progressRes: Int?)

View File

@ -1,13 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-10-26
*/
package pl.szczodrzynski.edziennik.api.v2.events.requests
import pl.szczodrzynski.edziennik.api.v2.models.ApiTask
data class AnnouncementsReadRequest(override val profileId: Int) : ApiTask(profileId) {
override fun toString(): String {
return "AnnouncementsReadRequest(profileId=$profileId)"
}
}

View File

@ -1,10 +0,0 @@
package pl.szczodrzynski.edziennik.api.v2.events.requests
import pl.szczodrzynski.edziennik.api.v2.models.ApiTask
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
data class FirstLoginRequest(val loginStore: LoginStore) : ApiTask(-1) {
override fun toString(): String {
return "FirstLoginRequest(loginStore=$loginStore)"
}
}

View File

@ -1,13 +0,0 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
*/
package pl.szczodrzynski.edziennik.api.v2.events.requests
import pl.szczodrzynski.edziennik.api.v2.models.ApiTask
data class MessageGetRequest(override val profileId: Int, val messageId: Int) : ApiTask(profileId) {
override fun toString(): String {
return "MessageGetRequest(profileId=$profileId, messageId=$messageId)"
}
}

View File

@ -1,7 +0,0 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-10-23.
*/
package pl.szczodrzynski.edziennik.api.v2.events.requests
class SyncProfileListRequest(val profileList: List<Int>)

View File

@ -1,13 +0,0 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
*/
package pl.szczodrzynski.edziennik.api.v2.events.requests
import pl.szczodrzynski.edziennik.api.v2.models.ApiTask
data class SyncProfileRequest(override val profileId: Int, val viewIds: List<Pair<Int, Int>>? = null) : ApiTask(profileId) {
override fun toString(): String {
return "SyncProfileRequest(profileId=$profileId, viewIds=$viewIds)"
}
}

View File

@ -1,7 +0,0 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
*/
package pl.szczodrzynski.edziennik.api.v2.events.requests
class SyncRequest

View File

@ -0,0 +1,90 @@
package pl.szczodrzynski.edziennik.api.v2.events.task
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.*
import pl.szczodrzynski.edziennik.api.v2.idziennik.Idziennik
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.mobidziennik.Mobidziennik
import pl.szczodrzynski.edziennik.api.v2.template.Template
import pl.szczodrzynski.edziennik.api.v2.vulcan.Vulcan
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
companion object {
private const val TAG = "EdziennikTask"
fun firstLogin(loginStore: LoginStore) = EdziennikTask(-1, FirstLoginRequest(loginStore))
fun sync() = EdziennikTask(-1, SyncRequest())
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds))
fun syncProfileList(profileList: List<Int>) = EdziennikTask(-1, SyncProfileListRequest(profileList))
fun messageGet(profileId: Int, messageId: Int) = EdziennikTask(profileId, MessageGetRequest(messageId))
fun announcementsRead(profileId: Int) = EdziennikTask(profileId, AnnouncementsReadRequest())
}
private lateinit var loginStore: LoginStore
override fun prepare(app: App) {
if (request is FirstLoginRequest) {
// get the requested profile and login store
this.profile = null
loginStore = request.loginStore
// save the profile ID and name as the current task's
taskName = app.getString(R.string.edziennik_notification_api_first_login_title)
}
else {
// get the requested profile and login store
val profile = app.db.profileDao().getByIdNow(profileId)
this.profile = profile
if (profile == null || !profile.syncEnabled) {
return
}
val loginStore = app.db.loginStoreDao().getByIdNow(profile.loginStoreId) ?: return
this.loginStore = loginStore
// save the profile ID and name as the current task's
taskName = app.getString(R.string.edziennik_notification_api_sync_title_format, profile.name)
}
}
private var edziennikInterface: EdziennikInterface? = null
fun run(app: App, taskCallback: EdziennikCallback) {
edziennikInterface = when (loginStore.type) {
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
LOGIN_TYPE_IDZIENNIK -> Idziennik(app, profile, loginStore, taskCallback)
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
else -> null
}
if (edziennikInterface == null) {
return
}
when (request) {
is SyncProfileRequest -> edziennikInterface?.sync(
featureIds = request.viewIds?.flatMap { Features.getIdsByView(it.first, it.second) } ?: Features.getAllIds(),
viewId = request.viewIds?.get(0)?.first)
is MessageGetRequest -> edziennikInterface?.getMessage(request.messageId)
is FirstLoginRequest -> edziennikInterface?.firstLogin()
is AnnouncementsReadRequest -> edziennikInterface?.markAllAnnouncementsAsRead()
}
}
override fun cancel() {
edziennikInterface?.cancel()
}
override fun toString(): String {
return "EdziennikTask(profileId=$profileId, request=$request, edziennikInterface=$edziennikInterface)"
}
data class FirstLoginRequest(val loginStore: LoginStore)
class SyncRequest
data class SyncProfileRequest(val viewIds: List<Pair<Int, Int>>? = null)
data class SyncProfileListRequest(val profileList: List<Int>)
data class MessageGetRequest(val messageId: Int)
class AnnouncementsReadRequest
}

View File

@ -4,23 +4,31 @@
package pl.szczodrzynski.edziennik.api.v2.events.task package pl.szczodrzynski.edziennik.api.v2.events.task
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.ApiService import pl.szczodrzynski.edziennik.api.v2.ApiService
import pl.szczodrzynski.edziennik.api.v2.EdziennikNotification import pl.szczodrzynski.edziennik.api.v2.EdziennikNotification
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.api.v2.models.ApiTask
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
class ErrorReportTask : ApiTask(-1) { class ErrorReportTask : IApiTask(-1) {
fun run(notification: EdziennikNotification, errorList: MutableList<ApiError>) { override fun prepare(app: App) {
notification taskName = app.getString(R.string.edziennik_notification_api_error_report_title)
.setCurrentTask(taskId, null) }
.setProgressRes(R.string.edziennik_notification_api_error_report_title)
.post() override fun cancel() {
}
fun run(app: App, taskCallback: EdziennikCallback, notification: EdziennikNotification, errorList: MutableList<ApiError>) {
errorList.forEach { error -> errorList.forEach { error ->
Utils.d(ApiService.TAG, "Error ${error.tag} profile ${error.profileId}: code ${error.errorCode}") Utils.d(ApiService.TAG, "Error ${error.tag} profile ${error.profileId}: code ${error.errorCode}")
} }
errorList.clear() errorList.clear()
notification.setIdle().post()
taskCallback.onCompleted()
} }
} }

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
*/
package pl.szczodrzynski.edziennik.api.v2.events.task
import android.content.Context
import android.content.Intent
import org.greenrobot.eventbus.EventBus
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.api.v2.ApiService
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
abstract class IApiTask(open val profileId: Int) {
var taskId: Int = 0
var profile: Profile? = null
var taskName: String? = null
/**
* A method called before running the task.
* It is synchronous and its main task is
* to prepare the correct task name.
*/
abstract fun prepare(app: App)
abstract fun cancel()
fun enqueue(context: Context) {
context.startService(Intent(context, ApiService::class.java))
EventBus.getDefault().postSticky(this)
}
override fun toString(): String {
return "IApiTask(profileId=$profileId, taskId=$taskId, profile=$profile, taskName=$taskName)"
}
}

View File

@ -8,14 +8,22 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.Notifier.ID_NOTIFICATIONS import pl.szczodrzynski.edziennik.Notifier.ID_NOTIFICATIONS
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.models.ApiTask import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.utils.models.Notification import pl.szczodrzynski.edziennik.utils.models.Notification
import kotlin.math.min import kotlin.math.min
class NotifyTask : ApiTask(-1) { class NotifyTask : IApiTask(-1) {
fun run(app: App) { override fun prepare(app: App) {
taskName = app.getString(R.string.edziennik_notification_api_notify_title)
}
override fun cancel() {
}
fun run(app: App, taskCallback: EdziennikCallback) {
val list = app.db.notificationDao().getNotPostedNow() val list = app.db.notificationDao().getNotPostedNow()
val notificationList = list.subList(0, min(8, list.size)) val notificationList = list.subList(0, min(15, list.size))
var unreadCount = list.size var unreadCount = list.size
@ -75,5 +83,7 @@ class NotifyTask : ApiTask(-1) {
} }
app.db.notificationDao().setAllPosted() app.db.notificationDao().setAllPosted()
taskCallback.onCompleted()
} }
} }

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.idziennik package pl.szczodrzynski.edziennik.api.v2.idziennik
import android.util.Log
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
import pl.szczodrzynski.edziennik.api.v2.idziennik.data.IdziennikData import pl.szczodrzynski.edziennik.api.v2.idziennik.data.IdziennikData
@ -17,7 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.api.v2.prepare import pl.szczodrzynski.edziennik.api.v2.prepare
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore 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
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils.d
class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
companion object { companion object {
@ -51,8 +50,8 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|__*/ |__*/
override fun sync(featureIds: List<Int>, viewId: Int?) { override fun sync(featureIds: List<Int>, viewId: Int?) {
data.prepare(idziennikLoginMethods, IdziennikFeatures, featureIds, viewId) data.prepare(idziennikLoginMethods, IdziennikFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}") d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}") d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
IdziennikLogin(data) { IdziennikLogin(data) {
IdziennikData(data) { IdziennikData(data) {
completed() completed()
@ -75,7 +74,7 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
} }
override fun cancel() { override fun cancel() {
Utils.d(TAG, "Cancelled") d(TAG, "Cancelled")
data.cancel() data.cancel()
} }
@ -85,7 +84,7 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
callback.onCompleted() callback.onCompleted()
} }
override fun onProgress(step: Int) { override fun onProgress(step: Float) {
callback.onProgress(step) callback.onProgress(step)
} }

View File

@ -17,8 +17,6 @@ class IdziennikData(val data: DataIdziennik, val onSuccess: () -> Unit) {
private const val TAG = "IdziennikData" private const val TAG = "IdziennikData"
} }
private var cancelled = false
init { init {
nextEndpoint(onSuccess) nextEndpoint(onSuccess)
} }
@ -28,11 +26,12 @@ class IdziennikData(val data: DataIdziennik, val onSuccess: () -> Unit) {
onSuccess() onSuccess()
return return
} }
if (cancelled) { if (data.cancelled) {
onSuccess() onSuccess()
return return
} }
useEndpoint(data.targetEndpointIds.removeAt(0)) { useEndpoint(data.targetEndpointIds.removeAt(0)) {
data.progress(data.progressStep)
nextEndpoint(onSuccess) nextEndpoint(onSuccess)
} }
} }

View File

@ -31,6 +31,7 @@ class IdziennikLogin(val data: DataIdziennik, val onSuccess: () -> Unit) {
return return
} }
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId -> useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
data.progress(data.progressStep)
if (usedMethodId != -1) if (usedMethodId != -1)
data.loginMethods.add(usedMethodId) data.loginMethods.add(usedMethodId)
nextLoginMethod(onSuccess) nextLoginMethod(onSuccess)

View File

@ -13,6 +13,6 @@ import pl.szczodrzynski.edziennik.api.v2.models.LoginMethod
*/ */
interface EndpointCallback { interface EndpointCallback {
fun onError(apiError: ApiError) fun onError(apiError: ApiError)
fun onProgress(step: Int) fun onProgress(step: Float)
fun onStartProgress(stringRes: Int) fun onStartProgress(stringRes: Int)
} }

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.librus package pl.szczodrzynski.edziennik.api.v2.librus
import android.util.Log
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
@ -20,7 +19,7 @@ import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.api.v2.prepare import pl.szczodrzynski.edziennik.api.v2.prepare
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore 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
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils.d
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
companion object { companion object {
@ -54,8 +53,8 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|__*/ |__*/
override fun sync(featureIds: List<Int>, viewId: Int?) { override fun sync(featureIds: List<Int>, viewId: Int?) {
data.prepare(librusLoginMethods, LibrusFeatures, featureIds, viewId) data.prepare(librusLoginMethods, LibrusFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}") d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}") d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
LibrusLogin(data) { LibrusLogin(data) {
LibrusData(data) { LibrusData(data) {
completed() completed()
@ -84,7 +83,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
} }
override fun cancel() { override fun cancel() {
Utils.d(TAG, "Cancelled") d(TAG, "Cancelled")
data.cancel() data.cancel()
} }
@ -94,7 +93,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
callback.onCompleted() callback.onCompleted()
} }
override fun onProgress(step: Int) { override fun onProgress(step: Float) {
callback.onProgress(step) callback.onProgress(step)
} }

View File

@ -32,6 +32,7 @@ class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) {
return return
} }
useEndpoint(data.targetEndpointIds.removeAt(0)) { useEndpoint(data.targetEndpointIds.removeAt(0)) {
data.progress(data.progressStep)
nextEndpoint(onSuccess) nextEndpoint(onSuccess)
} }
} }

View File

@ -4,16 +4,17 @@
package pl.szczodrzynski.edziennik.api.v2.librus.data.api package pl.szczodrzynski.edziennik.api.v2.librus.data.api
import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.api.v2.librus.DataLibrus import pl.szczodrzynski.edziennik.api.v2.librus.DataLibrus
import pl.szczodrzynski.edziennik.api.v2.librus.ENDPOINT_LIBRUS_API_LUCKY_NUMBER import pl.szczodrzynski.edziennik.api.v2.librus.ENDPOINT_LIBRUS_API_LUCKY_NUMBER
import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApi import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.data.db.modules.luckynumber.LuckyNumber import pl.szczodrzynski.edziennik.data.db.modules.luckynumber.LuckyNumber
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
import pl.szczodrzynski.edziennik.getInt import pl.szczodrzynski.edziennik.getInt
import pl.szczodrzynski.edziennik.getJsonObject import pl.szczodrzynski.edziennik.getJsonObject
import pl.szczodrzynski.edziennik.getString import pl.szczodrzynski.edziennik.getString
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
class LibrusApiLuckyNumber(override val data: DataLibrus, class LibrusApiLuckyNumber(override val data: DataLibrus,
val onSuccess: () -> Unit) : LibrusApi(data) { val onSuccess: () -> Unit) : LibrusApi(data) {
@ -25,18 +26,26 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
data.profile?.luckyNumber = -1 data.profile?.luckyNumber = -1
data.profile?.luckyNumberDate = null data.profile?.luckyNumberDate = null
var nextSync = System.currentTimeMillis() + 2*DAY*1000
apiGet(TAG, "LuckyNumbers") { json -> apiGet(TAG, "LuckyNumbers") { json ->
if (json.isJsonNull) { if (json.isJsonNull) {
//profile?.luckyNumberEnabled = false //profile?.luckyNumberEnabled = false
} else { } else {
json.getJsonObject("LuckyNumber")?.also { luckyNumberEl -> json.getJsonObject("LuckyNumber")?.also { luckyNumberEl ->
val luckyNumberDate = Date.fromY_m_d(luckyNumberEl.getString("LuckyNumberDay")) ?: Date.getToday()
val luckyNumber = luckyNumberEl.getInt("LuckyNumber") ?: -1
val luckyNumberObject = LuckyNumber( val luckyNumberObject = LuckyNumber(
profileId, profileId,
Date.fromY_m_d(luckyNumberEl.getString("LuckyNumberDay")) ?: Date.getToday(), luckyNumberDate,
luckyNumberEl.getInt("LuckyNumber") ?: -1 luckyNumber
) )
//if (luckyNumberDate > Date.getToday()) {
nextSync = luckyNumberDate.combineWith(Time(15, 0, 0))
//}
data.luckyNumberList.add(luckyNumberObject) data.luckyNumberList.add(luckyNumberObject)
data.metadataList.add( data.metadataList.add(
Metadata( Metadata(
@ -50,7 +59,7 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
} }
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_LUCKY_NUMBER, SYNC_ALWAYS) data.setSyncNext(ENDPOINT_LIBRUS_API_LUCKY_NUMBER, syncAt = nextSync)
onSuccess() onSuccess()
} }
} }

View File

@ -33,6 +33,7 @@ class LibrusLogin(val data: DataLibrus, val onSuccess: () -> Unit) {
return return
} }
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId -> useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
data.progress(data.progressStep)
if (usedMethodId != -1) if (usedMethodId != -1)
data.loginMethods.add(usedMethodId) data.loginMethods.add(usedMethodId)
nextLoginMethod(onSuccess) nextLoginMethod(onSuccess)

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.mobidziennik package pl.szczodrzynski.edziennik.api.v2.mobidziennik
import android.util.Log
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
@ -17,7 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.api.v2.prepare import pl.szczodrzynski.edziennik.api.v2.prepare
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore 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
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils.d
class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
companion object { companion object {
@ -51,8 +50,8 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
|__*/ |__*/
override fun sync(featureIds: List<Int>, viewId: Int?) { override fun sync(featureIds: List<Int>, viewId: Int?) {
data.prepare(mobidziennikLoginMethods, MobidziennikFeatures, featureIds, viewId) data.prepare(mobidziennikLoginMethods, MobidziennikFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}") d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}") d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
MobidziennikLogin(data) { MobidziennikLogin(data) {
MobidziennikData(data) { MobidziennikData(data) {
completed() completed()
@ -75,7 +74,7 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
} }
override fun cancel() { override fun cancel() {
Utils.d(TAG, "Cancelled") d(TAG, "Cancelled")
data.cancel() data.cancel()
} }
@ -85,7 +84,7 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
callback.onCompleted() callback.onCompleted()
} }
override fun onProgress(step: Int) { override fun onProgress(step: Float) {
callback.onProgress(step) callback.onProgress(step)
} }

View File

@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.api.v2.mobidziennik package pl.szczodrzynski.edziennik.api.v2.mobidziennik
import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.*
import pl.szczodrzynski.edziennik.api.v2.librus.ENDPOINT_LIBRUS_API_PUSH_CONFIG
import pl.szczodrzynski.edziennik.api.v2.models.Feature import pl.szczodrzynski.edziennik.api.v2.models.Feature
const val ENDPOINT_MOBIDZIENNIK_API_MAIN = 1000 const val ENDPOINT_MOBIDZIENNIK_API_MAIN = 1000
@ -22,17 +21,17 @@ const val ENDPOINT_MOBIDZIENNIK_API2_MAIN = 3000
val MobidziennikFeatures = listOf( val MobidziennikFeatures = listOf(
// always synced // always synced
Feature(LOGIN_TYPE_MOBIDZIENNIK, FEATURE_ALWAYS_NEEDED, listOf( /*Feature(LOGIN_TYPE_MOBIDZIENNIK, FEATURE_ALWAYS_NEEDED, listOf(
ENDPOINT_MOBIDZIENNIK_API_MAIN to LOGIN_METHOD_MOBIDZIENNIK_WEB, ENDPOINT_MOBIDZIENNIK_API_MAIN to LOGIN_METHOD_MOBIDZIENNIK_WEB,
ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL to LOGIN_METHOD_MOBIDZIENNIK_WEB ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL to LOGIN_METHOD_MOBIDZIENNIK_WEB
), listOf(LOGIN_METHOD_MOBIDZIENNIK_WEB)), ), listOf(LOGIN_METHOD_MOBIDZIENNIK_WEB)),*/
// push config // push config
Feature(LOGIN_TYPE_MOBIDZIENNIK, FEATURE_PUSH_CONFIG, listOf( /*Feature(LOGIN_TYPE_MOBIDZIENNIK, FEATURE_PUSH_CONFIG, listOf(
ENDPOINT_MOBIDZIENNIK_API2_MAIN to LOGIN_METHOD_MOBIDZIENNIK_API2 ENDPOINT_MOBIDZIENNIK_API2_MAIN to LOGIN_METHOD_MOBIDZIENNIK_API2
), listOf(LOGIN_METHOD_MOBIDZIENNIK_API2)).withShouldSync { data -> ), listOf(LOGIN_METHOD_MOBIDZIENNIK_API2)).withShouldSync { data ->
data.app.appConfig.fcmTokens[LOGIN_TYPE_MOBIDZIENNIK]?.second?.contains(data.profileId) == false data.app.appConfig.fcmTokens[LOGIN_TYPE_MOBIDZIENNIK]?.second?.contains(data.profileId) == false
}, },*/

View File

@ -32,6 +32,7 @@ class MobidziennikData(val data: DataMobidziennik, val onSuccess: () -> Unit) {
return return
} }
useEndpoint(data.targetEndpointIds.removeAt(0)) { useEndpoint(data.targetEndpointIds.removeAt(0)) {
data.progress(data.progressStep)
nextEndpoint(onSuccess) nextEndpoint(onSuccess)
} }
} }

View File

@ -31,6 +31,7 @@ class MobidziennikLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) {
return return
} }
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId -> useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
data.progress(data.progressStep)
if (usedMethodId != -1) if (usedMethodId != -1)
data.loginMethods.add(usedMethodId) data.loginMethods.add(usedMethodId)
nextLoginMethod(onSuccess) nextLoginMethod(onSuccess)

View File

@ -51,4 +51,10 @@ class ApiError(val tag: String, val errorCode: Int) {
errorCode, response, throwable, apiResponse errorCode, response, throwable, apiResponse
) )
} }
override fun toString(): String {
return "ApiError(tag='$tag', errorCode=$errorCode, profileId=$profileId, throwable=$throwable, apiResponse=$apiResponse, request=$request, response=$response, isCritical=$isCritical)"
}
} }

View File

@ -1,9 +0,0 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
*/
package pl.szczodrzynski.edziennik.api.v2.models
open class ApiTask(open val profileId: Int) {
var taskId: Int = 0
}

View File

@ -91,6 +91,15 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
* to run. * to run.
*/ */
var targetEndpointIds = mutableListOf<Int>() var targetEndpointIds = mutableListOf<Int>()
/**
* A count of all network requests to do.
*/
var progressCount: Int = 0
/**
* A number by which the progress will be incremented, every time
* a login method/endpoint finishes its job.
*/
var progressStep: Float = 0f
/** /**
* A map of endpoint IDs to JSON objects, specifying their arguments bundle. * A map of endpoint IDs to JSON objects, specifying their arguments bundle.
@ -386,7 +395,7 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
callback.onError(apiError) callback.onError(apiError)
} }
fun progress(step: Int) { fun progress(step: Float) {
callback.onProgress(step) callback.onProgress(step)
} }

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.template package pl.szczodrzynski.edziennik.api.v2.template
import android.util.Log
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
@ -17,7 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.template.login.TemplateLogin
import pl.szczodrzynski.edziennik.api.v2.templateLoginMethods import pl.szczodrzynski.edziennik.api.v2.templateLoginMethods
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore 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
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils.d
class Template(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Template(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
companion object { companion object {
@ -51,8 +50,8 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|__*/ |__*/
override fun sync(featureIds: List<Int>, viewId: Int?) { override fun sync(featureIds: List<Int>, viewId: Int?) {
data.prepare(templateLoginMethods, TemplateFeatures, featureIds, viewId) data.prepare(templateLoginMethods, TemplateFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}") d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}") d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
TemplateLogin(data) { TemplateLogin(data) {
TemplateData(data) { TemplateData(data) {
completed() completed()
@ -75,7 +74,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
} }
override fun cancel() { override fun cancel() {
Utils.d(TAG, "Cancelled") d(TAG, "Cancelled")
data.cancel() data.cancel()
} }
@ -85,7 +84,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
callback.onCompleted() callback.onCompleted()
} }
override fun onProgress(step: Int) { override fun onProgress(step: Float) {
callback.onProgress(step) callback.onProgress(step)
} }

View File

@ -19,8 +19,6 @@ class TemplateData(val data: DataTemplate, val onSuccess: () -> Unit) {
private const val TAG = "TemplateData" private const val TAG = "TemplateData"
} }
private var cancelled = false
init { init {
nextEndpoint(onSuccess) nextEndpoint(onSuccess)
} }
@ -30,11 +28,12 @@ class TemplateData(val data: DataTemplate, val onSuccess: () -> Unit) {
onSuccess() onSuccess()
return return
} }
if (cancelled) { if (data.cancelled) {
onSuccess() onSuccess()
return return
} }
useEndpoint(data.targetEndpointIds.removeAt(0)) { useEndpoint(data.targetEndpointIds.removeAt(0)) {
data.progress(data.progressStep)
nextEndpoint(onSuccess) nextEndpoint(onSuccess)
} }
} }

View File

@ -5,7 +5,8 @@
package pl.szczodrzynski.edziennik.api.v2.template.login package pl.szczodrzynski.edziennik.api.v2.template.login
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_TEMPLATE_API
import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_TEMPLATE_WEB
import pl.szczodrzynski.edziennik.api.v2.template.DataTemplate import pl.szczodrzynski.edziennik.api.v2.template.DataTemplate
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
@ -30,6 +31,7 @@ class TemplateLogin(val data: DataTemplate, val onSuccess: () -> Unit) {
return return
} }
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId -> useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
data.progress(data.progressStep)
if (usedMethodId != -1) if (usedMethodId != -1)
data.loginMethods.add(usedMethodId) data.loginMethods.add(usedMethodId)
nextLoginMethod(onSuccess) nextLoginMethod(onSuccess)

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.vulcan package pl.szczodrzynski.edziennik.api.v2.vulcan
import android.util.Log
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
@ -17,7 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.vulcan.login.VulcanLogin
import pl.szczodrzynski.edziennik.api.v2.vulcanLoginMethods import pl.szczodrzynski.edziennik.api.v2.vulcanLoginMethods
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore 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
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils.d
class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
companion object { companion object {
@ -51,8 +50,8 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|__*/ |__*/
override fun sync(featureIds: List<Int>, viewId: Int?) { override fun sync(featureIds: List<Int>, viewId: Int?) {
data.prepare(vulcanLoginMethods, VulcanFeatures, featureIds, viewId) data.prepare(vulcanLoginMethods, VulcanFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}") d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}") d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
VulcanLogin(data) { VulcanLogin(data) {
VulcanData(data) { VulcanData(data) {
completed() completed()
@ -75,7 +74,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
} }
override fun cancel() { override fun cancel() {
Utils.d(TAG, "Cancelled") d(TAG, "Cancelled")
data.cancel() data.cancel()
} }
@ -85,7 +84,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
callback.onCompleted() callback.onCompleted()
} }
override fun onProgress(step: Int) { override fun onProgress(step: Float) {
callback.onProgress(step) callback.onProgress(step)
} }

View File

@ -14,8 +14,6 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
private const val TAG = "VulcanData" private const val TAG = "VulcanData"
} }
private var cancelled = false
init { init {
nextEndpoint(onSuccess) nextEndpoint(onSuccess)
} }
@ -25,11 +23,12 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
onSuccess() onSuccess()
return return
} }
if (cancelled) { if (data.cancelled) {
onSuccess() onSuccess()
return return
} }
useEndpoint(data.targetEndpointIds.removeAt(0)) { useEndpoint(data.targetEndpointIds.removeAt(0)) {
data.progress(data.progressStep)
nextEndpoint(onSuccess) nextEndpoint(onSuccess)
} }
} }

View File

@ -30,6 +30,7 @@ class VulcanLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
return return
} }
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId -> useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
data.progress(data.progressStep)
if (usedMethodId != -1) if (usedMethodId != -1)
data.loginMethods.add(usedMethodId) data.loginMethods.add(usedMethodId)
nextLoginMethod(onSuccess) nextLoginMethod(onSuccess)

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-10-25.
*/
package pl.szczodrzynski.edziennik.data.db.modules.timetable
import androidx.room.ColumnInfo
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
open class Lesson(val profileId: Int) {
companion object {
const val TYPE_NORMAL = 0
const val TYPE_CANCELLED = 1
const val TYPE_CHANGE = 2
const val TYPE_SHIFTED_SOURCE = 3 /* source lesson */
const val TYPE_SHIFTED_TARGET = 4 /* target lesson */
}
@ColumnInfo(name = "lessonType")
var type: Int = TYPE_NORMAL
var date: Date? = null
var lessonNumber: Int? = null
var startTime: Time? = null
var endTime: Time? = null
var teacherId: Long? = null
var subjectId: Long? = null
var teamId: Long? = null
var classroom: String? = null
var oldDate: Date? = null
var oldLessonNumber: Int? = null
var oldStartTime: Time? = null
var oldEndTime: Time? = null
var oldTeacherId: Long? = null
var oldSubjectId: Long? = null
var oldTeamId: Long? = null
var oldClassroom: String? = null
}

View File

@ -9,9 +9,8 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import pl.szczodrzynski.edziennik.api.v2.ApiService import pl.szczodrzynski.edziennik.api.v2.ApiService
import pl.szczodrzynski.edziennik.api.v2.events.requests.ServiceCloseRequest import pl.szczodrzynski.edziennik.api.v2.events.requests.ServiceCloseRequest
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.TaskCancelRequest import pl.szczodrzynski.edziennik.api.v2.events.requests.TaskCancelRequest
import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
class SzkolnyReceiver : BroadcastReceiver() { class SzkolnyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) { override fun onReceive(context: Context?, intent: Intent?) {
@ -19,8 +18,8 @@ class SzkolnyReceiver : BroadcastReceiver() {
when (intent?.extras?.getString("task", null)) { when (intent?.extras?.getString("task", null)) {
"ServiceCloseRequest" -> ApiService.startAndRequest(context, ServiceCloseRequest()) "ServiceCloseRequest" -> ApiService.startAndRequest(context, ServiceCloseRequest())
"TaskCancelRequest" -> ApiService.startAndRequest(context, TaskCancelRequest(intent.extras?.getInt("taskId", -1) ?: return)) "TaskCancelRequest" -> ApiService.startAndRequest(context, TaskCancelRequest(intent.extras?.getInt("taskId", -1) ?: return))
"SyncRequest" -> ApiService.startAndRequest(context, SyncRequest()) "SyncRequest" -> EdziennikTask.sync().enqueue(context)
"SyncProfileRequest" -> ApiService.startAndRequest(context, SyncProfileRequest(intent.extras?.getInt("profileId", -1) ?: return)) "SyncProfileRequest" -> EdziennikTask.syncProfile(intent.extras?.getInt("profileId", -1) ?: return).enqueue(context)
} }
} }
} }

View File

@ -17,9 +17,7 @@ import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.BuildConfig; import pl.szczodrzynski.edziennik.BuildConfig;
import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.api.v2.ApiService; import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask;
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncProfileRequest;
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest;
import pl.szczodrzynski.edziennik.data.db.modules.events.Event; import pl.szczodrzynski.edziennik.data.db.modules.events.Event;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull; import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventType; import pl.szczodrzynski.edziennik.data.db.modules.events.EventType;
@ -114,7 +112,7 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
app.notifier.postAll(profile); app.notifier.postAll(profile);
app.saveConfig("notifications");*/ app.saveConfig("notifications");*/
d(TAG, "Syncing profile " + profile.getId()); d(TAG, "Syncing profile " + profile.getId());
ApiService.Companion.startAndRequest(app, new SyncProfileRequest(profile.getId(), null)); EdziennikTask.Companion.syncProfile(profile.getId(), null).enqueue(app);
} else { } else {
/*app.notifier.add(new Notification(app.getContext(), remoteMessage.getData().get("message")) /*app.notifier.add(new Notification(app.getContext(), remoteMessage.getData().get("message"))
.withProfileData(profile.id, profile.name) .withProfileData(profile.id, profile.name)
@ -125,7 +123,7 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
app.notifier.postAll(profile); app.notifier.postAll(profile);
app.saveConfig("notifications");*/ app.saveConfig("notifications");*/
d(TAG, "Syncing profile " + profile.getId()); d(TAG, "Syncing profile " + profile.getId());
ApiService.Companion.startAndRequest(app, new SyncProfileRequest(profile.getId(), null)); EdziennikTask.Companion.syncProfile(profile.getId(), null).enqueue(app);
} }
} }
}); });

View File

@ -8,8 +8,7 @@ import androidx.work.impl.WorkManagerImpl
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MINUTE import pl.szczodrzynski.edziennik.MINUTE
import pl.szczodrzynski.edziennik.api.v2.ApiService import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest
import pl.szczodrzynski.edziennik.formatDate import pl.szczodrzynski.edziennik.formatDate
import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.utils.Utils.d
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -101,7 +100,7 @@ class SyncWorker(val context: Context, val params: WorkerParameters) : Worker(co
override fun doWork(): Result { override fun doWork(): Result {
d(TAG, "Running worker ID ${params.id}") d(TAG, "Running worker ID ${params.id}")
ApiService.startAndRequest(context, SyncRequest()) EdziennikTask.sync().enqueue(context)
rescheduleNext(context as App) rescheduleNext(context as App)
return Result.success() return Result.success()
} }

View File

@ -1,6 +1,5 @@
package pl.szczodrzynski.edziennik.ui.modules.login; package pl.szczodrzynski.edziennik.ui.modules.login;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -21,10 +20,9 @@ import org.greenrobot.eventbus.ThreadMode;
import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.api.v2.ApiService; import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskErrorEvent;
import pl.szczodrzynski.edziennik.api.v2.events.FirstLoginFinishedEvent; import pl.szczodrzynski.edziennik.api.v2.events.FirstLoginFinishedEvent;
import pl.szczodrzynski.edziennik.api.v2.events.SyncErrorEvent; import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask;
import pl.szczodrzynski.edziennik.api.v2.events.requests.FirstLoginRequest;
import pl.szczodrzynski.edziennik.data.api.AppError; import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore; import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore;
import pl.szczodrzynski.edziennik.databinding.FragmentLoginProgressBinding; import pl.szczodrzynski.edziennik.databinding.FragmentLoginProgressBinding;
@ -63,13 +61,15 @@ public class LoginProgressFragment extends Fragment {
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncErrorEvent(SyncErrorEvent event) { public void onSyncErrorEvent(ApiTaskErrorEvent event) {
LoginActivity.error = event.getError().toAppError(); LoginActivity.error = event.getError().toAppError();
if (getActivity() == null) if (getActivity() == null)
return; return;
nav.navigateUp(); nav.navigateUp();
} }
// TODO add progress bar in login
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
assert getContext() != null; assert getContext() != null;
@ -89,8 +89,7 @@ public class LoginProgressFragment extends Fragment {
LoginStore loginStore = new LoginStore(-1, loginType, new JsonObject()); LoginStore loginStore = new LoginStore(-1, loginType, new JsonObject());
loginStore.copyFrom(args); loginStore.copyFrom(args);
getContext().startService(new Intent(app, ApiService.class)); EdziennikTask.Companion.firstLogin(loginStore).enqueue(getContext());
EventBus.getDefault().postSticky(new FirstLoginRequest(loginStore));
} }
@Override @Override

View File

@ -15,12 +15,11 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.ApiService import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskAllFinishedEvent
import pl.szczodrzynski.edziennik.api.v2.events.SyncErrorEvent import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskErrorEvent
import pl.szczodrzynski.edziennik.api.v2.events.SyncFinishedEvent import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskProgressEvent
import pl.szczodrzynski.edziennik.api.v2.events.SyncProgressEvent import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskStartedEvent
import pl.szczodrzynski.edziennik.api.v2.events.SyncStartedEvent import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
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.Event.*
import pl.szczodrzynski.edziennik.data.db.modules.events.EventType 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.login.LoginStore
@ -29,6 +28,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile.Companion.REG
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile.Companion.REGISTRATION_ENABLED 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.data.db.modules.profiles.Profile.Companion.REGISTRATION_UNSPECIFIED
import pl.szczodrzynski.edziennik.databinding.FragmentLoginSyncBinding import pl.szczodrzynski.edziennik.databinding.FragmentLoginSyncBinding
import kotlin.math.roundToInt
class LoginSyncFragment : Fragment() { class LoginSyncFragment : Fragment() {
@ -47,23 +47,24 @@ class LoginSyncFragment : Fragment() {
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncStartedEvent(event: SyncStartedEvent) { fun onSyncStartedEvent(event: ApiTaskStartedEvent) {
b.loginSyncSubtitle1.text = Html.fromHtml(getString(R.string.login_sync_subtitle_1_format, event.profile?.name ?: "")) b.loginSyncSubtitle1.text = Html.fromHtml(getString(R.string.login_sync_subtitle_1_format, event.profile?.name ?: ""))
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncFinishedEvent(event: SyncFinishedEvent) { fun onSyncFinishedEvent(event: ApiTaskAllFinishedEvent) {
nav.navigate(R.id.loginFinishFragment, null, LoginActivity.navOptions) nav.navigate(R.id.loginFinishFragment, null, LoginActivity.navOptions)
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncProgressEvent(event: SyncProgressEvent) { fun onSyncProgressEvent(event: ApiTaskProgressEvent) {
b.loginSyncProgressBar.progress = event.progress b.loginSyncProgressBar.progress = event.progress.roundToInt()
b.loginSyncSubtitle2.text = event.progressRes?.let { getString(it) } b.loginSyncProgressBar.isIndeterminate = event.progress < 0f
b.loginSyncSubtitle2.text = event.progressText
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncErrorEvent(event: SyncErrorEvent) { fun onSyncErrorEvent(event: ApiTaskErrorEvent) {
LoginActivity.error = event.error.toAppError() LoginActivity.error = event.error.toAppError()
nav.navigate(R.id.loginSyncErrorFragment, null, LoginActivity.navOptions) nav.navigate(R.id.loginSyncErrorFragment, null, LoginActivity.navOptions)
} }
@ -109,8 +110,7 @@ class LoginSyncFragment : Fragment() {
} }
LoginFinishFragment.firstProfileId = firstProfileId LoginFinishFragment.firstProfileId = firstProfileId
ApiService.start(activity) EdziennikTask.syncProfileList(profileIds).enqueue(activity)
EventBus.getDefault().postSticky(SyncProfileListRequest(profileIds))
} }
} }

View File

@ -1,6 +1,8 @@
package pl.szczodrzynski.edziennik.ui.modules.messages package pl.szczodrzynski.edziennik.ui.modules.messages
import android.os.Bundle import android.os.Bundle
import android.text.Html
import android.text.InputType
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -8,11 +10,20 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter import androidx.fragment.app.FragmentPagerAdapter
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.afollestad.materialdialogs.MaterialDialog
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.databinding.FragmentMessagesBinding import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.LOGIN_TYPE_LIBRUS
import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskErrorEvent
import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskFinishedEvent
import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message import pl.szczodrzynski.edziennik.data.db.modules.messages.Message
import pl.szczodrzynski.edziennik.databinding.FragmentMessagesBinding
import pl.szczodrzynski.edziennik.utils.Themes import pl.szczodrzynski.edziennik.utils.Themes
import java.util.* import java.util.*
@ -80,6 +91,61 @@ class MessagesFragment : Fragment() {
}) })
b.tabLayout.setupWithViewPager(b.viewPager) b.tabLayout.setupWithViewPager(b.viewPager)
if (app.profile.loginStoreType == LOGIN_TYPE_LIBRUS && app.profile.getStudentData("accountPassword", null) == null) {
MaterialDialog.Builder(activity)
.title("Wiadomości w systemie Synergia")
.content("Moduł Wiadomości w aplikacji Szkolny.eu jest przeglądarką zasobów szkolnego konta Synergia. Z tego powodu, musisz wpisać swoje hasło do tego konta, aby móc korzystać z tej funkcji.")
.positiveText(R.string.ok)
.onPositive { dialog, which ->
MaterialDialog.Builder(activity)
.title("Zaloguj się")
.content(Html.fromHtml("Podaj hasło do konta Synergia z loginem <b>" + app.profile.getStudentData("accountLogin", "???") + "</b>"))
.inputType(InputType.TYPE_TEXT_VARIATION_PASSWORD)
.input(null, null) { dialog1, input ->
app.profile.putStudentData("accountPassword", input.toString())
app.profileSaveFullAsync(app.profile)
EdziennikTask.syncProfile(App.profileId, listOf(
DRAWER_ITEM_MESSAGES to Message.TYPE_RECEIVED,
DRAWER_ITEM_MESSAGES to Message.TYPE_SENT
)).enqueue(context!!)
}
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
.show()
}
.show()
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncProfileFinishedEvent(event: ApiTaskFinishedEvent) {
if (event.profileId == App.profileId) {
app.profileSaveFullAsync(app.profile)
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncErrorEvent(event: ApiTaskErrorEvent) {
app.profile.removeStudentData("accountPassword")
app.profileSaveFullAsync(app.profile)
/*MaterialDialog.Builder(activity)
.title(R.string.login_failed)
.content(R.string.login_failed_text)
.positiveText(R.string.ok)
.neutralText(R.string.report)
.onNeutral { dialog2, which1 -> app.apiEdziennik.guiReportError(getActivity(), error, null) }
.show()*/
}
override fun onStart() {
EventBus.getDefault().register(this)
super.onStart()
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
} }
internal class Adapter(manager: FragmentManager) : FragmentPagerAdapter(manager) { internal class Adapter(manager: FragmentManager) : FragmentPagerAdapter(manager) {

View File

@ -1,13 +1,9 @@
package pl.szczodrzynski.edziennik.ui.modules.messages; package pl.szczodrzynski.edziennik.ui.modules.messages;
import android.content.Context;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.text.InputType;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -21,28 +17,19 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import com.afollestad.materialdialogs.MaterialDialog;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.data.api.AppError; import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.api.Edziennik;
import pl.szczodrzynski.edziennik.data.api.interfaces.SyncCallback;
import pl.szczodrzynski.edziennik.databinding.MessagesListBinding;
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore;
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message; import pl.szczodrzynski.edziennik.data.db.modules.messages.Message;
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull; import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull;
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageRecipientFull; import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageRecipientFull;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile; import pl.szczodrzynski.edziennik.databinding.MessagesListBinding;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull;
import pl.szczodrzynski.edziennik.utils.Themes; import pl.szczodrzynski.edziennik.utils.Themes;
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION; import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_LIBRUS;
import static pl.szczodrzynski.edziennik.utils.Utils.d; import static pl.szczodrzynski.edziennik.utils.Utils.d;
public class MessagesListFragment extends Fragment { public class MessagesListFragment extends Fragment {
@ -96,66 +83,6 @@ public class MessagesListFragment extends Fragment {
return; return;
} }
if (app.profile.getLoginStoreType() == LOGIN_TYPE_LIBRUS && app.profile.getStudentData("accountPassword", null) == null && false) {
new MaterialDialog.Builder(activity)
.title("Wiadomości w systemie Synergia")
.content("Moduł Wiadomości w aplikacji Szkolny.eu jest przeglądarką zasobów szkolnego konta Synergia. Z tego powodu, musisz wpisać swoje hasło do tego konta, aby móc korzystać z tej funkcji.")
.positiveText(R.string.ok)
.onPositive(((dialog, which) -> {
new MaterialDialog.Builder(activity)
.title("Zaloguj się")
.content(Html.fromHtml("Podaj hasło do konta Synergia z loginem <b>"+app.profile.getStudentData("accountLogin", "???")+"</b>"))
.inputType(InputType.TYPE_TEXT_VARIATION_PASSWORD)
.input(null, null, (dialog1, input) -> {
app.profile.putStudentData("accountPassword", input.toString());
Edziennik.getApi(app, app.profile.getLoginStoreType()).syncMessages(activity, new SyncCallback() {
@Override
public void onLoginFirst(List<Profile> profileList, LoginStore loginStore) {
}
@Override
public void onSuccess(Context activityContext, ProfileFull profileFull) {
app.profile.putStudentData("accountPassword", input.toString());
app.profileSaveFullAsync(profileFull);
((MainActivity) activityContext).recreate();
}
@Override
public void onError(Context activityContext, AppError error) {
new Handler(activityContext.getMainLooper()).post(() -> {
app.profile.removeStudentData("accountPassword");
app.profileSaveFullAsync(app.profile);
new MaterialDialog.Builder(activity)
.title(R.string.login_failed)
.content(R.string.login_failed_text)
.positiveText(R.string.ok)
.neutralText(R.string.report)
.onNeutral(((dialog2, which1) -> {
app.apiEdziennik.guiReportError(getActivity(), error, null);
}))
.show();
});
}
@Override
public void onProgress(int progressStep) {
}
@Override
public void onActionStarted(int stringResId) {
}
}, app.profile);
})
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
.show();
}))
.show();
}
if (getArguments() != null) { if (getArguments() != null) {
messageType = getArguments().getInt("messageType", Message.TYPE_RECEIVED); messageType = getArguments().getInt("messageType", Message.TYPE_RECEIVED);
} }

View File

@ -236,7 +236,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
} }
else { else {
items.add( /*items.add(
new MaterialAboutSwitchItem( new MaterialAboutSwitchItem(
getString(R.string.settings_profile_notify_text), getString(R.string.settings_profile_notify_text),
getString(R.string.settings_profile_notify_subtext), getString(R.string.settings_profile_notify_subtext),
@ -251,7 +251,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
app.profileSaveAsync(); app.profileSaveAsync();
return true; return true;
})) }))
); );*/
items.add( items.add(
new MaterialAboutActionItem( new MaterialAboutActionItem(

View File

@ -24,8 +24,7 @@ import java.lang.reflect.Method;
import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.api.v2.ApiService; import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask;
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile; import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
import pl.szczodrzynski.edziennik.utils.models.Date; import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.widgets.WidgetConfig; import pl.szczodrzynski.edziennik.widgets.WidgetConfig;
@ -40,7 +39,7 @@ public class WidgetLuckyNumber extends AppWidgetProvider {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (ACTION_SYNC_DATA.equals(intent.getAction())){ if (ACTION_SYNC_DATA.equals(intent.getAction())){
ApiService.Companion.startAndRequest(context, new SyncRequest()); EdziennikTask.Companion.sync().enqueue(context);
} }
super.onReceive(context, intent); super.onReceive(context, intent);
} }

View File

@ -24,8 +24,7 @@ import java.lang.reflect.Method;
import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.api.v2.ApiService; import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask;
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest;
import pl.szczodrzynski.edziennik.widgets.WidgetConfig; import pl.szczodrzynski.edziennik.widgets.WidgetConfig;
public class WidgetNotifications extends AppWidgetProvider { public class WidgetNotifications extends AppWidgetProvider {
@ -36,7 +35,7 @@ public class WidgetNotifications extends AppWidgetProvider {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (ACTION_SYNC_DATA.equals(intent.getAction())){ if (ACTION_SYNC_DATA.equals(intent.getAction())){
ApiService.Companion.startAndRequest(context, new SyncRequest()); EdziennikTask.Companion.sync().enqueue(context);
} }
super.onReceive(context, intent); super.onReceive(context, intent);
} }

View File

@ -982,4 +982,5 @@
<string name="app_manager_dialog_text">Na urządzeniu prawdopodobnie zainstalowany jest menedżer aplikacji, który może powodować problemy z synchronizacją automatyczną.\n\nNależy wyłączyć w ustawieniach telefonu optymalizację baterii dla aplikacji Szkolny.eu.\n\nKliknij OK, aby przejść do ustawień telefonu.</string> <string name="app_manager_dialog_text">Na urządzeniu prawdopodobnie zainstalowany jest menedżer aplikacji, który może powodować problemy z synchronizacją automatyczną.\n\nNależy wyłączyć w ustawieniach telefonu optymalizację baterii dla aplikacji Szkolny.eu.\n\nKliknij OK, aby przejść do ustawień telefonu.</string>
<string name="dont_ask_again">Nie pytaj ponownie</string> <string name="dont_ask_again">Nie pytaj ponownie</string>
<string name="app_manager_open_failed">Nie udało się otworzyć ustawień</string> <string name="app_manager_open_failed">Nie udało się otworzyć ustawień</string>
<string name="edziennik_notification_api_notify_title">Tworzenie powiadomień</string>
</resources> </resources>