Add announcements to compose
This commit is contained in:
@@ -80,14 +80,14 @@ dependencies {
|
|||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
|
|
||||||
// Compose
|
// Compose
|
||||||
implementation "androidx.compose.runtime:runtime:$compose_version"
|
implementation "androidx.compose.runtime:runtime:1.0.5"
|
||||||
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
|
implementation "androidx.compose.runtime:runtime-livedata:1.0.5"
|
||||||
implementation "androidx.compose.ui:ui:$compose_version"
|
implementation "androidx.compose.ui:ui:1.0.5"
|
||||||
implementation "androidx.compose.ui:ui-tooling:$compose_version"
|
implementation "androidx.compose.ui:ui-tooling:1.0.5"
|
||||||
implementation "androidx.compose.foundation:foundation:$compose_version"
|
implementation "androidx.compose.foundation:foundation:1.0.5"
|
||||||
implementation "androidx.compose.foundation:foundation-layout:$compose_version"
|
implementation "androidx.compose.foundation:foundation-layout:1.0.5"
|
||||||
implementation "androidx.compose.material:material:$compose_version"
|
implementation "androidx.compose.material:material:1.0.5"
|
||||||
implementation "androidx.navigation:navigation-compose:2.4.0-beta02"
|
implementation "androidx.navigation:navigation-compose:2.4.0-beta02"
|
||||||
|
|
||||||
implementation "com.google.android.material:compose-theme-adapter:$compose_version"
|
implementation "com.google.android.material:compose-theme-adapter:1.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import androidx.lifecycle.LiveData
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import com.google.android.material.composethemeadapter.MdcTheme
|
|
||||||
import de.sebse.fuplanner2.auth.AppAccounts
|
import de.sebse.fuplanner2.auth.AppAccounts
|
||||||
import de.sebse.fuplanner2.database.AppDatabase
|
import de.sebse.fuplanner2.database.AppDatabase
|
||||||
import de.sebse.fuplanner2.database.Course
|
import de.sebse.fuplanner2.database.Course
|
||||||
import de.sebse.fuplanner2.database.User
|
import de.sebse.fuplanner2.database.User
|
||||||
|
import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class MainActivity() : AppCompatActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
activityViewModel = ViewModelProvider(this)[MainActivityViewModel::class.java]
|
activityViewModel = ViewModelProvider(this)[MainActivityViewModel::class.java]
|
||||||
setContent {
|
setContent {
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
MainActivityComposable()
|
MainActivityComposable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package de.sebse.fuplanner2.database
|
package de.sebse.fuplanner2.database
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.paging.DataSource
|
import androidx.paging.DataSource
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import de.sebse.fuplanner2.utils.console
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface AnnouncementDao {
|
interface AnnouncementDao {
|
||||||
@@ -12,6 +12,9 @@ interface AnnouncementDao {
|
|||||||
@Query("SELECT * FROM announcement WHERE courseId = :courseId ORDER BY createdOn ASC")
|
@Query("SELECT * FROM announcement WHERE courseId = :courseId ORDER BY createdOn ASC")
|
||||||
fun getAll2(courseId: Long): List<Announcement>
|
fun getAll2(courseId: Long): List<Announcement>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM announcement WHERE courseId = :courseId ORDER BY createdOn ASC")
|
||||||
|
fun getAll3(courseId: Long): LiveData<List<Announcement>>
|
||||||
|
|
||||||
@Query("SELECT * FROM announcement WHERE uid = :announcementId LIMIT 1")
|
@Query("SELECT * FROM announcement WHERE uid = :announcementId LIMIT 1")
|
||||||
fun getAnnouncementById(announcementId: Long): Announcement
|
fun getAnnouncementById(announcementId: Long): Announcement
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import androidx.navigation.NavHostController
|
|||||||
import androidx.navigation.NavOptions
|
import androidx.navigation.NavOptions
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.google.android.material.composethemeadapter.MdcTheme
|
import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ fun DrawerItems(currentRoute: String?, menu: List<NavLinks>, onItemClick: (route
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun TopBarPreview() {
|
fun TopBarPreview() {
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
TopBar(
|
TopBar(
|
||||||
title = "A title"
|
title = "A title"
|
||||||
) { }
|
) { }
|
||||||
@@ -150,7 +150,7 @@ fun TopBarPreview() {
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun DrawerPreview() {
|
fun DrawerPreview() {
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
Drawer(currentRoute = "courses", menu = screens) { }
|
Drawer(currentRoute = "courses", menu = screens) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,14 +31,14 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
|
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
|
||||||
import com.google.android.material.composethemeadapter.MdcTheme
|
|
||||||
import de.sebse.fuplanner2.MenuItem
|
import de.sebse.fuplanner2.MenuItem
|
||||||
import de.sebse.fuplanner2.R
|
import de.sebse.fuplanner2.R
|
||||||
import de.sebse.fuplanner2.Tools
|
import de.sebse.fuplanner2.Tools
|
||||||
import de.sebse.fuplanner2.database.Course
|
import de.sebse.fuplanner2.database.Course
|
||||||
import de.sebse.fuplanner2.ui.details.CoursePreviewProvider
|
import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||||
|
import de.sebse.fuplanner2.ui.tools.previews.CoursePreviewProvider
|
||||||
|
import de.sebse.fuplanner2.ui.tools.viewmodels.CoursesViewModel
|
||||||
import de.sebse.fuplanner2.utils.color.getColor
|
import de.sebse.fuplanner2.utils.color.getColor
|
||||||
import de.sebse.fuplanner2.viewmodels.CoursesViewModel
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CoursesScreen(tools: Tools) {
|
fun CoursesScreen(tools: Tools) {
|
||||||
@@ -54,7 +54,7 @@ fun CoursesScreen(tools: Tools) {
|
|||||||
LaunchedEffect(title) {
|
LaunchedEffect(title) {
|
||||||
tools.setTitle(title)
|
tools.setTitle(title)
|
||||||
}
|
}
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
GroupedCourseList(groups = groups) { course ->
|
GroupedCourseList(groups = groups) { course ->
|
||||||
course.uid?.let {
|
course.uid?.let {
|
||||||
Log.d("WHERE TO GO", "${MenuItem.Courses.route}/$it")
|
Log.d("WHERE TO GO", "${MenuItem.Courses.route}/$it")
|
||||||
@@ -163,7 +163,7 @@ fun CourseItemHint(icon: ImageVector, @StringRes imageAltRes: Int, text: String)
|
|||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
@Composable
|
@Composable
|
||||||
fun CourseListPreview() {
|
fun CourseListPreview() {
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
CourseList(
|
CourseList(
|
||||||
CoursePreviewProvider().values.take(3).toList()
|
CoursePreviewProvider().values.take(3).toList()
|
||||||
) { }
|
) { }
|
||||||
@@ -174,7 +174,7 @@ fun CourseListPreview() {
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun CourseItemPreview(@PreviewParameter(CoursePreviewProvider::class, 1) course: Course) {
|
fun CourseItemPreview(@PreviewParameter(CoursePreviewProvider::class, 1) course: Course) {
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
CourseItem(course) {}
|
CourseItem(course) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,27 +12,34 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.google.android.material.composethemeadapter.MdcTheme
|
|
||||||
import de.sebse.fuplanner2.R
|
import de.sebse.fuplanner2.R
|
||||||
import de.sebse.fuplanner2.Tools
|
import de.sebse.fuplanner2.Tools
|
||||||
|
import de.sebse.fuplanner2.database.Announcement
|
||||||
|
import de.sebse.fuplanner2.database.AppDatabase
|
||||||
import de.sebse.fuplanner2.database.Course
|
import de.sebse.fuplanner2.database.Course
|
||||||
|
import de.sebse.fuplanner2.ui.details.components.AnnouncementItem
|
||||||
|
import de.sebse.fuplanner2.ui.details.components.LecturerItem
|
||||||
import de.sebse.fuplanner2.ui.details.components.QuickLinks
|
import de.sebse.fuplanner2.ui.details.components.QuickLinks
|
||||||
import de.sebse.fuplanner2.viewmodels.DetailsViewModel
|
import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||||
import de.sebse.fuplanner2.viewmodels.DetailsViewModelFactory
|
import de.sebse.fuplanner2.ui.tools.previews.AnnouncementPreviewProvider
|
||||||
|
import de.sebse.fuplanner2.ui.tools.previews.CoursePreviewProvider
|
||||||
|
import de.sebse.fuplanner2.ui.tools.viewmodels.DetailsViewModel
|
||||||
|
import de.sebse.fuplanner2.ui.tools.viewmodels.DetailsViewModelFactory
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CourseDetailsScreen(tools: Tools, id: Long) {
|
fun CourseDetailsScreen(tools: Tools, id: Long) {
|
||||||
val coursesViewModel: DetailsViewModel = viewModel(factory = DetailsViewModelFactory(id))
|
val coursesViewModel: DetailsViewModel = viewModel(factory = DetailsViewModelFactory(id))
|
||||||
val state = coursesViewModel.course.observeAsState()
|
val state = coursesViewModel.course.observeAsState()
|
||||||
|
val announce = AppDatabase.getInstance().announcementDao().getAll3(id).observeAsState()
|
||||||
val title = state.value?.title
|
val title = state.value?.title
|
||||||
LaunchedEffect(title) {
|
LaunchedEffect(title) {
|
||||||
title?.let { tools.setTitle(it) }
|
title?.let { tools.setTitle(it) }
|
||||||
}
|
}
|
||||||
CourseDetailsScreen(state.value, id)
|
CourseDetailsScreen(state.value, announce.value, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CourseDetailsScreen(course: Course?, id: Long) {
|
fun CourseDetailsScreen(course: Course?, announcement: List<Announcement>?, id: Long) {
|
||||||
Column {
|
Column {
|
||||||
QuickLinks(courseId = id)
|
QuickLinks(courseId = id)
|
||||||
Text(
|
Text(
|
||||||
@@ -44,6 +51,15 @@ fun CourseDetailsScreen(course: Course?, id: Long) {
|
|||||||
LecturerItem(lecturer = it, courseTitle = course?.title ?: "")
|
LecturerItem(lecturer = it, courseTitle = course?.title ?: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.announcements),
|
||||||
|
style = MaterialTheme.typography.h5
|
||||||
|
)
|
||||||
|
LazyColumn {
|
||||||
|
items(announcement ?: listOf()) {
|
||||||
|
AnnouncementItem(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO: Add latest announcements, current assignments, upcoming events
|
// TODO: Add latest announcements, current assignments, upcoming events
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +67,7 @@ fun CourseDetailsScreen(course: Course?, id: Long) {
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun CourseDetailsScreenPreview(@PreviewParameter(CoursePreviewProvider::class, 1) course: Course) {
|
fun CourseDetailsScreenPreview(@PreviewParameter(CoursePreviewProvider::class, 1) course: Course) {
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
CourseDetailsScreen(course, course.uid!!)
|
CourseDetailsScreen(course, AnnouncementPreviewProvider().values.take(3).toList(), course.uid!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package de.sebse.fuplanner2.ui.details.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.Card
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.dimensionResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
|
import de.sebse.fuplanner2.R
|
||||||
|
import de.sebse.fuplanner2.database.Announcement
|
||||||
|
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) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(dimensionResource(R.dimen.card_view_margin)),
|
||||||
|
elevation = dimensionResource(R.dimen.card_view_elevation)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable(true, onClick = click)
|
||||||
|
.padding(dimensionResource(R.dimen.card_view_padding))
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = announcement.title ?: "Title",
|
||||||
|
style = MaterialTheme.typography.h6
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = announcement.createdOn.toDateTimeString(LocalContext.current) ?: "",
|
||||||
|
style = MaterialTheme.typography.subtitle1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun AnnouncementItemPreview(@PreviewParameter(AnnouncementPreviewProvider::class, 5) announcement: Announcement) {
|
||||||
|
AppTheme {
|
||||||
|
AnnouncementItem(announcement)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package de.sebse.fuplanner2.ui.details
|
package de.sebse.fuplanner2.ui.details.components
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -21,9 +21,10 @@ import androidx.compose.ui.text.style.TextDecoration
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.google.android.material.composethemeadapter.MdcTheme
|
|
||||||
import de.sebse.fuplanner2.R
|
import de.sebse.fuplanner2.R
|
||||||
import de.sebse.fuplanner2.database.Lecturer
|
import de.sebse.fuplanner2.database.Lecturer
|
||||||
|
import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||||
|
import de.sebse.fuplanner2.ui.tools.previews.LecturerPreviewProvider
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LecturerItem(lecturer: Lecturer, courseTitle: String) {
|
fun LecturerItem(lecturer: Lecturer, courseTitle: String) {
|
||||||
@@ -84,8 +85,8 @@ fun LecturerItem(lecturer: Lecturer, click: () -> Unit) {
|
|||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun LecturerItemPreview(@PreviewParameter(LecturerPreviewProvider::class, 2) lecturer: Lecturer) {
|
fun LecturerItemPreview(@PreviewParameter(LecturerPreviewProvider::class, 3) lecturer: Lecturer) {
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
LecturerItem(lecturer, "Course Name")
|
LecturerItem(lecturer, "Course Name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.google.android.material.composethemeadapter.MdcTheme
|
|
||||||
import de.sebse.fuplanner2.R
|
import de.sebse.fuplanner2.R
|
||||||
|
import de.sebse.fuplanner2.ui.theme.AppTheme
|
||||||
|
|
||||||
|
|
||||||
data class QuickLinkProps(@StringRes val name: Int, val route: String)
|
data class QuickLinkProps(@StringRes val name: Int, val route: String)
|
||||||
@@ -64,7 +64,7 @@ fun QuickLinks(courseId: Long) {
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun QuickLinksPreview() {
|
fun QuickLinksPreview() {
|
||||||
MdcTheme {
|
AppTheme {
|
||||||
QuickLinks(3)
|
QuickLinks(3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,34 @@
|
|||||||
package de.sebse.fuplanner2.ui.details_announcements
|
package de.sebse.fuplanner2.ui.details_announcements
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.paging.LivePagedListBuilder
|
import androidx.paging.LivePagedListBuilder
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import de.sebse.fuplanner2.auth.AppAccounts
|
||||||
import de.sebse.fuplanner2.database.Announcement
|
import de.sebse.fuplanner2.database.Announcement
|
||||||
import de.sebse.fuplanner2.database.AppDatabase
|
import de.sebse.fuplanner2.database.AppDatabase
|
||||||
|
import de.sebse.fuplanner2.utils.enqueueOneTimeWork
|
||||||
|
import de.sebse.fuplanner2.worker.AbstractAccountWorker
|
||||||
|
import de.sebse.fuplanner2.worker.AnnouncementWorker
|
||||||
|
|
||||||
class AnnouncementsViewModelFactory(private val courseId: Long): ViewModelProvider.NewInstanceFactory() {
|
class AnnouncementsViewModelFactory(private val courseId: Long): ViewModelProvider.NewInstanceFactory() {
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T = AnnouncementsViewModel(courseId) as T
|
override fun <T : ViewModel> create(modelClass: Class<T>): T = AnnouncementsViewModel(courseId) as T
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnnouncementsViewModel(courseId: Long) : ViewModel() {
|
class AnnouncementsViewModel(private val courseId: Long) : ViewModel() {
|
||||||
private val factory = AppDatabase.getInstance().announcementDao().getAll1(courseId)
|
private val factory = AppDatabase.getInstance().announcementDao().getAll1(courseId)
|
||||||
|
|
||||||
|
fun refresh(ctx: Context) {
|
||||||
|
enqueueOneTimeWork<AnnouncementWorker>(ctx) {
|
||||||
|
it.setInputData(workDataOf(
|
||||||
|
AbstractAccountWorker.KEY_ACCOUNT_NAME to AppAccounts.getInstance().selectedAccount?.name,
|
||||||
|
AbstractAccountWorker.KEY_COURSE_ID to courseId
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val events: LiveData<PagedList<Announcement>> = LivePagedListBuilder(factory, 50).build()
|
val events: LiveData<PagedList<Announcement>> = LivePagedListBuilder(factory, 50).build()
|
||||||
}
|
}
|
||||||
@@ -15,8 +15,8 @@ import androidx.navigation.fragment.findNavController
|
|||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import de.sebse.fuplanner2.R
|
import de.sebse.fuplanner2.R
|
||||||
import de.sebse.fuplanner2.databinding.FragmentDescriptionBinding
|
import de.sebse.fuplanner2.databinding.FragmentDescriptionBinding
|
||||||
import de.sebse.fuplanner2.viewmodels.DetailsViewModel
|
import de.sebse.fuplanner2.ui.tools.viewmodels.DetailsViewModel
|
||||||
import de.sebse.fuplanner2.viewmodels.DetailsViewModelFactory
|
import de.sebse.fuplanner2.ui.tools.viewmodels.DetailsViewModelFactory
|
||||||
|
|
||||||
|
|
||||||
class DescriptionFragment : Fragment() {
|
class DescriptionFragment : Fragment() {
|
||||||
|
|||||||
58
app/src/main/java/de/sebse/fuplanner2/ui/theme/Color.kt
Normal file
58
app/src/main/java/de/sebse/fuplanner2/ui/theme/Color.kt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package de.sebse.fuplanner2.ui.theme
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
|
||||||
|
val md_theme_light_primary = Color(0xFF245fa7)
|
||||||
|
val md_theme_light_onPrimary = Color(0xFFffffff)
|
||||||
|
val md_theme_light_primaryContainer = Color(0xFFd4e3ff)
|
||||||
|
val md_theme_light_onPrimaryContainer = Color(0xFF001b3d)
|
||||||
|
val md_theme_light_secondary = Color(0xFF4a6800)
|
||||||
|
val md_theme_light_onSecondary = Color(0xFFffffff)
|
||||||
|
val md_theme_light_secondaryContainer = Color(0xFFbef43c)
|
||||||
|
val md_theme_light_onSecondaryContainer = Color(0xFF131f00)
|
||||||
|
val md_theme_light_tertiary = Color(0xFF8b5000)
|
||||||
|
val md_theme_light_onTertiary = Color(0xFFffffff)
|
||||||
|
val md_theme_light_tertiaryContainer = Color(0xFFffdcba)
|
||||||
|
val md_theme_light_onTertiaryContainer = Color(0xFF2d1600)
|
||||||
|
val md_theme_light_error = Color(0xFFba1b1b)
|
||||||
|
val md_theme_light_errorContainer = Color(0xFFffdad4)
|
||||||
|
val md_theme_light_onError = Color(0xFFffffff)
|
||||||
|
val md_theme_light_onErrorContainer = Color(0xFF410001)
|
||||||
|
val md_theme_light_background = Color(0xFFfdfbff)
|
||||||
|
val md_theme_light_onBackground = Color(0xFF1b1b1d)
|
||||||
|
val md_theme_light_surface = Color(0xFFfdfbff)
|
||||||
|
val md_theme_light_onSurface = Color(0xFF1b1b1d)
|
||||||
|
val md_theme_light_surfaceVariant = Color(0xFFe0e2eb)
|
||||||
|
val md_theme_light_onSurfaceVariant = Color(0xFF44474f)
|
||||||
|
val md_theme_light_outline = Color(0xFF74777f)
|
||||||
|
val md_theme_light_inverseOnSurface = Color(0xFFf1f0f4)
|
||||||
|
val md_theme_light_inverseSurface = Color(0xFF2f3033)
|
||||||
|
|
||||||
|
val md_theme_dark_primary = Color(0xFFa6c8ff)
|
||||||
|
val md_theme_dark_onPrimary = Color(0xFF003063)
|
||||||
|
val md_theme_dark_primaryContainer = Color(0xFF00468b)
|
||||||
|
val md_theme_dark_onPrimaryContainer = Color(0xFFd4e3ff)
|
||||||
|
val md_theme_dark_secondary = Color(0xFFa3d719)
|
||||||
|
val md_theme_dark_onSecondary = Color(0xFF253600)
|
||||||
|
val md_theme_dark_secondaryContainer = Color(0xFF374e00)
|
||||||
|
val md_theme_dark_onSecondaryContainer = Color(0xFFbef43c)
|
||||||
|
val md_theme_dark_tertiary = Color(0xFFffb86b)
|
||||||
|
val md_theme_dark_onTertiary = Color(0xFF4a2800)
|
||||||
|
val md_theme_dark_tertiaryContainer = Color(0xFF6a3c00)
|
||||||
|
val md_theme_dark_onTertiaryContainer = Color(0xFFffdcba)
|
||||||
|
val md_theme_dark_error = Color(0xFFffb4a9)
|
||||||
|
val md_theme_dark_errorContainer = Color(0xFF930006)
|
||||||
|
val md_theme_dark_onError = Color(0xFF680003)
|
||||||
|
val md_theme_dark_onErrorContainer = Color(0xFFffdad4)
|
||||||
|
val md_theme_dark_background = Color(0xFF1b1b1d)
|
||||||
|
val md_theme_dark_onBackground = Color(0xFFe3e2e6)
|
||||||
|
val md_theme_dark_surface = Color(0xFF1b1b1d)
|
||||||
|
val md_theme_dark_onSurface = Color(0xFFe3e2e6)
|
||||||
|
val md_theme_dark_surfaceVariant = Color(0xFF44474f)
|
||||||
|
val md_theme_dark_onSurfaceVariant = Color(0xFFc3c6cf)
|
||||||
|
val md_theme_dark_outline = Color(0xFF8e919a)
|
||||||
|
val md_theme_dark_inverseOnSurface = Color(0xFF1b1b1d)
|
||||||
|
val md_theme_dark_inverseSurface = Color(0xFFe3e2e6)
|
||||||
|
|
||||||
|
val seed = Color(0xFF003366)
|
||||||
|
val error = Color(0xFFba1b1b)
|
||||||
102
app/src/main/java/de/sebse/fuplanner2/ui/theme/Theme.kt
Normal file
102
app/src/main/java/de/sebse/fuplanner2/ui/theme/Theme.kt
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package de.sebse.fuplanner2.ui.theme
|
||||||
|
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.darkColors
|
||||||
|
import androidx.compose.material.lightColors
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
// Comments are changes in Material 3 (Material You)
|
||||||
|
|
||||||
|
//private val LightThemeColors = lightColorScheme(
|
||||||
|
private val LightThemeColors = lightColors(
|
||||||
|
primary = md_theme_light_primary,
|
||||||
|
onPrimary = md_theme_light_onPrimary,
|
||||||
|
//primaryContainer = md_theme_light_primaryContainer,
|
||||||
|
//onPrimaryContainer = md_theme_light_onPrimaryContainer,
|
||||||
|
primaryVariant = md_theme_light_onPrimaryContainer,
|
||||||
|
|
||||||
|
secondary = md_theme_light_secondary,
|
||||||
|
onSecondary = md_theme_light_onSecondary,
|
||||||
|
//secondaryContainer = md_theme_light_secondaryContainer,
|
||||||
|
//onSecondaryContainer = md_theme_light_onSecondaryContainer,
|
||||||
|
secondaryVariant = md_theme_light_onSecondaryContainer,
|
||||||
|
|
||||||
|
//tertiary = md_theme_light_tertiary,
|
||||||
|
//onTertiary = md_theme_light_onTertiary,
|
||||||
|
//tertiaryContainer = md_theme_light_tertiaryContainer,
|
||||||
|
//onTertiaryContainer = md_theme_light_onTertiaryContainer,
|
||||||
|
|
||||||
|
error = md_theme_light_error,
|
||||||
|
onError = md_theme_light_onError,
|
||||||
|
//errorContainer = md_theme_light_errorContainer,
|
||||||
|
//onErrorContainer = md_theme_light_onErrorContainer,
|
||||||
|
|
||||||
|
background = md_theme_light_background,
|
||||||
|
onBackground = md_theme_light_onBackground,
|
||||||
|
|
||||||
|
surface = md_theme_light_surface,
|
||||||
|
onSurface = md_theme_light_onSurface,
|
||||||
|
//surfaceVariant = md_theme_light_surfaceVariant,
|
||||||
|
//onSurfaceVariant = md_theme_light_onSurfaceVariant,
|
||||||
|
|
||||||
|
//outline = md_theme_light_outline,
|
||||||
|
//inverseOnSurface = md_theme_light_inverseOnSurface,
|
||||||
|
//inverseSurface = md_theme_light_inverseSurface,
|
||||||
|
)
|
||||||
|
|
||||||
|
//private val DarkThemeColors = darkColorScheme(
|
||||||
|
private val DarkThemeColors = darkColors(
|
||||||
|
|
||||||
|
primary = md_theme_dark_primary,
|
||||||
|
onPrimary = md_theme_dark_onPrimary,
|
||||||
|
//primaryContainer = md_theme_dark_primaryContainer,
|
||||||
|
//onPrimaryContainer = md_theme_dark_onPrimaryContainer,
|
||||||
|
primaryVariant = md_theme_dark_onPrimaryContainer,
|
||||||
|
|
||||||
|
secondary = md_theme_dark_secondary,
|
||||||
|
onSecondary = md_theme_dark_onSecondary,
|
||||||
|
//secondaryContainer = md_theme_dark_secondaryContainer,
|
||||||
|
//onSecondaryContainer = md_theme_dark_onSecondaryContainer,
|
||||||
|
secondaryVariant = md_theme_dark_onSecondaryContainer,
|
||||||
|
|
||||||
|
//tertiary = md_theme_dark_tertiary,
|
||||||
|
//onTertiary = md_theme_dark_onTertiary,
|
||||||
|
//tertiaryContainer = md_theme_dark_tertiaryContainer,
|
||||||
|
//onTertiaryContainer = md_theme_dark_onTertiaryContainer,
|
||||||
|
|
||||||
|
error = md_theme_dark_error,
|
||||||
|
onError = md_theme_dark_onError,
|
||||||
|
//errorContainer = md_theme_dark_errorContainer,
|
||||||
|
//onErrorContainer = md_theme_dark_onErrorContainer,
|
||||||
|
|
||||||
|
background = md_theme_dark_background,
|
||||||
|
onBackground = md_theme_dark_onBackground,
|
||||||
|
|
||||||
|
surface = md_theme_dark_surface,
|
||||||
|
onSurface = md_theme_dark_onSurface,
|
||||||
|
//surfaceVariant = md_theme_dark_surfaceVariant,
|
||||||
|
//onSurfaceVariant = md_theme_dark_onSurfaceVariant,
|
||||||
|
|
||||||
|
//outline = md_theme_dark_outline,
|
||||||
|
//inverseOnSurface = md_theme_dark_inverseOnSurface,
|
||||||
|
//inverseSurface = md_theme_dark_inverseSurface,
|
||||||
|
)
|
||||||
|
@Composable
|
||||||
|
fun AppTheme(
|
||||||
|
useDarkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
|
content: @Composable() () -> Unit
|
||||||
|
) {
|
||||||
|
val colors = if (!useDarkTheme) {
|
||||||
|
LightThemeColors
|
||||||
|
} else {
|
||||||
|
DarkThemeColors
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialTheme(
|
||||||
|
//colorScheme = colors,
|
||||||
|
colors = colors,
|
||||||
|
// typography = AppTypography,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
117
app/src/main/java/de/sebse/fuplanner2/ui/theme/Type.kt
Normal file
117
app/src/main/java/de/sebse/fuplanner2/ui/theme/Type.kt
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package de.sebse.fuplanner2.ui.theme
|
||||||
|
|
||||||
|
// Comments are changes in Material 3 (Material You)
|
||||||
|
// Use default instead
|
||||||
|
|
||||||
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
|
||||||
|
//Replace with your font locations
|
||||||
|
val Roboto = FontFamily.Default
|
||||||
|
|
||||||
|
/*val AppTypography = Typography(
|
||||||
|
displayLarge = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 57.sp,
|
||||||
|
lineHeight = 64.sp,
|
||||||
|
letterSpacing = -0.25.sp,
|
||||||
|
),
|
||||||
|
displayMedium = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 45.sp,
|
||||||
|
lineHeight = 52.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
displaySmall = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 36.sp,
|
||||||
|
lineHeight = 44.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
headlineLarge = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 32.sp,
|
||||||
|
lineHeight = 40.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
headlineMedium = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 28.sp,
|
||||||
|
lineHeight = 36.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
headlineSmall = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 24.sp,
|
||||||
|
lineHeight = 32.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
titleLarge = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 22.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.sp,
|
||||||
|
),
|
||||||
|
titleMedium = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.1.sp,
|
||||||
|
),
|
||||||
|
titleSmall = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.1.sp,
|
||||||
|
),
|
||||||
|
labelLarge = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.1.sp,
|
||||||
|
),
|
||||||
|
bodyLarge = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.5.sp,
|
||||||
|
),
|
||||||
|
bodyMedium = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.25.sp,
|
||||||
|
),
|
||||||
|
bodySmall = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.W400,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.4.sp,
|
||||||
|
),
|
||||||
|
labelMedium = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.5.sp,
|
||||||
|
),
|
||||||
|
labelSmall = TextStyle(
|
||||||
|
fontFamily = Roboto,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 11.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.5.sp,
|
||||||
|
),
|
||||||
|
)*/
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package de.sebse.fuplanner2.ui.tools.previews
|
||||||
|
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
import de.sebse.fuplanner2.database.Announcement
|
||||||
|
import de.sebse.fuplanner2.database.Attachment
|
||||||
|
import de.sebse.fuplanner2.utils.Faker
|
||||||
|
import de.sebse.fuplanner2.utils.getFaker
|
||||||
|
|
||||||
|
class AnnouncementPreviewProvider(private val faker: Faker = getFaker()) : PreviewParameterProvider<Announcement> {
|
||||||
|
override val values = generateSequence { getItem() }
|
||||||
|
|
||||||
|
private fun getItem(): Announcement {
|
||||||
|
val title = faker.strings.title()
|
||||||
|
return Announcement(
|
||||||
|
faker.primitive.long(0, 100),
|
||||||
|
faker.primitive.long(0, 100),
|
||||||
|
faker.other.lastRefreshed(),
|
||||||
|
faker.strings.uuid(title),
|
||||||
|
title,
|
||||||
|
faker.strings.lorem(100, 1000),
|
||||||
|
faker.other.date(-20, -2),
|
||||||
|
"${faker.name.firstName()} ${faker.name.lastName()}",
|
||||||
|
AttachmentPreviewProvider(faker).values
|
||||||
|
.take(faker.primitive.int(1, 4))
|
||||||
|
.toList()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AttachmentPreviewProvider(private val faker: Faker = getFaker()) : PreviewParameterProvider<Attachment> {
|
||||||
|
override val values = generateSequence { getItem() }
|
||||||
|
|
||||||
|
private fun getItem(): Attachment {
|
||||||
|
return Attachment(
|
||||||
|
faker.internet.url(),
|
||||||
|
faker.strings.title(),
|
||||||
|
faker.internet.mime()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package de.sebse.fuplanner2.ui.details
|
package de.sebse.fuplanner2.ui.tools.previews
|
||||||
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import de.sebse.fuplanner2.database.Course
|
import de.sebse.fuplanner2.database.Course
|
||||||
@@ -7,12 +7,13 @@ import de.sebse.fuplanner2.utils.Faker
|
|||||||
import de.sebse.fuplanner2.utils.getFaker
|
import de.sebse.fuplanner2.utils.getFaker
|
||||||
|
|
||||||
class LecturerPreviewProvider(private val faker: Faker = getFaker()) : PreviewParameterProvider<Lecturer> {
|
class LecturerPreviewProvider(private val faker: Faker = getFaker()) : PreviewParameterProvider<Lecturer> {
|
||||||
private val resp = faker.primitive.int(1, 2)
|
override val values = sequence {
|
||||||
override val values = (0..10).map {
|
yield(getItem(true))
|
||||||
getLecturer(it < resp)
|
yield(getItem(faker.primitive.bool(.5f)))
|
||||||
}.asSequence()
|
yieldAll(generateSequence { getItem(false) })
|
||||||
|
}
|
||||||
|
|
||||||
private fun getLecturer(isResponsible: Boolean): Lecturer {
|
private fun getItem(isResponsible: Boolean): Lecturer {
|
||||||
val firstName = faker.name.firstName()
|
val firstName = faker.name.firstName()
|
||||||
val lastName = faker.name.lastName()
|
val lastName = faker.name.lastName()
|
||||||
return Lecturer(
|
return Lecturer(
|
||||||
@@ -25,17 +26,16 @@ class LecturerPreviewProvider(private val faker: Faker = getFaker()) : PreviewPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CoursePreviewProvider(private val faker: Faker = getFaker()) : PreviewParameterProvider<Course> {
|
class CoursePreviewProvider(private val faker: Faker = getFaker()) : PreviewParameterProvider<Course> {
|
||||||
var isSummer = false
|
private var isSummer = false
|
||||||
var year = 21
|
private var year = 21
|
||||||
override val values = (0..10).map {
|
override val values = sequence {
|
||||||
val res = getCourse()
|
yield(getItem())
|
||||||
val reduce = faker.primitive.bool(.3f)
|
val reduce = faker.primitive.bool(.3f)
|
||||||
year = if (reduce && isSummer) year-1 else year
|
year = if (reduce && isSummer) year-1 else year
|
||||||
isSummer = if (reduce) !isSummer else isSummer
|
isSummer = if (reduce) !isSummer else isSummer
|
||||||
res
|
}
|
||||||
}.asSequence()
|
|
||||||
|
|
||||||
private fun getCourse(): Course {
|
private fun getItem(): Course {
|
||||||
val diff = 1000L*60*60*24*5
|
val diff = 1000L*60*60*24*5
|
||||||
val title =
|
val title =
|
||||||
"${faker.strings.title()} ${if (isSummer) "S" else "W"} ${if (isSummer) year else "$year/${year + 1}"}"
|
"${faker.strings.title()} ${if (isSummer) "S" else "W"} ${if (isSummer) year else "$year/${year + 1}"}"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package de.sebse.fuplanner2.viewmodels
|
package de.sebse.fuplanner2.ui.tools.viewmodels
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package de.sebse.fuplanner2.viewmodels
|
package de.sebse.fuplanner2.ui.tools.viewmodels
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -21,6 +21,9 @@ class Faker(randomSeed: Int) {
|
|||||||
val primitive: FakerPrimitive
|
val primitive: FakerPrimitive
|
||||||
get() = FakerPrimitive(random)
|
get() = FakerPrimitive(random)
|
||||||
|
|
||||||
|
val other: FakerOther
|
||||||
|
get() = FakerOther(random)
|
||||||
|
|
||||||
val strings: FakerStrings
|
val strings: FakerStrings
|
||||||
get() = FakerStrings(random)
|
get() = FakerStrings(random)
|
||||||
}
|
}
|
||||||
@@ -29,6 +32,7 @@ class FakerName(private val random: Random) {
|
|||||||
fun lastName(): String {
|
fun lastName(): String {
|
||||||
return LASTNAMES.random(random)
|
return LASTNAMES.random(random)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun firstName(): String {
|
fun firstName(): String {
|
||||||
return FIRSTNAMES.random(random)
|
return FIRSTNAMES.random(random)
|
||||||
}
|
}
|
||||||
@@ -60,6 +64,19 @@ class FakerInternet(private val random: Random) {
|
|||||||
.replace(Regex("[^a-z0-9.]"), "")
|
.replace(Regex("[^a-z0-9.]"), "")
|
||||||
return "$user@fu-berlin.de"
|
return "$user@fu-berlin.de"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun mime(): String {
|
||||||
|
return MIME_TYPES.random(random)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun url(): String {
|
||||||
|
return "https://example.de/file"
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val MIME_TYPES = listOf("application/pdf", "text/plain", "text/csv",
|
||||||
|
"application/msword")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakerPrimitive(private val random: Random) {
|
class FakerPrimitive(private val random: Random) {
|
||||||
@@ -76,11 +93,31 @@ class FakerPrimitive(private val random: Random) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FakerOther(private val random: Random) {
|
||||||
|
fun lastRefreshed(): Long {
|
||||||
|
return FakerPrimitive(random).long(
|
||||||
|
System.currentTimeMillis() - DIFF,
|
||||||
|
System.currentTimeMillis() + DIFF
|
||||||
|
)
|
||||||
|
}
|
||||||
|
fun date(startDay: Int, endDay: Int): Long {
|
||||||
|
return FakerPrimitive(random).long(
|
||||||
|
System.currentTimeMillis() + DAY * startDay,
|
||||||
|
System.currentTimeMillis() + DAY * endDay
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val DAY = 1000L*60*60*24
|
||||||
|
const val DIFF = DAY*5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class FakerStrings(private val random: Random) {
|
class FakerStrings(private val random: Random) {
|
||||||
fun lorem(min: Int, max: Int): String {
|
fun lorem(min: Int, max: Int): String {
|
||||||
val length = (min..max).random(random)
|
val length = (min..max).random(random)
|
||||||
val loremArray = LOREM.split(" ").size
|
val loremArray = LOREM.split(" ").size
|
||||||
val n = ceil(length.toFloat() / loremArray).toInt()
|
val n = ceil(length.toFloat() / loremArray).toInt() + 1
|
||||||
val repeatedArray = ("$LOREM ")
|
val repeatedArray = ("$LOREM ")
|
||||||
.repeat(n)
|
.repeat(n)
|
||||||
.trim()
|
.trim()
|
||||||
@@ -109,7 +146,7 @@ class FakerStrings(private val random: Random) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val LOREM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy "+
|
const val LOREM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy "+
|
||||||
"eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam "+
|
"eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam "+
|
||||||
"voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita "+
|
"voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita "+
|
||||||
"kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem "+
|
"kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem "+
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import de.sebse.fuplanner2.database.Course
|
|||||||
import de.sebse.fuplanner2.database.User
|
import de.sebse.fuplanner2.database.User
|
||||||
import de.sebse.fuplanner2.utils.Notifications
|
import de.sebse.fuplanner2.utils.Notifications
|
||||||
import de.sebse.fuplanner2.utils.UpdateResult
|
import de.sebse.fuplanner2.utils.UpdateResult
|
||||||
import de.sebse.fuplanner2.utils.console
|
|
||||||
import de.sebse.fuplanner2.whiteboard.Whiteboard
|
import de.sebse.fuplanner2.whiteboard.Whiteboard
|
||||||
import de.sebse.fuplanner2.whiteboard.getCourse
|
import de.sebse.fuplanner2.whiteboard.getCourse
|
||||||
import de.sebse.fuplanner2.whiteboard.getCourses
|
import de.sebse.fuplanner2.whiteboard.getCourses
|
||||||
@@ -39,6 +38,7 @@ class CourseWorker(context: Context, params: WorkerParameters) : AbstractAccount
|
|||||||
updates.added.forEach {
|
updates.added.forEach {
|
||||||
if (it.isSummerSemester == latestSemester.semester && it.year == latestSemester.year) {
|
if (it.isSummerSemester == latestSemester.semester && it.year == latestSemester.year) {
|
||||||
EventWorker.work(applicationContext, database, user, it)
|
EventWorker.work(applicationContext, database, user, it)
|
||||||
|
AnnouncementWorker.work(applicationContext, database, user, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Notifications.courseUpdates(updates, database, applicationContext)
|
Notifications.courseUpdates(updates, database, applicationContext)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import de.sebse.fuplanner2.auth.AppAccounts
|
|||||||
import de.sebse.fuplanner2.database.AppDatabase
|
import de.sebse.fuplanner2.database.AppDatabase
|
||||||
import de.sebse.fuplanner2.database.Course
|
import de.sebse.fuplanner2.database.Course
|
||||||
import de.sebse.fuplanner2.utils.Notifications
|
import de.sebse.fuplanner2.utils.Notifications
|
||||||
import de.sebse.fuplanner2.utils.Updatable
|
|
||||||
import de.sebse.fuplanner2.utils.UpdateResult
|
import de.sebse.fuplanner2.utils.UpdateResult
|
||||||
import de.sebse.fuplanner2.utils.mergeUpdatable
|
import de.sebse.fuplanner2.utils.mergeUpdatable
|
||||||
|
|
||||||
@@ -52,6 +51,7 @@ class SyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(c
|
|||||||
courseCreations.forEach { course ->
|
courseCreations.forEach { course ->
|
||||||
if (course.isSummerSemester == latestSemester.semester && course.year == latestSemester.year) {
|
if (course.isSummerSemester == latestSemester.semester && course.year == latestSemester.year) {
|
||||||
EventWorker.work(applicationContext, database, it, course)
|
EventWorker.work(applicationContext, database, it, course)
|
||||||
|
AnnouncementWorker.work(applicationContext, database, it, course)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Notifications.courseUpdates(notifications, database, applicationContext)
|
Notifications.courseUpdates(notifications, database, applicationContext)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.sebse.fuplanner2
|
package de.sebse.fuplanner2
|
||||||
|
|
||||||
|
import de.sebse.fuplanner2.ui.tools.previews.AnnouncementPreviewProvider
|
||||||
import de.sebse.fuplanner2.utils.getFaker
|
import de.sebse.fuplanner2.utils.getFaker
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@@ -17,4 +18,9 @@ class FakerTest {
|
|||||||
getFaker().strings.lorem(100, 1000)
|
getFaker().strings.lorem(100, 1000)
|
||||||
getFaker().strings.lorem(100, 1000)
|
getFaker().strings.lorem(100, 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun announcement() {
|
||||||
|
AnnouncementPreviewProvider().values.take(10)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user