Skip to content

Commit

Permalink
1.3.0
Browse files Browse the repository at this point in the history
feat: app - TagDetail TagMemo Tab
feat: app - preferred width 500
fix: app - CalendarScreen request focus when resume(after close filter dialog can use keyboard shortcut)
fix: app - memo sort start, endInclusive, title
fix: app - screen navigate animation
feat: app - CalendarScreen F1~F2 shortcut(TopBar action)
  • Loading branch information
taetae98coding committed Dec 1, 2024
1 parent 27eedf0 commit 7a1d43b
Show file tree
Hide file tree
Showing 72 changed files with 1,435 additions and 670 deletions.
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
package io.github.taetae98coding.diary.core.calendar.compose

import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.unit.dp
import io.github.taetae98coding.diary.core.calendar.compose.color.CalendarColors
import io.github.taetae98coding.diary.core.calendar.compose.item.CalendarItemUiState
import io.github.taetae98coding.diary.core.calendar.compose.month.CalendarMonth
import io.github.taetae98coding.diary.core.calendar.compose.month.CalendarMonthState
import io.github.taetae98coding.diary.core.calendar.compose.state.CalendarState
import io.github.taetae98coding.diary.core.design.system.theme.DiaryTheme
import kotlinx.coroutines.launch
import kotlinx.datetime.DateTimeUnit
import kotlinx.datetime.LocalDate
import kotlinx.datetime.plus
Expand All @@ -36,26 +29,8 @@ public fun Calendar(
modifier: Modifier = Modifier,
colors: CalendarColors = CalendarDefaults.colors(),
) {
val coroutineScope = rememberCoroutineScope()

Surface(
modifier = modifier
.onPreviewKeyEvent {
when {
!state.pagerState.isScrollInProgress && it.key == Key.DirectionRight -> {
coroutineScope.launch { state.animateScrollToForward() }
true
}

!state.pagerState.isScrollInProgress && it.key == Key.DirectionLeft -> {
coroutineScope.launch { state.animateScrollToBackward() }
true
}

else -> false
}
}.focusRequester(state.focusRequester)
.focusable(),
modifier = modifier,
color = DiaryTheme.color.background,
) {
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
Expand All @@ -70,10 +45,6 @@ public fun Calendar(
)
}
}

