From 5d3bebfdce8e6c1d7e5b6bc279e258775256f414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 22 Oct 2019 22:37:02 +0200 Subject: [PATCH] [APIv2] Implement swipe to refresh with ApiService. --- .../szczodrzynski/edziennik/MainActivity.kt | 132 +++++++++++------- .../edziennik/api/v2/ApiService.kt | 12 +- .../edziennik/receivers/SzkolnyReceiver.kt | 2 + app/src/main/res/values/strings.xml | 2 + 4 files changed, 92 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index e617b152..c27156ff 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -14,66 +14,66 @@ import android.view.Gravity import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity -import androidx.lifecycle.Observer -import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial -import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont -import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem -import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem -import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.* -import pl.szczodrzynski.edziennik.utils.Themes -import pl.szczodrzynski.navlib.SystemBarsUtil.Companion.COLOR_HALF_TRANSPARENT -import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet -import pl.szczodrzynski.navlib.drawer.NavDrawer -import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem -import pl.szczodrzynski.navlib.drawer.items.withAppTitle import androidx.appcompat.widget.PopupMenu import androidx.core.graphics.ColorUtils +import androidx.lifecycle.Observer import androidx.navigation.NavOptions import com.danimahardhika.cafebar.CafeBar import com.mikepenz.iconics.IconicsColor import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.IconicsSize +import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial +import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont import com.mikepenz.materialdrawer.model.DividerDrawerItem import com.mikepenz.materialdrawer.model.ProfileDrawerItem +import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem +import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem import com.mikepenz.materialdrawer.model.interfaces.IProfile -import me.zhanghai.android.materialprogressbar.internal.ThemeUtils +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode import pl.droidsonroids.gif.GifDrawable import pl.szczodrzynski.edziennik.App.APP_URL -import pl.szczodrzynski.edziennik.data.api.AppError +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.data.api.interfaces.EdziennikInterface.* -import pl.szczodrzynski.edziennik.data.api.interfaces.SyncCallback +import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.* import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding -import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore -import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile -import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull -import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog -import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment -import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity -import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesDetailsFragment -import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment -import pl.szczodrzynski.edziennik.utils.models.NavTarget import pl.szczodrzynski.edziennik.network.ServerRequest import pl.szczodrzynski.edziennik.sync.SyncJob +import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment import pl.szczodrzynski.edziennik.ui.modules.announcements.AnnouncementsFragment import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceFragment import pl.szczodrzynski.edziennik.ui.modules.base.DebugFragment +import pl.szczodrzynski.edziennik.ui.modules.behaviour.BehaviourFragment import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment -import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment import pl.szczodrzynski.edziennik.ui.modules.grades.GradesFragment +import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment -import pl.szczodrzynski.edziennik.ui.modules.behaviour.BehaviourFragment +import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment +import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity +import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesDetailsFragment +import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsFragment import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsNewFragment 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.dpToPx +import pl.szczodrzynski.edziennik.utils.models.NavTarget import pl.szczodrzynski.navlib.* +import pl.szczodrzynski.navlib.SystemBarsUtil.Companion.COLOR_HALF_TRANSPARENT +import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem +import pl.szczodrzynski.navlib.drawer.NavDrawer +import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem +import pl.szczodrzynski.navlib.drawer.items.withAppTitle import java.io.File import java.io.IOException import java.util.* @@ -474,6 +474,13 @@ class MainActivity : AppCompatActivity() { .withIcon(CommunityMaterial.Icon.cmd_android_debug_bridge) .withOnClickListener(View.OnClickListener { loadTarget(DRAWER_ITEM_DEBUG) }) } + + EventBus.getDefault().register(this) + } + + override fun onDestroy() { + EventBus.getDefault().unregister(this) + super.onDestroy() } var profileListEmptyListener = { @@ -508,35 +515,56 @@ class MainActivity : AppCompatActivity() { fun syncCurrentFeature() { swipeRefreshLayout.isRefreshing = true Toast.makeText(this, fragmentToSyncName(navTargetId), Toast.LENGTH_SHORT).show() - val callback = object : SyncCallback { - override fun onLoginFirst(profileList: List, loginStore: LoginStore) { - - } - - override fun onSuccess(activityContext: Context, profileFull: ProfileFull) { - swipeRefreshLayout.isRefreshing = false - } - - override fun onError(activityContext: Context, error: AppError) { - swipeRefreshLayout.isRefreshing = false - app.apiEdziennik.guiShowErrorSnackbar(this@MainActivity, error) - } - - override fun onProgress(progressStep: Int) { - - } - - override fun onActionStarted(stringResId: Int) { - + ApiService.start(this) + val fragmentParam = when (navTargetId) { + DRAWER_ITEM_MESSAGES -> MessagesFragment.pageSelection + else -> 0 + } + EventBus.getDefault().postSticky( + SyncProfileRequest( + App.profileId, + listOf(navTargetId to fragmentParam) + ) + ) + } + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncStartedEvent(event: SyncStartedEvent) { + swipeRefreshLayout.isRefreshing = true + if (event.profileId == App.profileId) { + navView.toolbar.apply { + subtitleFormat = null + subtitleFormatWithUnread = null + subtitle = getString(R.string.toolbar_subtitle_syncing) } } - val feature = fragmentToFeature(navTargetId) - if (feature == FEATURE_ALL) { - swipeRefreshLayout.isRefreshing = false - app.apiEdziennik.guiSync(app, this, App.profileId, R.string.sync_dialog_title, R.string.sync_dialog_text, R.string.sync_done) - } else { - app.apiEdziennik.guiSyncSilent(app, this, App.profileId, callback, feature) + } + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncProgressEvent(event: SyncProgressEvent) { + 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) } ?: "") + } } + } + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncProfileFinishedEvent(event: SyncProfileFinishedEvent) { + if (event.profileId == App.profileId) { + navView.toolbar.apply { + subtitleFormat = R.string.toolbar_subtitle + subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread + subtitle = "Gotowe" + } + } + } + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncFinishedEvent(event: SyncFinishedEvent) { + swipeRefreshLayout.isRefreshing = false + } + @Subscribe(threadMode = ThreadMode.MAIN) + fun onSyncErrorEvent(event: SyncErrorEvent) { + } private fun fragmentToFeature(currentFragment: Int): Int { return when (currentFragment) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt index 6ec5b605..d5545fb0 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt @@ -5,6 +5,7 @@ package pl.szczodrzynski.edziennik.api.v2 import android.app.Service +import android.content.Context import android.content.Intent import android.os.IBinder import android.util.Log @@ -13,10 +14,7 @@ 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.SyncErrorEvent -import pl.szczodrzynski.edziennik.api.v2.events.SyncFinishedEvent -import pl.szczodrzynski.edziennik.api.v2.events.SyncProfileFinishedEvent -import pl.szczodrzynski.edziennik.api.v2.events.SyncProgressEvent +import pl.szczodrzynski.edziennik.api.v2.events.* import pl.szczodrzynski.edziennik.api.v2.events.requests.* import pl.szczodrzynski.edziennik.api.v2.events.task.ErrorReportTask import pl.szczodrzynski.edziennik.api.v2.events.task.NotifyTask @@ -37,6 +35,9 @@ class ApiService : Service() { companion object { const val TAG = "ApiService" const val NOTIFICATION_API_CHANNEL_ID = "pl.szczodrzynski.edziennik.GET_DATA" + fun start(context: Context) { + context.startService(Intent(context, ApiService::class.java)) + } } private val app by lazy { applicationContext as App } @@ -211,6 +212,9 @@ class ApiService : Service() { // update the notification notification.setCurrentTask(taskRunningId, taskProfileName).post() + // post an event + EventBus.getDefault().post(SyncStartedEvent(taskProfileId)) + edziennikInterface = when (loginStore.type) { LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback) LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt b/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt index e9d3fb9d..8cf52b11 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt @@ -8,6 +8,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import org.greenrobot.eventbus.EventBus +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 @@ -15,6 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.events.requests.TaskCancelRequest class SzkolnyReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { + context?.startService(Intent(context, ApiService::class.java)) when (intent?.extras?.getString("task", null)) { "ServiceCloseRequest" -> EventBus.getDefault().post(ServiceCloseRequest()) "TaskCancelRequest" -> EventBus.getDefault().post(TaskCancelRequest(intent.extras?.getInt("taskId", -1) ?: return)) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0c9952b5..1fb474fa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -952,4 +952,6 @@ Pobieranie nieobecności nauczycieli... Pobieranie rodzajów nieobecności nauczycieli... Pobieranie słowników... + Synchronizuję... + [%d%%] %s