[UI] Improve archive-related UI. Add archived info home card.

This commit is contained in:
Kuba Szczodrzyński
2020-08-25 19:14:11 +02:00
parent 1e3da45340
commit 6c6bc89f57
12 changed files with 299 additions and 67 deletions

View File

@ -42,6 +42,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.viewpager.widget.ViewPager
import com.google.android.gms.security.ProviderInstaller
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
@ -672,6 +673,16 @@ fun TextView.setText(@StringRes resid: Int, vararg formatArgs: Any) {
text = context.getString(resid, *formatArgs)
}
fun MaterialAlertDialogBuilder.setTitle(@StringRes resid: Int, vararg formatArgs: Any): MaterialAlertDialogBuilder {
setTitle(context.getString(resid, *formatArgs))
return this
}
fun MaterialAlertDialogBuilder.setMessage(@StringRes resid: Int, vararg formatArgs: Any): MaterialAlertDialogBuilder {
setMessage(context.getString(resid, *formatArgs))
return this
}
fun JsonObject(vararg properties: Pair<String, Any?>): JsonObject {
return JsonObject().apply {
for (property in properties) {

View File

@ -604,6 +604,46 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
__/ |
|__*/
fun syncCurrentFeature() {
if (app.profile.archived) {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.profile_archived_title)
.setMessage(
R.string.profile_archived_text,
app.profile.studentSchoolYearStart,
app.profile.studentSchoolYearStart + 1
)
.setPositiveButton(R.string.ok, null)
.show()
swipeRefreshLayout.isRefreshing = false
return
}
if (app.profile.isBeforeYear()) {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.profile_year_not_started_title)
.setMessage(
R.string.profile_year_not_started_format,
app.profile.dateSemester1Start.formattedString
)
.setPositiveButton(R.string.ok, null)
.show()
swipeRefreshLayout.isRefreshing = false
return
}
// vulcan hotfix
if (app.profile.dateYearEnd.month > 6) {
app.profile.dateYearEnd.month = 6
app.profile.dateYearEnd.day = 30
}
if (app.profile.shouldArchive()) {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.profile_archiving_title)
.setMessage(
R.string.profile_archiving_format,
app.profile.dateYearEnd.formattedString
)
.setPositiveButton(R.string.ok, null)
.show()
}
swipeRefreshLayout.isRefreshing = true
Toast.makeText(this, fragmentToSyncName(navTargetId), Toast.LENGTH_SHORT).show()
val fragmentParam = when (navTargetId) {

View File

@ -26,7 +26,6 @@ import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
companion object {
@ -74,6 +73,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
internal fun run(app: App, taskCallback: EdziennikCallback) {
profile?.let { profile ->
// vulcan hotfix
if (profile.dateYearEnd.month > 6) {
profile.dateYearEnd.month = 6
profile.dateYearEnd.day = 30
@ -83,11 +83,11 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
taskCallback.onError(ApiError(TAG, ERROR_PROFILE_ARCHIVED))
return
}
else if (Date.getToday() >= profile.dateYearEnd) {
else if (profile.shouldArchive()) {
d(TAG, "The profile $profileId's year ended on ${profile.dateYearEnd}, archiving")
ProfileArchiver(app, profile)
}
if (Date.getToday() < profile.dateSemester1Start) {
if (profile.isBeforeYear()) {
d(TAG, "The profile $profileId's school year has not started yet; aborting sync")
cancel()
taskCallback.onCompleted()

View File

@ -1,3 +1,7 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-8-25.
*/
package pl.szczodrzynski.edziennik.data.api.edziennik
import android.content.Intent

View File

@ -91,6 +91,9 @@ open class Profile(
@delegate:Ignore
val currentSemester by lazy { dateToSemester(Date.getToday()) }
fun shouldArchive() = Date.getToday() >= dateYearEnd && Date.getToday().year > studentSchoolYearStart
fun isBeforeYear() = Date.getToday() < dateSemester1Start
var disabledNotifications: List<Long>? = null
var lastReceiversSync: Long = 0

View File

@ -33,7 +33,7 @@ class CardItemTouchHelperCallback(private val cardAdapter: HomeCardAdapter, priv
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
removeCard(viewHolder.adapterPosition)
removeCard(viewHolder.adapterPosition, cardAdapter)
cardAdapter.items.removeAt(viewHolder.adapterPosition)
cardAdapter.notifyItemRemoved(viewHolder.adapterPosition)
}

View File

@ -28,10 +28,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
import pl.szczodrzynski.edziennik.databinding.FragmentHomeBinding
import pl.szczodrzynski.edziennik.onClick
import pl.szczodrzynski.edziennik.ui.dialogs.home.StudentNumberDialog
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeEventsCard
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeGradesCard
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeLuckyNumberCard
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeTimetableCard
import pl.szczodrzynski.edziennik.ui.modules.home.cards.*
import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
@ -44,8 +41,8 @@ class HomeFragment : Fragment(), CoroutineScope {
fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter): Boolean {
val fromCard = cardAdapter.items[fromPosition]
val toCard = cardAdapter.items[toPosition]
if (fromCard.id == 100 || toCard.id == 100) {
// debug card is not swappable
if (fromCard.id >= 100 || toCard.id >= 100) {
// debug & archive cards are not swappable
return false
}
cardAdapter.items[fromPosition] = cardAdapter.items[toPosition]
@ -60,10 +57,16 @@ class HomeFragment : Fragment(), CoroutineScope {
return true
}
fun removeCard(position: Int) {
fun removeCard(position: Int, cardAdapter: HomeCardAdapter) {
val homeCards = App.config.forProfile().ui.homeCards.toMutableList()
if (position >= homeCards.size)
return
val card = cardAdapter.items[position]
if (card.id >= 100) {
// debug & archive cards are not removable
cardAdapter.notifyDataSetChanged()
return
}
homeCards.removeAt(position)
App.config.forProfile().ui.homeCards = homeCards
}
@ -160,6 +163,8 @@ class HomeFragment : Fragment(), CoroutineScope {
}
//if (App.devMode)
// items += HomeDebugCard(100, app, activity, this, app.profile)
if (app.profile.archived)
items.add(0, HomeArchiveCard(101, app, activity, this, app.profile))
val adapter = HomeCardAdapter(items)
val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter, b.refreshLayout))

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-8-25.
*/
package pl.szczodrzynski.edziennik.ui.modules.home.cards
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.view.plusAssign
import androidx.core.view.setMargins
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.databinding.CardHomeArchiveBinding
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardAdapter
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
import kotlin.coroutines.CoroutineContext
class HomeArchiveCard(
override val id: Int,
val app: App,
val activity: MainActivity,
val fragment: HomeFragment,
val profile: Profile
) : HomeCard, CoroutineScope {
companion object {
private const val TAG = "HomeArchiveCard"
}
private var job: Job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
override fun bind(position: Int, holder: HomeCardAdapter.ViewHolder) {
holder.root.removeAllViews()
val b = CardHomeArchiveBinding.inflate(LayoutInflater.from(holder.root.context))
b.root.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT).apply {
setMargins(8.dp)
}
holder.root += b.root
b.homeArchiveText.setText(
R.string.home_archive_text,
profile.studentSchoolYearStart,
profile.studentSchoolYearStart + 1
)
b.homeArchiveClose.onClick {
launch {
val profile = profile.archiveId?.let {
withContext(Dispatchers.IO) {
app.db.profileDao().getNotArchivedOf(it)
}
}
if (profile == null) {
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.home_archive_close_no_target_title)
.setMessage(R.string.home_archive_close_no_target_text, this@HomeArchiveCard.profile.name)
.setPositiveButton(R.string.ok) { _, _ ->
activity.drawer.profileSelectionOpen()
activity.drawer.open()
}
.show()
return@launch
}
activity.loadProfile(profile)
}
}
holder.root.onClick {
activity.loadTarget(MainActivity.DRAWER_ITEM_AGENDA)
}
}
override fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder) = Unit
}