LaunchedEffect(state.focusRequester) {
state.focusRequester.requestFocus()
}
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import androidx.compose.foundation.pager.PagerState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.focus.FocusRequester
import io.github.taetae98coding.diary.library.datetime.todayIn
import kotlinx.datetime.DateTimeUnit
import kotlinx.datetime.LocalDate
import kotlinx.datetime.Month
Expand All @@ -13,8 +13,6 @@ import kotlinx.datetime.plus
public class CalendarState internal constructor(
internal val pagerState: PagerState,
) {
internal val focusRequester = FocusRequester()

internal val localDate: LocalDate
get() = LocalDate(1, 1, 1).plus(pagerState.currentPage, DateTimeUnit.MONTH)

Expand All @@ -27,17 +25,24 @@ public class CalendarState internal constructor(
public val month: Month
get() = localDate.month

public val isScrollInProgress: Boolean
get() = pagerState.isScrollInProgress

public suspend fun animateScrollToToday() {
animateScrollTo(LocalDate.todayIn())
}

public suspend fun animateScrollTo(localDate: LocalDate) {
pagerState.animateScrollToPage(page(localDate))
}

internal suspend fun animateScrollToBackward() {
public suspend fun animateScrollToBackward() {
if (pagerState.canScrollBackward) {
pagerState.animateScrollToPage(pagerState.currentPage - 1)
}
}

internal suspend fun animateScrollToForward() {
public suspend fun animateScrollToForward() {
if (pagerState.canScrollForward) {
pagerState.animateScrollToPage(pagerState.currentPage + 1)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.github.taetae98coding.diary.core.design.system.icon

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Group
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
public fun BuddyIcon(
modifier: Modifier = Modifier,
) {
Icon(
imageVector = Icons.Rounded.Group,
contentDescription = null,
modifier = modifier,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,9 @@ internal abstract class MemoEntityDao : EntityDao<MemoEntity>() {
SELECT *
FROM MemoEntity
WHERE id = :memoId
AND (:filterNotDelete = 0 OR isDelete = 0)
""",
)
abstract fun find(memoId: String, filterNotDelete: Boolean): Flow<MemoEntity?>
abstract fun find(memoId: String): Flow<MemoEntity?>

@Query(
"""
Expand All @@ -108,10 +107,9 @@ internal abstract class MemoEntityDao : EntityDao<MemoEntity>() {
LEFT OUTER JOIN MemoTagEntity
ON MemoEntity.id = MemoTagEntity.memoId
WHERE MemoEntity.id IN (:memoIds)
AND (:filterNotDelete = 0 OR isDelete = 0)
""",
)
abstract fun findMemoAndTagIdsByIds(memoIds: Set<String>, filterNotDelete: Boolean): Flow<Map<MemoEntity, List<MemoTagEntity>>>
abstract fun findMemoAndTagIdsByIds(memoIds: Set<String>): Flow<Map<MemoEntity, List<MemoTagEntity>>>

@Query(
"""
Expand All @@ -123,9 +121,10 @@ internal abstract class MemoEntityDao : EntityDao<MemoEntity>() {
AND endInclusive IS NOT NULL
AND endInclusive >= :start AND start <= :endInclusive
AND (:hasTagFilter = 0 OR id IN (SELECT memoId FROM MemoTagEntity WHERE tagId in (:tagFilter)))
ORDER BY start, endInclusive, title
""",
)
abstract fun findByDateRange(owner: String?, start: LocalDate, endInclusive: LocalDate, hasTagFilter: Boolean, tagFilter: Set<String>): Flow<List<MemoEntity>>
abstract fun pageByDateRange(owner: String?, start: LocalDate, endInclusive: LocalDate, hasTagFilter: Boolean, tagFilter: Set<String>): Flow<List<MemoEntity>>

@Query("SELECT MAX(serverUpdateAt) FROM MemoEntity WHERE owner = :owner")
abstract fun getLastUpdateAt(owner: String?): Flow<Instant?>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ internal class MemoRoomDao(
database.memo().updateDelete(memoId, isDelete, clock.now())
}

override fun find(memoId: String, filterNotDelete: Boolean): Flow<MemoDto?> =
override fun find(memoId: String): Flow<MemoDto?> =
database
.memo()
.find(memoId, filterNotDelete)
.find(memoId)
.mapLatest { it?.toDto() }

override fun findMemoAndTagIdsByIds(memoIds: Set<String>, filterNotDelete: Boolean): Flow<List<MemoAndTagIds>> =
override fun findMemoAndTagIdsByIds(memoIds: Set<String>): Flow<List<MemoAndTagIds>> =
database
.memo()
.findMemoAndTagIdsByIds(memoIds, filterNotDelete)
.findMemoAndTagIdsByIds(memoIds)
.mapLatest { map ->
map.map { entry ->
MemoAndTagIds(
Expand All @@ -71,10 +71,10 @@ internal class MemoRoomDao(
}
}

override fun findByDateRange(owner: String?, dateRange: ClosedRange<LocalDate>, tagFilter: Set<String>): Flow<List<MemoDto>> =
override fun pageByDateRange(owner: String?, dateRange: ClosedRange<LocalDate>, tagFilter: Set<String>): Flow<List<MemoDto>> =
database
.memo()
.findByDateRange(owner, dateRange.start, dateRange.endInclusive, tagFilter.isNotEmpty(), tagFilter)
.pageByDateRange(owner, dateRange.start, dateRange.endInclusive, tagFilter.isNotEmpty(), tagFilter)
.mapCollectionLatest(MemoEntity::toDto)

override suspend fun upsert(memoList: List<MemoAndTagIds>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,40 @@ package io.github.taetae98coding.diary.core.diary.database.room.dao

import androidx.room.Dao
import androidx.room.Query
import io.github.taetae98coding.diary.core.diary.database.room.entity.MemoEntity
import io.github.taetae98coding.diary.core.diary.database.room.entity.MemoTagEntity
import io.github.taetae98coding.diary.core.diary.database.room.entity.TagEntity
import io.github.taetae98coding.diary.library.room.dao.EntityDao
import kotlinx.coroutines.flow.Flow

@Dao
internal abstract class MemoTagEntityDao : EntityDao<MemoTagEntity>() {
@Query(
"""
SELECT tagId
FROM MemoTagEntity
WHERE memoId = :memoId
SELECT *
FROM TagEntity
WHERE id IN (
SELECT tagId
FROM MemoTagEntity
WHERE memoId = :memoId
)
""",
)
abstract fun findTagIdsByMemoId(memoId: String): Flow<List<String>>
abstract fun findTagByMemoId(memoId: String): Flow<List<TagEntity>>

@Query(
"""
SELECT *
FROM MemoEntity
WHERE isDelete = 0
AND isFinish = 0
AND id IN (
SELECT memoId
FROM MemoTagEntity
WHERE tagId = :tagId
)
ORDER BY start, endInclusive, title
""",
)
abstract fun pageMemoByTagId(tagId: String): Flow<List<MemoEntity>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@ package io.github.taetae98coding.diary.core.diary.database.room.dao
import io.github.taetae98coding.diary.core.diary.database.MemoTagDao
import io.github.taetae98coding.diary.core.diary.database.room.DiaryDatabase
import io.github.taetae98coding.diary.core.diary.database.room.entity.MemoTagEntity
import kotlinx.coroutines.ExperimentalCoroutinesApi
import io.github.taetae98coding.diary.core.diary.database.room.entity.TagEntity
import io.github.taetae98coding.diary.core.diary.database.room.mapper.toDto
import io.github.taetae98coding.diary.core.model.tag.TagDto
import io.github.taetae98coding.diary.library.coroutines.mapCollectionLatest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.mapLatest
import org.koin.core.annotation.Factory

@OptIn(ExperimentalCoroutinesApi::class)
@Factory
internal class MemoTagRoomDao(
private val database: DiaryDatabase,
) : MemoTagDao {
override fun findTagIdsByMemoId(memoId: String): Flow<Set<String>> =
database
.memoTag()
.findTagIdsByMemoId(memoId)
.mapLatest(List<String>::toSet)

override suspend fun upsert(memoId: String, tagId: String) {
database.memoTag().upsert(MemoTagEntity(memoId, tagId))
}

override suspend fun delete(memoId: String, tagId: String) {
database.memoTag().delete(MemoTagEntity(memoId, tagId))
}

override fun findTagByMemoId(memoId: String): Flow<List<TagDto>> = database
.memoTag()
.findTagByMemoId(memoId)
.mapCollectionLatest(TagEntity::toDto)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package io.github.taetae98coding.diary.core.diary.database.room.dao

import androidx.room.Dao
import androidx.room.Query
import io.github.taetae98coding.diary.core.diary.database.room.entity.MemoEntity
import io.github.taetae98coding.diary.core.diary.database.room.entity.TagEntity
import io.github.taetae98coding.diary.library.room.dao.EntityDao
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -68,36 +67,18 @@ internal abstract class TagEntityDao : EntityDao<TagEntity>() {
SELECT *
FROM TagEntity
WHERE id = :tagId
AND (:filterNotDelete = 0 OR isDelete = 0)
""",
)
abstract fun find(tagId: String, filterNotDelete: Boolean): Flow<TagEntity?>
abstract fun find(tagId: String): Flow<TagEntity?>

@Query(
"""
SELECT *
FROM TagEntity
WHERE id IN (:tagIds)
AND (:filterNotDelete = 0 OR isDelete = 0)
""",
)
abstract fun findByIds(tagIds: Set<String>, filterNotDelete: Boolean): Flow<List<TagEntity>>

@Query(
"""
SELECT *
FROM MemoEntity
WHERE isDelete = 0
AND isFinish = 0
AND id IN (
SELECT memoId
FROM MemoTagEntity
WHERE tagId = :tagId
)
ORDER BY title
""",
)
abstract fun findMemoByTagId(tagId: String): Flow<List<MemoEntity>>
abstract fun findByIds(tagIds: Set<String>): Flow<List<TagEntity>>

@Query("SELECT MAX(serverUpdateAt) FROM TagEntity WHERE owner = :owner")
abstract fun getLastUpdateAt(owner: String?): Flow<Instant?>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.github.taetae98coding.diary.core.diary.database.room.dao

import io.github.taetae98coding.diary.core.diary.database.TagMemoDao
import io.github.taetae98coding.diary.core.diary.database.room.DiaryDatabase
import io.github.taetae98coding.diary.core.diary.database.room.entity.MemoEntity
import io.github.taetae98coding.diary.core.diary.database.room.mapper.toDto
import io.github.taetae98coding.diary.core.model.memo.MemoDto
import io.github.taetae98coding.diary.library.coroutines.mapCollectionLatest
import kotlinx.coroutines.flow.Flow
import org.koin.core.annotation.Factory

@Factory
internal class TagMemoRoomDao(
private val database: DiaryDatabase,
) : TagMemoDao {
override fun pageMemoByTagId(tagId: String): Flow<List<MemoDto>> = database
.memoTag()
.pageMemoByTagId(tagId)
.mapCollectionLatest(MemoEntity::toDto)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package io.github.taetae98coding.diary.core.diary.database.room.dao

import io.github.taetae98coding.diary.core.diary.database.TagDao
import io.github.taetae98coding.diary.core.diary.database.room.DiaryDatabase
import io.github.taetae98coding.diary.core.diary.database.room.entity.MemoEntity
import io.github.taetae98coding.diary.core.diary.database.room.entity.TagEntity
import io.github.taetae98coding.diary.core.diary.database.room.mapper.toDto
import io.github.taetae98coding.diary.core.diary.database.room.mapper.toEntity
import io.github.taetae98coding.diary.core.model.memo.MemoDto
import io.github.taetae98coding.diary.core.model.tag.TagDetail
import io.github.taetae98coding.diary.core.model.tag.TagDto
import io.github.taetae98coding.diary.library.coroutines.mapCollectionLatest
Expand Down Expand Up @@ -55,18 +53,13 @@ internal class TagRoomDao(
.page(owner)
.mapCollectionLatest(TagEntity::toDto)

override fun find(tagId: String, filterNotDelete: Boolean): Flow<TagDto?> = database.tag().find(tagId, filterNotDelete).mapLatest { it?.toDto() }
override fun find(tagId: String): Flow<TagDto?> = database.tag().find(tagId).mapLatest { it?.toDto() }

override fun findByIds(tagIds: Set<String>, filterNotDelete: Boolean): Flow<List<TagDto>> =
override fun findByIds(tagIds: Set<String>): Flow<List<TagDto>> =
database
.tag()
.findByIds(tagIds, filterNotDelete)
.findByIds(tagIds)
.mapCollectionLatest(TagEntity::toDto)

override fun findMemoByTagId(tagId: String): Flow<List<MemoDto>> = database
.tag()
.findMemoByTagId(tagId)
.mapCollectionLatest(MemoEntity::toDto)

override fun getLastServerUpdateAt(owner: String?): Flow<Instant?> = database.tag().getLastUpdateAt(owner)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ public interface MemoDao {

public suspend fun updateDelete(memoId: String, isDelete: Boolean)

public fun findByDateRange(owner: String?, dateRange: ClosedRange<LocalDate>, tagFilter: Set<String>): Flow<List<MemoDto>>
public fun pageByDateRange(owner: String?, dateRange: ClosedRange<LocalDate>, tagFilter: Set<String>): Flow<List<MemoDto>>

public fun find(memoId: String, filterNotDelete: Boolean): Flow<MemoDto?>
public fun find(memoId: String): Flow<MemoDto?>

public fun findMemoAndTagIdsByIds(memoIds: Set<String>, filterNotDelete: Boolean): Flow<List<MemoAndTagIds>>
public fun findMemoAndTagIdsByIds(memoIds: Set<String>): Flow<List<MemoAndTagIds>>

public fun getLastServerUpdateAt(owner: String?): Flow<Instant?>
}
Loading

0 comments on commit 7a1d43b

Please sign in to comment.