Skip to content

Commit

Permalink
Updated the projects filter code
Browse files Browse the repository at this point in the history
  • Loading branch information
janewaitara committed May 7, 2024
1 parent a6e8d4b commit d002b58
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import com.mumbicodes.projectie.domain.model.Project
import com.mumbicodes.projectie.domain.model.ProjectName
import com.mumbicodes.projectie.domain.relations.ProjectWithMilestones
import com.mumbicodes.projectie.domain.repository.ProjectsRepository
import com.mumbicodes.projectie.domain.util.OrderType
import com.mumbicodes.projectie.domain.util.ProjectsOrder
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

class ProjectsRepositoryImpl(
private val projectsDao: ProjectsDao,
Expand Down Expand Up @@ -45,28 +42,8 @@ class ProjectsRepositoryImpl(
*
* By default, the order is the date added
* */
override suspend fun getAllProjects(projectOrder: ProjectsOrder): DataResult<Flow<List<Project>>> =
safeTransaction {
projectsDao.getAllProjects().map { projects ->
when (projectOrder.orderType) {
is OrderType.Ascending -> {
when (projectOrder) {
is ProjectsOrder.Name -> projects.sortedBy { it.projectName.lowercase() }
is ProjectsOrder.Deadline -> projects.sortedBy { it.projectDeadline }
is ProjectsOrder.DateAdded -> projects.sortedBy { it.timeStamp }
}
}

is OrderType.Descending -> {
when (projectOrder) {
is ProjectsOrder.Name -> projects.sortedByDescending { it.projectName.lowercase() }
is ProjectsOrder.Deadline -> projects.sortedByDescending { it.projectDeadline }
is ProjectsOrder.DateAdded -> projects.sortedByDescending { it.timeStamp }
}
}
}
}
}.toDataResult()
override suspend fun getAllProjects(): DataResult<Flow<List<Project>>> =
safeTransaction { projectsDao.getAllProjects() }.toDataResult()

override suspend fun getProjectNameAndId(): DataResult<Flow<List<ProjectName>>> =
safeTransaction { projectsDao.getProjectNameAndId() }.toDataResult()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.mumbicodes.projectie.domain.model.DataResult
import com.mumbicodes.projectie.domain.model.Project
import com.mumbicodes.projectie.domain.model.ProjectName
import com.mumbicodes.projectie.domain.relations.ProjectWithMilestones
import com.mumbicodes.projectie.domain.util.ProjectsOrder
import kotlinx.coroutines.flow.Flow

interface ProjectsRepository {
Expand All @@ -17,7 +16,7 @@ interface ProjectsRepository {

suspend fun getProjectByIdWithMilestones(projectId: Int): DataResult <Flow<ProjectWithMilestones?>>

suspend fun getAllProjects(projectOrder: ProjectsOrder): DataResult<Flow<List<Project>>>
suspend fun getAllProjects(): DataResult<Flow<List<Project>>>

suspend fun getProjectNameAndId(): DataResult<Flow<List<ProjectName>>>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@ package com.mumbicodes.projectie.domain.use_case.projects
import com.mumbicodes.projectie.domain.model.DataResult
import com.mumbicodes.projectie.domain.model.Project
import com.mumbicodes.projectie.domain.repository.ProjectsRepository
import com.mumbicodes.projectie.domain.util.OrderType
import com.mumbicodes.projectie.domain.util.ProjectsOrder
import kotlinx.coroutines.flow.Flow

class GetProjectsUseCase(
private val repository: ProjectsRepository,
) {
suspend operator fun invoke(
projectOrder: ProjectsOrder = ProjectsOrder.DateAdded(OrderType.Descending),
): DataResult<Flow<List<Project>>> =
repository.getAllProjects(projectOrder = projectOrder)
suspend operator fun invoke(): DataResult<Flow<List<Project>>> =
repository.getAllProjects()
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import com.mumbicodes.projectie.R
import com.mumbicodes.projectie.domain.model.DataResult
import com.mumbicodes.projectie.domain.model.Project
import com.mumbicodes.projectie.domain.repository.ProjectsRepository
import com.mumbicodes.projectie.domain.util.OrderType
import com.mumbicodes.projectie.domain.util.ProjectsOrder
import com.mumbicodes.projectie.presentation.util.toLocalDate
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.time.LocalDate

private const val TAG = "ProjectWorkerInTwoDays"
Expand All @@ -34,9 +37,7 @@ class CheckProjectDeadlineIsInTwoDaysWorker @AssistedInject constructor(
return@withContext try {
Log.e("Reached 3", "It has been reached - 2 days ")

val allProjects = projectsRepository.getAllProjects(
projectOrder = ProjectsOrder.DateAdded(OrderType.Descending)
)
val allProjects = projectsRepository.getAllProjects()

CoroutineScope(Dispatchers.IO).launch {
when (allProjects) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import com.mumbicodes.projectie.R
import com.mumbicodes.projectie.domain.model.DataResult
import com.mumbicodes.projectie.domain.model.Project
import com.mumbicodes.projectie.domain.repository.ProjectsRepository
import com.mumbicodes.projectie.domain.util.OrderType
import com.mumbicodes.projectie.domain.util.ProjectsOrder
import com.mumbicodes.projectie.presentation.util.toLocalDate
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.time.LocalDate

private const val TAG = "ProjectWorkerIsToday"
Expand All @@ -30,11 +32,7 @@ class CheckProjectDeadlineWorker @AssistedInject constructor(

return withContext(Dispatchers.IO) {
return@withContext try {
val allProjects = projectsRepository.getAllProjects(
projectOrder = ProjectsOrder.DateAdded(
OrderType.Descending
)
)
val allProjects = projectsRepository.getAllProjects()

CoroutineScope(Dispatchers.IO).launch {
when (allProjects) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,65 @@ import com.mumbicodes.projectie.domain.model.Project
import com.mumbicodes.projectie.domain.util.OrderType
import com.mumbicodes.projectie.domain.util.ProjectsOrder
import com.mumbicodes.projectie.presentation.util.state.ListState
import com.mumbicodes.projectie.presentation.util.state.SuccessState

/**
* @param selectedProjectOrder Holds the user selection until they press filter
*
* There is the empty state when there is nothing created -- Screen Empty -- the db is empty
* There is loading of the screen -- Initial state
* There is data -- Screen data
*
* Projects - Error, Loading, Success (Empty, Data)
* The overall data
* The search results -- within the same data
*
*
* - projects - The projects we are showing (default and search results)-- All projects - have the states
* - filters - name and selected state @param filtersStatus,
* @param filtersStatus and @param selectedProjectStatus
*
* - Projects Order
* - showFilterBottomSheet
* - has requested Notification
* - selected project order
* - Search param
* -
*
* @param projectsOrder This is the actual projects order after the user updates the filters
* @param selectedProjectOrder Holds the user selection until they press filter
* */
data class AllProjectsStates(
val projects: ListState<List<Project>> = ListState.Loading,
val filteredProjects: ListState<List<Project>> = ListState.Loading,
val projectsOrder: ProjectsOrder = ProjectsOrder.DateAdded(OrderType.Descending),
val filtersStatus: List<String> = filters,
val selectedProjectStatus: String = filters.first(),
val isFilterBottomSheetVisible: Boolean = false,
val hasRequestedNotificationPermission: Boolean = false,
val selectedProjectOrder: ProjectsOrder = projectsOrder,
val searchParam: String = "",
)
) {

val filteredProjects: ListState<List<Project>>
get() = if (projects is ListState.Success) {
if (projects.data is SuccessState.Data) {
val allProjects = projects.data.data
val filteredList = allProjects
.filter {
if (selectedProjectStatus == filters.first()) true
else selectedProjectStatus == it.projectStatus
}
.filter {
if (searchParam.isNotBlank()) it.projectName.contains(searchParam)
else true
}
.let { projectsList ->
when (selectedProjectOrder.orderType) {
is OrderType.Ascending -> {
when (selectedProjectOrder) {
is ProjectsOrder.Name -> projectsList.sortedBy { it.projectName.lowercase() }
is ProjectsOrder.Deadline -> projectsList.sortedBy { it.projectDeadline }
is ProjectsOrder.DateAdded -> projectsList.sortedBy { it.timeStamp }
}
}

is OrderType.Descending -> {
when (selectedProjectOrder) {
is ProjectsOrder.Name -> projectsList.sortedByDescending { it.projectName.lowercase() }
is ProjectsOrder.Deadline -> projectsList.sortedByDescending { it.projectDeadline }
is ProjectsOrder.DateAdded -> projectsList.sortedByDescending { it.timeStamp }
}
}
}
}

if (filteredList.isEmpty()) ListState.Success(SuccessState.Empty)
else ListState.Success(SuccessState.Data(data = filteredList))
} else {
projects
}
} else {
projects
}
}

val filters = listOf(
"All",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.mumbicodes.projectie.R
import com.mumbicodes.projectie.domain.model.DataResult
import com.mumbicodes.projectie.domain.model.Project
import com.mumbicodes.projectie.domain.use_case.notifications.NotificationUseCases
Expand Down Expand Up @@ -43,7 +42,7 @@ class AllProjectsViewModel @Inject constructor(
private var getProjectsJob: Job? = null

init {
getProjects(ProjectsOrder.DateAdded(OrderType.Descending), "All")
getProjects(ProjectsOrder.DateAdded(OrderType.Descending))
if (state is ScreenState.Data<*>) {
readNotPromptState()
}
Expand All @@ -58,17 +57,18 @@ class AllProjectsViewModel @Inject constructor(
) {
return
}
getProjects(
(state.value as ScreenState.Data).data.selectedProjectOrder,
(state.value as ScreenState.Data).data.selectedProjectStatus
_state.value = ScreenState.Data(
data = (state.value as ScreenState.Data<AllProjectsStates>).data.copy(
projectsOrder = (state.value as ScreenState.Data).data.selectedProjectOrder
)
)
}

is AllProjectsEvent.ResetProjectsOrder -> {

getProjects(
projectsEvent.projectsOrder,
(state.value as ScreenState.Data).data.selectedProjectStatus
_state.value = ScreenState.Data(
data = (state.value as ScreenState.Data<AllProjectsStates>).data.copy(
selectedProjectOrder = projectsEvent.projectsOrder
)
)
}

Expand All @@ -90,9 +90,10 @@ class AllProjectsViewModel @Inject constructor(
if ((state.value as ScreenState.Data).data.selectedProjectStatus == projectsEvent.projectStatus) {
return
}
(((state.value as ScreenState.Data).data.projects as ListState.Success).data as SuccessState.Data).data.filterProjects(
projectStatus = projectsEvent.projectStatus,
searchParam = (state.value as ScreenState.Data).data.searchParam
_state.value = ScreenState.Data(
data = (state.value as ScreenState.Data<AllProjectsStates>).data.copy(
selectedProjectStatus = projectsEvent.projectStatus
)
)
}

Expand All @@ -110,10 +111,6 @@ class AllProjectsViewModel @Inject constructor(
searchParam = projectsEvent.searchParam
)
)
(((state.value as ScreenState.Data).data.projects as ListState.Success).data as SuccessState.Data).data.filterProjects(
projectStatus = (state.value as ScreenState.Data<AllProjectsStates>).data.selectedProjectStatus,
searchParam = projectsEvent.searchParam,
)
}

is AllProjectsEvent.UpdateProjectOrder -> {
Expand All @@ -129,12 +126,12 @@ class AllProjectsViewModel @Inject constructor(
/**
* Whenever called, a new flow is emitted. Hence cancel the old coroutine that's observing db
* */
private fun getProjects(projectsOrder: ProjectsOrder, projectStatus: String) {
private fun getProjects(projectsOrder: ProjectsOrder) {
viewModelScope.launch {

getProjectsJob?.cancel()
getProjectsJob =
when (val results = projectsUseCases.getProjectsUseCase(projectsOrder)) {
when (val results = projectsUseCases.getProjectsUseCase()) {
is DataResult.Error -> {
// Doing this in a viewModelScope as we need to return a job
viewModelScope.launch {
Expand Down Expand Up @@ -163,10 +160,6 @@ class AllProjectsViewModel @Inject constructor(
projectsOrder = projectsOrder,
),
)
projects.filterProjects(
projectStatus,
(state.value as ScreenState.Data<AllProjectsStates>).data.searchParam
)
}
}
.launchIn(viewModelScope)
Expand All @@ -175,39 +168,6 @@ class AllProjectsViewModel @Inject constructor(
}
}

private fun List<Project>.filterProjects(
projectStatus: String,
searchParam: String,
) {
_state.value = ScreenState.Data(
data = (state.value as ScreenState.Data).data.copy(
filteredProjects = ListState.Success
(
data = when (
this.filter { projectStatus == appContext.getString(R.string.all) || it.projectStatus == projectStatus }
.filter {
it.projectName.contains(searchParam)
}.isEmpty()
) {
true -> {
SuccessState.Empty
}

false -> {
SuccessState.Data(
this.filter { projectStatus == appContext.getString(R.string.all) || it.projectStatus == projectStatus }
.filter {
it.projectName.contains(searchParam)
}
)
}
}
),
selectedProjectStatus = projectStatus,
)
)
}

private fun readNotPromptState() {
viewModelScope.launch {
notificationUseCases.readNotificationPromptStateUseCase.invoke().collect { isPrompted ->
Expand Down

0 comments on commit d002b58

Please sign in to comment.