Added announcement list screen
This commit is contained in:
@@ -8,6 +8,7 @@ import androidx.navigation.navArgument
|
||||
import de.sebse.fuplanner2.ui.courses.CoursesScreen
|
||||
import de.sebse.fuplanner2.ui.details.CourseDetailsScreen
|
||||
import de.sebse.fuplanner2.ui.details_announcements.CourseAnnouncementScreen
|
||||
import de.sebse.fuplanner2.ui.details_announcements.CourseAnnouncementsScreen
|
||||
import de.sebse.fuplanner2.ui.details_description.CourseDescriptionScreen
|
||||
|
||||
sealed class MenuItem {
|
||||
@@ -53,6 +54,15 @@ fun MainActivityComposable() {
|
||||
val id = it.arguments!!.getLong("id")
|
||||
CourseDescriptionScreen(tools, id)
|
||||
}
|
||||
composable(
|
||||
arguments = listOf(
|
||||
navArgument("id") { type = NavType.LongType }
|
||||
),
|
||||
route = "${MenuItem.Courses.route}/{id}/announcements"
|
||||
) {
|
||||
val id = it.arguments!!.getLong("id")
|
||||
CourseAnnouncementsScreen(tools, id)
|
||||
}
|
||||
composable(
|
||||
arguments = listOf(
|
||||
navArgument("id") { type = NavType.LongType },
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.sebse.fuplanner2.ui.details
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -91,7 +92,8 @@ fun CourseDetailsScreen(
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(showBackground = true)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
|
||||
@Composable
|
||||
fun CourseDetailsScreenPreview(@PreviewParameter(CoursePreviewProvider::class, 1) course: Course) {
|
||||
AppTheme {
|
||||
|
||||
@@ -14,11 +14,6 @@ import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||
import de.sebse.fuplanner2.ui.tools.previews.AnnouncementPreviewProvider
|
||||
import de.sebse.fuplanner2.utils.toDateTimeString
|
||||
|
||||
@Composable
|
||||
fun AnnouncementItem(announcement: Announcement) {
|
||||
AnnouncementItem(announcement) { }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AnnouncementItem(announcement: Announcement, click: () -> Unit) {
|
||||
FuCardColumn(
|
||||
@@ -40,6 +35,6 @@ fun AnnouncementItem(announcement: Announcement, click: () -> Unit) {
|
||||
@Composable
|
||||
fun AnnouncementItemPreview(@PreviewParameter(AnnouncementPreviewProvider::class, 5) announcement: Announcement) {
|
||||
AppTheme {
|
||||
AnnouncementItem(announcement)
|
||||
AnnouncementItem(announcement) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package de.sebse.fuplanner2.ui.details.components
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.GridCells
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.ButtonDefaults.buttonColors
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -37,28 +38,28 @@ fun QuickLinks(courseId: Long, onClick: (String) -> Unit) {
|
||||
cells = GridCells.Adaptive(150.dp)
|
||||
) {
|
||||
list.forEach {
|
||||
Card(
|
||||
backgroundColor = MaterialTheme.colors.secondary,
|
||||
Button(
|
||||
colors = buttonColors(
|
||||
backgroundColor = MaterialTheme.colors.secondary,
|
||||
contentColor = MaterialTheme.colors.onSecondary,
|
||||
),
|
||||
modifier = Modifier
|
||||
.padding(dimensionResource(R.dimen.card_view_margin))
|
||||
.fillMaxWidth()
|
||||
.clickable { onClick(it.route) },
|
||||
elevation = dimensionResource(R.dimen.card_view_elevation),
|
||||
.fillMaxWidth(),
|
||||
onClick = { onClick(it.route) }
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(it.name),
|
||||
color = MaterialTheme.colors.onSecondary,
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.h6,
|
||||
modifier = Modifier
|
||||
.padding(dimensionResource(R.dimen.card_view_padding))
|
||||
style = MaterialTheme.typography.h6
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(showBackground = true)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
|
||||
@Composable
|
||||
fun QuickLinksPreview() {
|
||||
AppTheme {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package de.sebse.fuplanner2.ui.details_announcements
|
||||
|
||||
import android.view.ViewGroup
|
||||
import androidx.paging.PagedListAdapter
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import de.sebse.fuplanner2.database.Announcement
|
||||
import de.sebse.fuplanner2.ui.ListItemHolder
|
||||
import de.sebse.fuplanner2.utils.toDateTimeString
|
||||
|
||||
class AnnouncementsAdapter() : PagedListAdapter<Announcement, ListItemHolder>(EventDiffCallback()) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemHolder {
|
||||
return ListItemHolder.invoke(parent)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ListItemHolder, position: Int) {
|
||||
val event = getItem(position)
|
||||
val actCtx = holder.itemView.context
|
||||
|
||||
event?.let {
|
||||
holder.title.text = it.title
|
||||
holder.subLeft.text = it.createdOn.toDateTimeString(actCtx)
|
||||
holder.subRight.text = it.createdBy
|
||||
} ?: run {
|
||||
holder.clear()
|
||||
holder.itemView.setOnClickListener(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EventDiffCallback : DiffUtil.ItemCallback<Announcement>() {
|
||||
|
||||
override fun areItemsTheSame(oldItem: Announcement, newItem: Announcement): Boolean {
|
||||
return oldItem.uid == newItem.uid
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: Announcement, newItem: Announcement): Boolean {
|
||||
return oldItem.getHash() == newItem.getHash()
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package de.sebse.fuplanner2.ui.details_announcements
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.work.workDataOf
|
||||
import de.sebse.fuplanner2.R
|
||||
import de.sebse.fuplanner2.auth.AppAccounts
|
||||
import de.sebse.fuplanner2.databinding.FragmentRefreshRecyclerBinding
|
||||
import de.sebse.fuplanner2.utils.console
|
||||
import de.sebse.fuplanner2.utils.enqueueOneTimeWork
|
||||
import de.sebse.fuplanner2.worker.AbstractAccountWorker.Companion.KEY_ACCOUNT_NAME
|
||||
import de.sebse.fuplanner2.worker.AbstractAccountWorker.Companion.KEY_COURSE_ID
|
||||
import de.sebse.fuplanner2.worker.AnnouncementWorker
|
||||
|
||||
class AnnouncementsFragment : Fragment() {
|
||||
|
||||
private var title: String = ""
|
||||
private val args: AnnouncementsFragmentArgs by navArgs()
|
||||
private val announcementsViewModel: AnnouncementsViewModel by viewModels { AnnouncementsViewModelFactory(args.courseId) }
|
||||
private lateinit var navController: NavController
|
||||
private lateinit var binding: FragmentRefreshRecyclerBinding
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val viewManager = LinearLayoutManager(context)
|
||||
val viewAdapter = AnnouncementsAdapter()
|
||||
return inflater.inflate(R.layout.fragment_refresh_recycler, container, false).apply {
|
||||
console.log(findViewById(R.id.recycler_view), binding.recyclerView)
|
||||
binding.recyclerView.apply {
|
||||
setHasFixedSize(true)
|
||||
|
||||
layoutManager = viewManager
|
||||
adapter = viewAdapter
|
||||
}
|
||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||
enqueueOneTimeWork<AnnouncementWorker>(context.applicationContext) {
|
||||
it.setInputData(workDataOf(
|
||||
KEY_ACCOUNT_NAME to AppAccounts.getInstance().selectedAccount?.name,
|
||||
KEY_COURSE_ID to args.courseId
|
||||
))
|
||||
}.observe(viewLifecycleOwner, Observer {
|
||||
if (it.state.isFinished)
|
||||
binding.swipeRefreshLayout.isRefreshing = false
|
||||
})
|
||||
}
|
||||
announcementsViewModel.events.observe(viewLifecycleOwner, Observer {
|
||||
viewAdapter.submitList(it)
|
||||
this@AnnouncementsFragment.title = args.title
|
||||
})
|
||||
navController = findNavController()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package de.sebse.fuplanner2.ui.details_announcements
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import de.sebse.fuplanner2.database.Announcement
|
||||
import de.sebse.fuplanner2.database.AppDatabase
|
||||
|
||||
class AnnouncementsViewModelFactory(private val courseId: Long): ViewModelProvider.NewInstanceFactory() {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T = AnnouncementsViewModel(courseId) as T
|
||||
}
|
||||
|
||||
class AnnouncementsViewModel(private val courseId: Long) : ViewModel() {
|
||||
private val factory = AppDatabase.getInstance().announcementDao().getAll1(courseId)
|
||||
|
||||
val events: LiveData<PagedList<Announcement>> = LivePagedListBuilder(factory, 50).build()
|
||||
}
|
||||
@@ -16,11 +16,10 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.sebse.fuplanner2.R
|
||||
import de.sebse.fuplanner2.Tools
|
||||
import de.sebse.fuplanner2.database.Announcement
|
||||
import de.sebse.fuplanner2.database.Course
|
||||
import de.sebse.fuplanner2.ui.shared.Heading
|
||||
import de.sebse.fuplanner2.ui.shared.HtmlText
|
||||
import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||
import de.sebse.fuplanner2.ui.tools.previews.CoursePreviewProvider
|
||||
import de.sebse.fuplanner2.ui.tools.previews.AnnouncementPreviewProvider
|
||||
import de.sebse.fuplanner2.ui.tools.viewmodels.AnnouncementViewModel
|
||||
import de.sebse.fuplanner2.ui.tools.viewmodels.AnnouncementViewModelFactory
|
||||
import de.sebse.fuplanner2.ui.tools.viewmodels.DetailsViewModel
|
||||
@@ -57,10 +56,8 @@ fun CourseAnnouncementScreen(announcement: Announcement) {
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun CourseAnnouncementScreenPreview(@PreviewParameter(CoursePreviewProvider::class, 1) course: Course) {
|
||||
fun CourseAnnouncementScreenPreview(@PreviewParameter(AnnouncementPreviewProvider::class, 2) announcement: Announcement) {
|
||||
AppTheme {
|
||||
/*CourseAnnouncementScreen(
|
||||
"scrip<b>fsdfsfg</b><br><a href='example.com'>ti</a>on"
|
||||
)*/
|
||||
CourseAnnouncementScreen(announcement)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package de.sebse.fuplanner2.ui.details_announcements
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.sebse.fuplanner2.MenuItem
|
||||
import de.sebse.fuplanner2.R
|
||||
import de.sebse.fuplanner2.Tools
|
||||
import de.sebse.fuplanner2.database.Announcement
|
||||
import de.sebse.fuplanner2.ui.details.components.AnnouncementItem
|
||||
import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||
import de.sebse.fuplanner2.ui.tools.previews.AnnouncementPreviewProvider
|
||||
import de.sebse.fuplanner2.ui.tools.viewmodels.DetailsViewModel
|
||||
import de.sebse.fuplanner2.ui.tools.viewmodels.DetailsViewModelFactory
|
||||
|
||||
@Composable
|
||||
fun CourseAnnouncementsScreen(tools: Tools, id: Long) {
|
||||
val coursesViewModel: DetailsViewModel =
|
||||
viewModel(factory = DetailsViewModelFactory(id))
|
||||
val course by coursesViewModel.course.observeAsState()
|
||||
val announcements by coursesViewModel.announcements.observeAsState()
|
||||
val title = course?.title ?: stringResource(id = R.string.description)
|
||||
LaunchedEffect(title) {
|
||||
tools.setTitle(title)
|
||||
}
|
||||
announcements?.let { CourseAnnouncementsScreen(it) { uid ->
|
||||
tools.navTo("${MenuItem.Courses.route}/$id/announcements/${uid}")
|
||||
} }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CourseAnnouncementsScreen(announcements: List<Announcement>, onClick: (Long) -> Unit) {
|
||||
LazyColumn {
|
||||
items(announcements) {
|
||||
AnnouncementItem(it) {
|
||||
it.uid?.let { uid -> onClick(uid) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun CourseAnnouncementsScreenPreview() {
|
||||
AppTheme {
|
||||
CourseAnnouncementsScreen(
|
||||
AnnouncementPreviewProvider().values.take(10).toList()
|
||||
) { }
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ fun Heading(text: String, onClick: (() -> Unit)? = null) {
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.h5,
|
||||
color = MaterialTheme.colors.onSurface,
|
||||
modifier = Modifier
|
||||
.padding(top = dimensionResource(id = R.dimen.header_padding))
|
||||
)
|
||||
|
||||
@@ -27,18 +27,6 @@
|
||||
android:name="title"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/course_announcements"
|
||||
android:name="de.sebse.fuplanner2.ui.details_announcements.AnnouncementsFragment"
|
||||
android:label="{title}"
|
||||
tools:layout="@layout/fragment_refresh_recycler">
|
||||
<argument
|
||||
android:name="courseId"
|
||||
app:argType="long" />
|
||||
<argument
|
||||
android:name="title"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/nav_notifications"
|
||||
android:name="de.sebse.fuplanner2.ui.notification.NotificationFragment"
|
||||
|
||||
Reference in New Issue
Block a user