diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt index b3772fd9..6bd6934a 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt @@ -43,10 +43,7 @@ import pl.szczodrzynski.edziennik.sync.SyncWorker import pl.szczodrzynski.edziennik.sync.UpdateWorker import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity import pl.szczodrzynski.edziennik.utils.* -import pl.szczodrzynski.edziennik.utils.managers.GradesManager -import pl.szczodrzynski.edziennik.utils.managers.NotificationChannelsManager -import pl.szczodrzynski.edziennik.utils.managers.TimetableManager -import pl.szczodrzynski.edziennik.utils.managers.UserActionManager +import pl.szczodrzynski.edziennik.utils.managers.* import java.util.concurrent.TimeUnit import kotlin.coroutines.CoroutineContext @@ -67,6 +64,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope { val userActionManager by lazy { UserActionManager(this) } val gradesManager by lazy { GradesManager(this) } val timetableManager by lazy { TimetableManager(this) } + val eventManager by lazy { EventManager(this) } val db get() = App.db diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index 47a951fd..5a39dec5 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -55,9 +55,10 @@ import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog 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.base.MainSnackbar import pl.szczodrzynski.edziennik.ui.modules.behaviour.BehaviourFragment +import pl.szczodrzynski.edziennik.ui.modules.debug.DebugFragment +import pl.szczodrzynski.edziennik.ui.modules.debug.LabFragment import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment @@ -73,7 +74,6 @@ import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesListFragment import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsListFragment import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsNewFragment -import pl.szczodrzynski.edziennik.ui.modules.template.TemplateFragment import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment import pl.szczodrzynski.edziennik.ui.modules.webpush.WebPushFragment import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch @@ -130,7 +130,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { const val TARGET_MESSAGES_DETAILS = 503 const val TARGET_MESSAGES_COMPOSE = 504 const val TARGET_WEB_PUSH = 140 - const val TARGET_TEMPLATE = 1000 + const val TARGET_LAB = 1000 const val HOME_ID = DRAWER_ITEM_HOME @@ -230,8 +230,8 @@ class MainActivity : AppCompatActivity(), CoroutineScope { list += NavTarget(TARGET_WEB_PUSH, R.string.menu_web_push, WebPushFragment::class) list += NavTarget(DRAWER_ITEM_DEBUG, R.string.menu_debug, DebugFragment::class) if (App.devMode) { - list += NavTarget(TARGET_TEMPLATE, R.string.menu_template, TemplateFragment::class) - .withIcon(CommunityMaterial.Icon2.cmd_test_tube_empty) + list += NavTarget(TARGET_LAB, R.string.menu_lab, LabFragment::class) + .withIcon(CommunityMaterial.Icon.cmd_flask_outline) .isInDrawer(true) .isBelowSeparator(true) .isStatic(true) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Event.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Event.kt index 4869903f..b811ff61 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Event.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Event.kt @@ -93,7 +93,7 @@ open class Event( var attachmentNames: MutableList? = null @Ignore - var showAsUnseen = false + var showAsUnseen: Boolean? = null val startTimeCalendar: Calendar get() = Calendar.getInstance().also { it.set( diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/day/DayDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/day/DayDialog.kt index 12b7c71a..03cc4879 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/day/DayDialog.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/day/DayDialog.kt @@ -151,6 +151,7 @@ class DayDialog( showType = true, showTime = true, showSubject = true, + markAsSeen = true, onItemClick = { EventDetailsDialog( activity, diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventListAdapter.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventListAdapter.kt index cf63e4ea..34cc6a2d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventListAdapter.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventListAdapter.kt @@ -9,11 +9,15 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.databinding.EventListItemBinding import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Week +import kotlin.coroutines.CoroutineContext class EventListAdapter( val context: Context, @@ -23,11 +27,17 @@ class EventListAdapter( val showType: Boolean = true, val showTime: Boolean = true, val showSubject: Boolean = true, + val markAsSeen: Boolean = true, val onItemClick: ((event: EventFull) -> Unit)? = null, val onEventEditClick: ((event: EventFull) -> Unit)? = null -) : RecyclerView.Adapter() { +) : RecyclerView.Adapter(), CoroutineScope { - private val app by lazy { context.applicationContext as App } + private val app = context.applicationContext as App + private val manager = app.eventManager + + private val job = Job() + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main var items = listOf() @@ -40,9 +50,17 @@ class EventListAdapter( override fun onBindViewHolder(holder: ViewHolder, position: Int) { val event = items[position] val b = holder.b + val manager = app.eventManager b.root.onClick { onItemClick?.invoke(event) + if (!event.seen) { + manager.markAsSeen(event) + } + if (event.showAsUnseen == true) { + event.showAsUnseen = false + notifyItemChanged(event) + } } val bullet = " • " @@ -85,6 +103,22 @@ class EventListAdapter( b.editButton.attachToastHint(R.string.hint_edit_event) b.isDone.isVisible = event.isDone + + if (event.showAsUnseen == null) + event.showAsUnseen = !event.seen + + b.unread.isVisible = event.showAsUnseen == true + if (markAsSeen && !event.seen) { + manager.markAsSeen(event) + } + } + + private fun notifyItemChanged(model: Any) { + startCoroutineTimer(1000L, 0L) { + val index = items.indexOf(model) + if (index != -1) + notifyItemChanged(index) + } } override fun getItemCount() = items.size diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/LessonDetailsDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/LessonDetailsDialog.kt index 51b0eb03..6dc6edb6 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/LessonDetailsDialog.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/LessonDetailsDialog.kt @@ -175,6 +175,7 @@ class LessonDetailsDialog( showType = true, showTime = true, showSubject = true, + markAsSeen = true, onItemClick = { EventDetailsDialog( activity, diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/DebugFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/DebugFragment.java similarity index 98% rename from app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/DebugFragment.java rename to app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/DebugFragment.java index 57a4e00f..63ef7f51 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/DebugFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/DebugFragment.java @@ -1,4 +1,8 @@ -package pl.szczodrzynski.edziennik.ui.modules.base; +/* + * Copyright (c) Kuba Szczodrzyński 2020-4-3. + */ + +package pl.szczodrzynski.edziennik.ui.modules.debug; import android.os.Bundle; import android.util.Log; diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt new file mode 100644 index 00000000..7fbea1a6 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2020-4-3. + */ + +package pl.szczodrzynski.edziennik.ui.modules.debug + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.MainActivity +import pl.szczodrzynski.edziennik.data.db.entity.Event +import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding +import pl.szczodrzynski.edziennik.onClick +import kotlin.coroutines.CoroutineContext + +class LabFragment : Fragment(), CoroutineScope { + companion object { + private const val TAG = "LabFragment" + } + + private lateinit var app: App + private lateinit var activity: MainActivity + private lateinit var b: LabFragmentBinding + + private val job: Job = Job() + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main + + // local/private variables go here + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + activity = (getActivity() as MainActivity?) ?: return null + context ?: return null + app = activity.application as App + b = LabFragmentBinding.inflate(inflater) + return b.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + if (!isAdded) return + + b.last10unseen.onClick { + launch(Dispatchers.Default) { + val events = app.db.eventDao().getAllNow(App.profileId) + val ids = events.sortedBy { it.date }.filter { it.type == Event.TYPE_HOMEWORK }.takeLast(10) + ids.forEach { + app.db.metadataDao().setSeen(App.profileId, it, false) + } + } + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeEventsCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeEventsCard.kt index b0c8ec79..9a831c0f 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeEventsCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeEventsCard.kt @@ -65,6 +65,7 @@ class HomeEventsCard( showType = true, showTime = false, showSubject = false, + markAsSeen = false, onItemClick = { EventDetailsDialog( activity, diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/homework/HomeworkListFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/homework/HomeworkListFragment.kt index ba02cb6d..525d31c5 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/homework/HomeworkListFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/homework/HomeworkListFragment.kt @@ -60,6 +60,7 @@ class HomeworkListFragment : LazyFragment(), CoroutineScope { showType = false, showTime = true, showSubject = true, + markAsSeen = true, onItemClick = { EventDetailsDialog( activity, diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/EventManager.kt b/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/EventManager.kt new file mode 100644 index 00000000..ca444ca5 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/EventManager.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2020-4-3. + */ + +package pl.szczodrzynski.edziennik.utils.managers + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.data.db.full.EventFull +import pl.szczodrzynski.edziennik.startCoroutineTimer +import kotlin.coroutines.CoroutineContext + +class EventManager(val app: App) : CoroutineScope { + + private val job = Job() + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Default + + /* _ _ _____ _____ _ __ _ + | | | |_ _| / ____| (_)/ _(_) + | | | | | | | (___ _ __ ___ ___ _| |_ _ ___ + | | | | | | \___ \| '_ \ / _ \/ __| | _| |/ __| + | |__| |_| |_ ____) | |_) | __/ (__| | | | | (__ + \____/|_____| |_____/| .__/ \___|\___|_|_| |_|\___| + | | + |*/ + fun markAsSeen(event: EventFull) { + event.seen = true + startCoroutineTimer(500L, 0L) { + app.db.metadataDao().setSeen(event.profileId, event, true) + } + } +} diff --git a/app/src/main/res/layout/event_list_item.xml b/app/src/main/res/layout/event_list_item.xml index 62c0922e..295ffdc2 100644 --- a/app/src/main/res/layout/event_list_item.xml +++ b/app/src/main/res/layout/event_list_item.xml @@ -36,13 +36,23 @@ + + diff --git a/app/src/main/res/layout/fragment_debug.xml b/app/src/main/res/layout/fragment_debug.xml index 6dd2413c..2fecffa5 100644 --- a/app/src/main/res/layout/fragment_debug.xml +++ b/app/src/main/res/layout/fragment_debug.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.modules.base.DebugFragment"> + tools:context=".ui.modules.debug.DebugFragment"> + + + + + + + + + + + + +