[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.drawable.BitmapDrawable
import android.os.*
import android.util.Log
import android.view.Gravity
import android.view.View
import android.widget.Toast
@ -34,8 +33,7 @@ import pl.droidsonroids.gif.GifDrawable
import pl.szczodrzynski.edziennik.App.APP_URL
import pl.szczodrzynski.edziennik.api.v2.ApiService
import pl.szczodrzynski.edziennik.api.v2.events.*
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.task.EdziennikTask
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface.*
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.*
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.Themes
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.models.NavTarget
import pl.szczodrzynski.navlib.*
@ -77,7 +76,7 @@ import pl.szczodrzynski.navlib.drawer.items.withAppTitle
import java.io.File
import java.io.IOException
import java.util.*
import kotlin.math.roundToInt
class MainActivity : AppCompatActivity() {
companion object {
@ -499,7 +498,7 @@ class MainActivity : AppCompatActivity() {
profileListEmptyListener()
}
DRAWER_PROFILE_SYNC_ALL -> {
ApiService.startAndRequest(this, SyncRequest())
EdziennikTask.sync().enqueue(this)
}
else -> {
loadTarget(id)
@ -525,14 +524,14 @@ class MainActivity : AppCompatActivity() {
else -> 0
}
EventBus.getDefault().postSticky(
SyncProfileRequest(
EdziennikTask.syncProfile(
App.profileId,
listOf(navTargetId to fragmentParam)
)
)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncStartedEvent(event: SyncStartedEvent) {
fun onSyncStartedEvent(event: ApiTaskStartedEvent) {
swipeRefreshLayout.isRefreshing = true
if (event.profileId == App.profileId) {
navView.toolbar.apply {
@ -543,17 +542,21 @@ class MainActivity : AppCompatActivity() {
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncProgressEvent(event: SyncProgressEvent) {
fun onSyncProgressEvent(event: ApiTaskProgressEvent) {
if (event.profileId == App.profileId) {
navView.toolbar.apply {
subtitleFormat = 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)
fun onSyncProfileFinishedEvent(event: SyncProfileFinishedEvent) {
fun onSyncProfileFinishedEvent(event: ApiTaskFinishedEvent) {
if (event.profileId == App.profileId) {
navView.toolbar.apply {
subtitleFormat = R.string.toolbar_subtitle
@ -563,11 +566,11 @@ class MainActivity : AppCompatActivity() {
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncFinishedEvent(event: SyncFinishedEvent) {
fun onSyncFinishedEvent(event: ApiTaskAllFinishedEvent) {
swipeRefreshLayout.isRefreshing = false
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncErrorEvent(event: SyncErrorEvent) {
fun onSyncErrorEvent(event: ApiTaskErrorEvent) {
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
@ -657,11 +660,11 @@ class MainActivity : AppCompatActivity() {
}
private fun handleIntent(extras: Bundle?) {
Log.d(TAG, "handleIntent() {")
d(TAG, "handleIntent() {")
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) {
val reloadProfileId = extras.getInt("reloadProfileId", -1)
@ -785,7 +788,7 @@ class MainActivity : AppCompatActivity() {
fun loadProfile(id: Int) = loadProfile(id, navTargetId)
fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments)
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) {
drawer.currentProfile = app.profile.id
loadTarget(drawerSelection, arguments)
@ -825,7 +828,7 @@ class MainActivity : AppCompatActivity() {
}
}
private fun loadTarget(target: NavTarget, arguments: Bundle? = null) {
Log.d("NavDebug", "loadItem(id = ${target.id})")
d("NavDebug", "loadItem(id = ${target.id})")
bottomSheet.close()
bottomSheet.removeAllContextual()
@ -838,7 +841,7 @@ class MainActivity : AppCompatActivity() {
navView.bottomBar.fabExtended = false
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
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 ->
Log.d("NavDebug", " - $index: ${target2.fragmentClass?.java?.simpleName}")
d("NavDebug", " - $index: ${target2.fragmentClass?.java?.simpleName}")
}
transaction.replace(R.id.fragment, fragment)
@ -990,7 +993,7 @@ class MainActivity : AppCompatActivity() {
}
fun setDrawerItems() {
Log.d("NavDebug", "setDrawerItems() app.profile = ${app.profile ?: "null"}")
d("NavDebug", "setDrawerItems() app.profile = ${app.profile ?: "null"}")
val drawerItems = arrayListOf<IDrawerItem<*>>()
val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>()

View File

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

View File

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

View File

@ -10,9 +10,9 @@ 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
import kotlin.math.roundToInt
class EdziennikNotification(val context: Context) {
@ -92,18 +92,18 @@ class EdziennikNotification(val context: Context) {
return this
}
fun setProgress(progress: Int): EdziennikNotification {
notificationBuilder.setProgress(100, progress, false)
fun setProgress(progress: Float): EdziennikNotification {
notificationBuilder.setProgress(100, progress.roundToInt(), progress < 0f)
return this
}
fun setProgressRes(progressRes: Int): EdziennikNotification {
notificationBuilder.setContentTitle(context.getString(progressRes))
fun setProgressText(progressText: String?): EdziennikNotification {
notificationBuilder.setContentTitle(progressText)
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))
fun setCurrentTask(taskId: Int, progressText: String?): EdziennikNotification {
notificationBuilder.setProgress(100, 0, true)
notificationBuilder.setContentTitle(progressText)
notificationBuilder.apply {
val str = errorCountText()
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.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
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
class SyncErrorEvent(val error: ApiError)
class ApiTaskErrorEvent(val error: ApiError)

View File

@ -4,4 +4,4 @@
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
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
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.ApiService
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.ApiTask
import pl.szczodrzynski.edziennik.utils.Utils
class ErrorReportTask : ApiTask(-1) {
fun run(notification: EdziennikNotification, errorList: MutableList<ApiError>) {
notification
.setCurrentTask(taskId, null)
.setProgressRes(R.string.edziennik_notification_api_error_report_title)
.post()
class ErrorReportTask : IApiTask(-1) {
override fun prepare(app: App) {
taskName = app.getString(R.string.edziennik_notification_api_error_report_title)
}
override fun cancel() {
}
fun run(app: App, taskCallback: EdziennikCallback, notification: EdziennikNotification, errorList: MutableList<ApiError>) {
errorList.forEach { error ->
Utils.d(ApiService.TAG, "Error ${error.tag} profile ${error.profileId}: code ${error.errorCode}")
}
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.Notifier.ID_NOTIFICATIONS
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 kotlin.math.min
class NotifyTask : ApiTask(-1) {
fun run(app: App) {
class NotifyTask : IApiTask(-1) {
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 notificationList = list.subList(0, min(8, list.size))
val notificationList = list.subList(0, min(15, list.size))
var unreadCount = list.size
@ -75,5 +83,7 @@ class NotifyTask : ApiTask(-1) {
}
app.db.notificationDao().setAllPosted()
taskCallback.onCompleted()
}
}

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.idziennik
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.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.data.db.modules.login.LoginStore
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 {
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?) {
data.prepare(idziennikLoginMethods, IdziennikFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
IdziennikLogin(data) {
IdziennikData(data) {
completed()
@ -75,7 +74,7 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
}
override fun cancel() {
Utils.d(TAG, "Cancelled")
d(TAG, "Cancelled")
data.cancel()
}
@ -85,7 +84,7 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
callback.onCompleted()
}
override fun onProgress(step: Int) {
override fun onProgress(step: Float) {
callback.onProgress(step)
}

View File

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

View File

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

View File

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

View File

@ -4,7 +4,6 @@
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.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.data.db.modules.login.LoginStore
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 {
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?) {
data.prepare(librusLoginMethods, LibrusFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
LibrusLogin(data) {
LibrusData(data) {
completed()
@ -84,7 +83,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
}
override fun cancel() {
Utils.d(TAG, "Cancelled")
d(TAG, "Cancelled")
data.cancel()
}
@ -94,7 +93,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
callback.onCompleted()
}
override fun onProgress(step: Int) {
override fun onProgress(step: Float) {
callback.onProgress(step)
}

View File

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

View File

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

View File

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

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.mobidziennik
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.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.data.db.modules.login.LoginStore
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 {
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?) {
data.prepare(mobidziennikLoginMethods, MobidziennikFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
MobidziennikLogin(data) {
MobidziennikData(data) {
completed()
@ -75,7 +74,7 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
}
override fun cancel() {
Utils.d(TAG, "Cancelled")
d(TAG, "Cancelled")
data.cancel()
}
@ -85,7 +84,7 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
callback.onCompleted()
}
override fun onProgress(step: Int) {
override fun onProgress(step: Float) {
callback.onProgress(step)
}

View File

@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.api.v2.mobidziennik
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
const val ENDPOINT_MOBIDZIENNIK_API_MAIN = 1000
@ -22,17 +21,17 @@ const val ENDPOINT_MOBIDZIENNIK_API2_MAIN = 3000
val MobidziennikFeatures = listOf(
// 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_WEB_ACCOUNT_EMAIL to LOGIN_METHOD_MOBIDZIENNIK_WEB
), listOf(LOGIN_METHOD_MOBIDZIENNIK_WEB)),
), listOf(LOGIN_METHOD_MOBIDZIENNIK_WEB)),*/
// 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
), listOf(LOGIN_METHOD_MOBIDZIENNIK_API2)).withShouldSync { data ->
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
}
useEndpoint(data.targetEndpointIds.removeAt(0)) {
data.progress(data.progressStep)
nextEndpoint(onSuccess)
}
}

View File

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

View File

@ -51,4 +51,10 @@ class ApiError(val tag: String, val errorCode: Int) {
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.
*/
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.
@ -386,7 +395,7 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
callback.onError(apiError)
}
fun progress(step: Int) {
fun progress(step: Float) {
callback.onProgress(step)
}

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.template
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.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.data.db.modules.login.LoginStore
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 {
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?) {
data.prepare(templateLoginMethods, TemplateFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
TemplateLogin(data) {
TemplateData(data) {
completed()
@ -75,7 +74,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
}
override fun cancel() {
Utils.d(TAG, "Cancelled")
d(TAG, "Cancelled")
data.cancel()
}
@ -85,7 +84,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
callback.onCompleted()
}
override fun onProgress(step: Int) {
override fun onProgress(step: Float) {
callback.onProgress(step)
}

View File

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

View File

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

View File

@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.api.v2.vulcan
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.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.data.db.modules.login.LoginStore
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 {
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?) {
data.prepare(vulcanLoginMethods, VulcanFeatures, featureIds, viewId)
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
VulcanLogin(data) {
VulcanData(data) {
completed()
@ -75,7 +74,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
}
override fun cancel() {
Utils.d(TAG, "Cancelled")
d(TAG, "Cancelled")
data.cancel()
}
@ -85,7 +84,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
callback.onCompleted()
}
override fun onProgress(step: Int) {
override fun onProgress(step: Float) {
callback.onProgress(step)
}

View File

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

View File

@ -30,6 +30,7 @@ class VulcanLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
return
}
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
data.progress(data.progressStep)
if (usedMethodId != -1)
data.loginMethods.add(usedMethodId)
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 pl.szczodrzynski.edziennik.api.v2.ApiService
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.task.EdziennikTask
class SzkolnyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
@ -19,8 +18,8 @@ class SzkolnyReceiver : BroadcastReceiver() {
when (intent?.extras?.getString("task", null)) {
"ServiceCloseRequest" -> ApiService.startAndRequest(context, ServiceCloseRequest())
"TaskCancelRequest" -> ApiService.startAndRequest(context, TaskCancelRequest(intent.extras?.getInt("taskId", -1) ?: return))
"SyncRequest" -> ApiService.startAndRequest(context, SyncRequest())
"SyncProfileRequest" -> ApiService.startAndRequest(context, SyncProfileRequest(intent.extras?.getInt("profileId", -1) ?: return))
"SyncRequest" -> EdziennikTask.sync().enqueue(context)
"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.MainActivity;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.api.v2.ApiService;
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncProfileRequest;
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest;
import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask;
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.EventType;
@ -114,7 +112,7 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
app.notifier.postAll(profile);
app.saveConfig("notifications");*/
d(TAG, "Syncing profile " + profile.getId());
ApiService.Companion.startAndRequest(app, new SyncProfileRequest(profile.getId(), null));
EdziennikTask.Companion.syncProfile(profile.getId(), null).enqueue(app);
} else {
/*app.notifier.add(new Notification(app.getContext(), remoteMessage.getData().get("message"))
.withProfileData(profile.id, profile.name)
@ -125,7 +123,7 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
app.notifier.postAll(profile);
app.saveConfig("notifications");*/
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 pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MINUTE
import pl.szczodrzynski.edziennik.api.v2.ApiService
import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest
import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
import pl.szczodrzynski.edziennik.formatDate
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.util.concurrent.TimeUnit
@ -101,7 +100,7 @@ class SyncWorker(val context: Context, val params: WorkerParameters) : Worker(co
override fun doWork(): Result {
d(TAG, "Running worker ID ${params.id}")
ApiService.startAndRequest(context, SyncRequest())
EdziennikTask.sync().enqueue(context)
rescheduleNext(context as App)
return Result.success()
}

View File

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

View File

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

View File

@ -1,6 +1,8 @@
package pl.szczodrzynski.edziennik.ui.modules.messages
import android.os.Bundle
import android.text.Html
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -8,11 +10,20 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
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.R
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.databinding.FragmentMessagesBinding
import pl.szczodrzynski.edziennik.utils.Themes
import java.util.*
@ -80,6 +91,61 @@ class MessagesFragment : Fragment() {
})
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) {

View File

@ -1,13 +1,9 @@
package pl.szczodrzynski.edziennik.ui.modules.messages;
import android.content.Context;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -21,28 +17,19 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.afollestad.materialdialogs.MaterialDialog;
import java.util.ArrayList;
import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.data.api.AppError;
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.R;
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.MessageRecipientFull;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull;
import pl.szczodrzynski.edziennik.databinding.MessagesListBinding;
import pl.szczodrzynski.edziennik.utils.Themes;
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;
public class MessagesListFragment extends Fragment {
@ -96,66 +83,6 @@ public class MessagesListFragment extends Fragment {
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) {
messageType = getArguments().getInt("messageType", Message.TYPE_RECEIVED);
}

View File

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

View File

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

View File

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