Skip to content

Commit

Permalink
Merge pull request #224 from mhss1/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
mhss1 authored Sep 9, 2024
2 parents 72ec184 + 0a73589 commit 8b68b02
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ sealed interface AssistantEvent {
data class SendMessage(val message: AiMessage): AssistantEvent
data class SearchNotes(val query: String) : AssistantEvent
data class SearchTasks(val query: String) : AssistantEvent
data class AddAttachmentNote(val id: Int): AssistantEvent
data class AddAttachmentTask(val id: Int): AssistantEvent
data object AddAttachmentEvents: AssistantEvent
data class RemoveAttachment(val index: Int): AssistantEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
Expand Down Expand Up @@ -62,17 +62,15 @@ import org.koin.androidx.compose.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AssistantScreen(
viewModel: AssistantViewModel = koinViewModel()
viewModel: AssistantViewModel = koinViewModel(),
) {
val context = LocalContext.current
val uiState = viewModel.uiState
val messages = uiState.messages
val loading = uiState.loading
val error = uiState.error
var text by rememberSaveable { mutableStateOf("") }
val attachments = remember {
mutableStateListOf<AiMessageAttachment>()
}
val attachments = viewModel.attachments
var attachmentsMenuExpanded by remember {
mutableStateOf(false)
}
Expand All @@ -88,7 +86,7 @@ fun AssistantScreen(
val keyboardController = LocalSoftwareKeyboardController.current
Scaffold(
topBar = {
MyBrainAppBar(stringResource(id = R.string.assistant))
MyBrainAppBar(stringResource(id = R.string.assistant))
},
bottomBar = {
AiChatBar(
Expand All @@ -97,7 +95,11 @@ fun AssistantScreen(
attachments = attachments,
onTextChange = { text = it },
onAttachClick = { attachmentsMenuExpanded = true },
onRemoveAttachment = { attachments.removeAt(it) },
onRemoveAttachment = {
viewModel.onEvent(
AssistantEvent.RemoveAttachment(it)
)
},
loading = loading,
onSend = {
viewModel.onEvent(
Expand All @@ -111,28 +113,28 @@ fun AssistantScreen(
)
)
text = ""
attachments.clear()
keyboardController?.hide()
}
)
val excludedItems by remember {
derivedStateOf {
if (attachments.contains(AiMessageAttachment.CalenderEvents)) {
listOf(AttachmentMenuItem.CalendarEvents)
} else {
emptyList()
}
}
}
AttachmentDropDownMenu(
modifier = Modifier.fillMaxWidth(),
expanded = attachmentsMenuExpanded,
onDismiss = { attachmentsMenuExpanded = false },
excludedItems = attachments.map {
when (it) {
is AiMessageAttachment.Note -> AttachmentMenuItem.Note
is AiMessageAttachment.Task -> AttachmentMenuItem.Task
is AiMessageAttachment.CalenderEvents -> AttachmentMenuItem.CalendarEvents
}
},
excludedItems = excludedItems,
onItemClick = {
when (it) {
AttachmentMenuItem.Note -> openNoteSheet = true
AttachmentMenuItem.Task -> openTaskSheet = true
AttachmentMenuItem.CalendarEvents -> attachments.add(
AiMessageAttachment.CalenderEvents
)
AttachmentMenuItem.CalendarEvents -> viewModel.onEvent(AssistantEvent.AddAttachmentEvents)
}
attachmentsMenuExpanded = false
}
Expand All @@ -146,7 +148,7 @@ fun AssistantScreen(
view = uiState.noteView,
onQueryChange = { viewModel.onEvent(AssistantEvent.SearchNotes(it)) }
) {
attachments.add(AiMessageAttachment.Note(it))
viewModel.onEvent(AssistantEvent.AddAttachmentNote(it.id))
openNoteSheet = false
}
if (openTaskSheet) AttachTaskSheet(
Expand All @@ -155,7 +157,7 @@ fun AssistantScreen(
tasks = uiState.searchTasks,
onQueryChange = { viewModel.onEvent(AssistantEvent.SearchTasks(it)) }
) {
attachments.add(AiMessageAttachment.Task(it))
viewModel.onEvent(AssistantEvent.AddAttachmentTask(it.id))
openTaskSheet = false
}
Column(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mhss.app.presentation

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
Expand All @@ -12,6 +13,8 @@ import com.mhss.app.domain.model.CalendarEvent
import com.mhss.app.domain.model.Note
import com.mhss.app.domain.model.Task
import com.mhss.app.domain.use_case.GetAllEventsUseCase
import com.mhss.app.domain.use_case.GetNoteUseCase
import com.mhss.app.domain.use_case.GetTaskByIdUseCase
import com.mhss.app.domain.use_case.SearchNotesUseCase
import com.mhss.app.domain.use_case.SearchTasksUseCase
import com.mhss.app.domain.use_case.SendAiMessageUseCase
Expand Down Expand Up @@ -49,10 +52,13 @@ class AssistantViewModel(
private val getPreference: GetPreferenceUseCase,
private val searchNotes: SearchNotesUseCase,
private val searchTasks: SearchTasksUseCase,
private val getCalendarEvents: GetAllEventsUseCase
private val getCalendarEvents: GetAllEventsUseCase,
private val getNoteById: GetNoteUseCase,
private val getTaskById: GetTaskByIdUseCase,
) : ViewModel() {

private val messages = ArrayList<AiMessage>()
val attachments = mutableStateListOf<AiMessageAttachment>()

// LinkedList to enable inserting at the beginning of the list efficiently
// LazyColumn needs the list in reverse order
Expand Down Expand Up @@ -132,6 +138,7 @@ class AssistantViewModel(
)
messages.add(message)
uiMessages.addFirst(message)
attachments.clear()

uiState = uiState.copy(
messages = uiMessages,
Expand Down Expand Up @@ -186,6 +193,25 @@ class AssistantViewModel(
}
}
}

AssistantEvent.AddAttachmentEvents -> {
attachments.add(AiMessageAttachment.CalenderEvents)
}

is AssistantEvent.AddAttachmentNote -> viewModelScope.launch {
val note = getNoteById(event.id)
attachments.add(AiMessageAttachment.Note(note.copy(
title = note.title.ifBlank { "Untitled Note" }
)))
}

is AssistantEvent.AddAttachmentTask -> viewModelScope.launch {
attachments.add(AiMessageAttachment.Task(getTaskById(event.id)))
}

is AssistantEvent.RemoveAttachment -> {
attachments.removeAt(event.index)
}
}
}

Expand All @@ -197,12 +223,12 @@ class AssistantViewModel(
for (attachment in attachments) {
when (attachment) {
is AiMessageAttachment.Note -> {
builder.appendLine("Attached Notes:")
builder.appendLine("Attached Note:")
builder.appendLine(Json.encodeToString(attachment.note))
}

is AiMessageAttachment.Task -> {
builder.appendLine("Attached Tasks:")
builder.appendLine("Attached Task:")
builder.appendLine(Json.encodeToString(attachment.task))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ContextualFlowRow
import androidx.compose.foundation.layout.ContextualFlowRowOverflow
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
Expand All @@ -20,8 +20,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
Expand Down Expand Up @@ -69,36 +68,34 @@ fun AiAttachmentsSection(
editable: Boolean = false,
) {
if (editable) {
LazyRow(
Row(
modifier = modifier
.fillMaxWidth()
.padding(top = 5.dp, end = 5.dp),
verticalAlignment = Alignment.CenterVertically,
contentPadding = PaddingValues(start = 8.dp, bottom = 8.dp)
.padding(top = 5.dp, end = 5.dp)
.horizontalScroll(rememberScrollState()),
) {
itemsIndexed(attachments) {i, it ->
when (it) {
is AiMessageAttachment.Note -> NoteAttachmentCard(
note = it.note,
modifier = Modifier.animateItem(),
showRemoveButton = true
) {
onRemove(i)
}
is AiMessageAttachment.Task -> TaskAttachmentCard(
task = it.task,
modifier = Modifier.animateItem(),
showRemoveButton = true
) {
onRemove(i)
}
is AiMessageAttachment.CalenderEvents -> CalendarEventsAttachmentCard(
showRemoveButton = true,
modifier = Modifier.animateItem()
) {
onRemove(i)
}
attachments.forEachIndexed { i, it ->
when (it) {
is AiMessageAttachment.Note -> NoteAttachmentCard(
note = it.note,
showRemoveButton = true
) {
onRemove(i)
}

is AiMessageAttachment.Task -> TaskAttachmentCard(
task = it.task,
showRemoveButton = true
) {
onRemove(i)
}

is AiMessageAttachment.CalenderEvents -> CalendarEventsAttachmentCard(
showRemoveButton = true,
) {
onRemove(i)
}
}
}
}
} else {
Expand Down Expand Up @@ -126,10 +123,7 @@ fun AiAttachmentsSection(
collapseIndicator = {}
)
) { i ->
val attachment = remember {
attachments[i]
}
when (attachment) {
when (val attachment = attachments[i]) {
is AiMessageAttachment.Note -> NoteAttachmentCard(attachment.note)
is AiMessageAttachment.Task -> TaskAttachmentCard(attachment.task)
is AiMessageAttachment.CalenderEvents -> CalendarEventsAttachmentCard()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
Expand All @@ -18,14 +19,17 @@ fun AttachmentDropDownMenu(
excludedItems: List<AttachmentMenuItem>,
onDismiss: () -> Unit,
onItemClick: (AttachmentMenuItem) -> Unit,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
val items = remember(excludedItems) {
AttachmentMenuItem.entries.filterNot { it in excludedItems }
}
DropdownMenu(
modifier = modifier,
expanded = expanded,
onDismissRequest = onDismiss
) {
AttachmentMenuItem.entries.filter { it !in excludedItems }.forEach {
items.forEach {
DropdownMenuItem(
text = { Text(stringResource(it.titleRes)) },
leadingIcon = {
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId = "com.mhss.app.mybrain"
minSdk = 26
targetSdk = 35
versionCode = 9
versionName = "2.0.0"
versionCode = 10
versionName = "2.0.1"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ class DBConverters {
}
@TypeConverter
fun toSubTasksList(value: String): List<SubTask> {
return Json.decodeFromString<List<SubTask>>(value)
val json = Json {
ignoreUnknownKeys = true
}
return json.decodeFromString<List<SubTask>>(value)
}

@TypeConverter
Expand Down
2 changes: 2 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/10.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added the ability to choose which spaces to export
- Bug fixes
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ class BackupRepositoryImpl(
@OptIn(ExperimentalSerializationApi::class)
override suspend fun exportDatabase(
directoryUri: String,
exportNotes: Boolean,
exportTasks: Boolean,
exportDiary: Boolean,
exportBookmarks: Boolean,
encrypted: Boolean, // To be added in a future version
password: String // To be added in a future version
): Boolean {
Expand All @@ -43,11 +47,11 @@ class BackupRepositoryImpl(
val pickedDir = DocumentFile.fromTreeUri(context, directoryUri.toUri())
val destination = pickedDir!!.createFile("application/json", fileName)

val notes = database.noteDao().getAllNotes()
val noteFolders = database.noteDao().getAllNoteFolders().first()
val tasks = database.taskDao().getAllTasks().first()
val diary = database.diaryDao().getAllEntries().first()
val bookmarks = database.bookmarkDao().getAllBookmarks().first()
val notes = if (exportNotes) database.noteDao().getAllNotes() else emptyList()
val noteFolders = if (exportNotes) database.noteDao().getAllNoteFolders().first() else emptyList()
val tasks = if (exportTasks) database.taskDao().getAllTasks().first() else emptyList()
val diary = if (exportDiary) database.diaryDao().getAllEntries().first() else emptyList()
val bookmarks = if (exportBookmarks) database.bookmarkDao().getAllBookmarks().first() else emptyList()

val backupData = BackupData(notes, noteFolders, tasks, diary, bookmarks)

Expand Down Expand Up @@ -115,10 +119,10 @@ class BackupRepositoryImpl(

@Serializable
private data class BackupData(
@SerialName("notes") val notes: List<NoteEntity>,
@SerialName("noteFolders") val noteFolders: List<NoteFolderEntity>,
@SerialName("tasks") val tasks: List<TaskEntity>,
@SerialName("diary") val diary: List<DiaryEntryEntity>,
@SerialName("bookmarks") val bookmarks: List<BookmarkEntity>
@SerialName("notes") val notes: List<NoteEntity> = emptyList(),
@SerialName("noteFolders") val noteFolders: List<NoteFolderEntity> = emptyList(),
@SerialName("tasks") val tasks: List<TaskEntity> = emptyList(),
@SerialName("diary") val diary: List<DiaryEntryEntity> = emptyList(),
@SerialName("bookmarks") val bookmarks: List<BookmarkEntity> = emptyList()
)
}
Loading

0 comments on commit 8b68b02

Please sign in to comment.