From 4a794c167dc5c5bbf0db8f5eb4e409e470d7f988 Mon Sep 17 00:00:00 2001 From: "M. Utku Ensert" Date: Sat, 24 Aug 2024 10:35:19 +0300 Subject: [PATCH 01/35] Add gradle kts files --- app/build.gradle | 71 --------------------------------------- app/build.gradle.kts | 65 +++++++++++++++++++++++++++++++++++ build.gradle | 23 ------------- build.gradle.kts | 7 ++++ gradle.properties | 4 ++- gradle/libs.versions.toml | 35 +++++++++++++++++++ settings.gradle | 10 ------ settings.gradle.kts | 23 +++++++++++++ 8 files changed, 133 insertions(+), 105 deletions(-) delete mode 100644 app/build.gradle create mode 100644 app/build.gradle.kts delete mode 100644 build.gradle create mode 100644 build.gradle.kts create mode 100644 gradle/libs.versions.toml delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index c5c01e7..0000000 --- a/app/build.gradle +++ /dev/null @@ -1,71 +0,0 @@ -plugins { - id 'com.android.application' - id 'kotlin-android' - id "androidx.navigation.safeargs.kotlin" - id 'kotlin-kapt' - id 'com.google.devtools.ksp' -} - -android { - compileSdk 34 - - defaultConfig { - applicationId "com.mutkuensert.highlightandnote" - minSdk 23 - targetSdk 34 - versionCode 5 - versionName "1.0.4" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - viewBinding true - } - namespace 'com.mutkuensert.highlightandnote' -} - -dependencies { - - implementation 'androidx.core:core-ktx:1.13.1' - implementation 'androidx.appcompat:appcompat:1.7.0' - implementation 'com.google.android.material:material:1.12.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'androidx.legacy:legacy-support-v4:1.0.0' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.2.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' - - def roomVersion = "2.6.1" - def lifecycle_version = "2.8.4" - def nav_version = "2.7.7" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3" - - implementation("androidx.room:room-runtime:$roomVersion") - - // To use Kotlin annotation processing tool (kapt) - ksp("androidx.room:room-compiler:$roomVersion") - implementation("androidx.room:room-ktx:$roomVersion") - - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" - implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" - implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version") - ksp("androidx.lifecycle:lifecycle-compiler:$lifecycle_version") - - implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" - implementation "androidx.navigation:navigation-ui-ktx:$nav_version" - -} \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..ec73eed --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,65 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.jetbrains.kotlin.android) + alias(libs.plugins.dagger.hilt.android) + alias(libs.plugins.kotlin.ksp) + alias(libs.plugins.compose.compiler.plugin) +} + +android { + namespace = "com.mutkuensert.highlightandnote" + compileSdk = 34 + + defaultConfig { + applicationId = "com.mutkuensert.highlightandnote" + minSdk = 23 + targetSdk = 34 + versionCode = 5 + versionName = "1.0.4" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = true + isShrinkResources = true + + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + + buildFeatures { + viewBinding = true + compose = true + } +} + +dependencies { + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + + implementation(platform(libs.compose.bom)) + implementation(libs.compose.material3) + implementation(libs.compose.preview) + + implementation(libs.androidx.activity) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + + implementation(libs.dagger.hilt) + ksp(libs.dagger.hilt.compiler) + + implementation(libs.navigation.ui) +} \ No newline at end of file diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 66017b0..0000000 --- a/build.gradle +++ /dev/null @@ -1,23 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -buildscript { - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:8.5.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24" - - def nav_version = '2.7.7' - classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" - - } -} - -plugins { - id("com.google.devtools.ksp") version "1.9.24-1.0.20" apply false -} - -tasks.register('clean', Delete) { - delete rootProject.layout.buildDirectory -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..8044f22 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,7 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + alias(libs.plugins.android.application) apply false + alias(libs.plugins.jetbrains.kotlin.android) apply false + alias(libs.plugins.dagger.hilt.android) apply false + alias(libs.plugins.kotlin.ksp) apply false +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 98bed16..c56aebb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,6 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +kotlin.code.style=official + +KotlinVersion = 2.0.20 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..9cc3071 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,35 @@ +[versions] +activity = "1.9.1" +agp = "8.4.2" +appcompat = "1.7.0" +coreKtx = "1.13.1" +composeBom = "2024.08.00" +dagger = "2.51" +espressoCore = "3.6.1" +junit = "4.13.2" +junitVersion = "1.2.1" +kotlin = "2.0.20" +kotlinKsp = "2.0.20-1.0.24" +navigation = "2.8.0-rc01" + +[libraries] +androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } +compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +compose-material3 = { group = "androidx.compose.material3", name = "material3" } +compose-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +dagger-hilt = { group = "com.google.dagger", name = "hilt-android", version.ref = "dagger" } +dagger-hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "dagger" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +navigation-ui = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigation" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +compose-compiler-plugin = { id = "org.jetbrains.kotlin.plugin.compose" , version.ref = "kotlin"} +dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "dagger" } +jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-ksp = { id = "com.google.devtools.ksp", version.ref = "kotlinKsp" } + diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 6ba2d7a..0000000 --- a/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - jcenter() // Warning: this repository is going to shut down soon - } -} -rootProject.name = "Highlight and Note" -include ':app' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..281bb16 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,23 @@ +pluginManagement { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "Highlight and Note" +include(":app") From 8bcdc3d6be8296a07eca91b667e4c7dfacba0dc1 Mon Sep 17 00:00:00 2001 From: "M. Utku Ensert" Date: Sat, 24 Aug 2024 17:00:40 +0300 Subject: [PATCH 02/35] Add kotlin serialization and HomeRoute --- app/build.gradle.kts | 6 ++ app/src/main/AndroidManifest.xml | 2 +- .../highlightandnote/home/HomeRoute.kt | 6 ++ .../highlightandnote/home/HomeScreen.kt | 12 ++++ .../highlightandnote/home/HomeViewModel.kt | 37 ++++++++++++ .../highlightandnote/main/MainActivity.kt | 34 +++++++++++ .../highlightandnote/main/MainRoute.kt | 6 ++ .../highlightandnote/theme/Color.kt | 11 ++++ .../highlightandnote/theme/Theme.kt | 57 +++++++++++++++++++ .../highlightandnote/theme/Type.kt | 34 +++++++++++ .../highlightandnote/view/MainActivity.kt | 13 ----- .../viewmodel/MainFragmentViewModel.kt | 11 ---- app/src/main/res/layout/activity_main.xml | 2 +- gradle/libs.versions.toml | 11 +++- 14 files changed, 214 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/home/HomeRoute.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/main/MainRoute.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/theme/Color.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/theme/Theme.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/theme/Type.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/view/MainActivity.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ec73eed..7a5c3c0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,7 @@ plugins { alias(libs.plugins.dagger.hilt.android) alias(libs.plugins.kotlin.ksp) alias(libs.plugins.compose.compiler.plugin) + alias(libs.plugins.kotlin.serialization) } android { @@ -48,10 +49,13 @@ android { dependencies { implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) + implementation(libs.androidx.activity.compose) implementation(platform(libs.compose.bom)) implementation(libs.compose.material3) implementation(libs.compose.preview) + implementation(libs.compose.navigation) + implementation((libs.compose.view.model)) implementation(libs.androidx.activity) testImplementation(libs.junit) @@ -62,4 +66,6 @@ dependencies { ksp(libs.dagger.hilt.compiler) implementation(libs.navigation.ui) + + implementation(libs.kotlin.serialization) } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a7f05b4..f693171 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,7 @@ android:supportsRtl="true" android:theme="@style/Theme.HighlightAndNote"> diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeRoute.kt b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeRoute.kt new file mode 100644 index 0000000..dbaa62a --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeRoute.kt @@ -0,0 +1,6 @@ +package com.mutkuensert.highlightandnote.home + +import kotlinx.serialization.Serializable + +@Serializable +data class HomeRoute(val receivedText: String? = null) diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt new file mode 100644 index 0000000..34315c3 --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt @@ -0,0 +1,12 @@ +package com.mutkuensert.highlightandnote.home + +import androidx.compose.runtime.Composable +import androidx.lifecycle.viewmodel.compose.viewModel + +@Composable +fun HomeScreen( + navigateToNote: (id: Int) -> Unit, + viewModel: HomeViewModel = viewModel() +) { + +} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt new file mode 100644 index 0000000..d0fcf33 --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt @@ -0,0 +1,37 @@ +package com.mutkuensert.highlightandnote.home + +import android.content.Context +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.mutkuensert.highlightandnote.model.NoteClass +import com.mutkuensert.highlightandnote.service.NoteDAO +import com.mutkuensert.highlightandnote.service.NoteDatabase +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch + +@HiltViewModel +class HomeViewModel : ViewModel() { + private val _notes = MutableStateFlow>(emptyList()) + val notes: StateFlow> get() = _notes + + private lateinit var dao: NoteDAO + + fun initScreen(context: Context) { + createDataAccessObject(context) + getNotes() + } + + private fun createDataAccessObject(context: Context) { + dao = NoteDatabase(context).noteDao() + } + + fun getNotes() { + viewModelScope.launch(Dispatchers.IO) { + _notes.update { dao.getAll() } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt new file mode 100644 index 0000000..d80520d --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt @@ -0,0 +1,34 @@ +package com.mutkuensert.highlightandnote.main + +import android.os.Bundle +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.mutkuensert.androidsignatureexample.ui.theme.HighlightAndNoteTheme +import com.mutkuensert.highlightandnote.home.HomeRoute +import com.mutkuensert.highlightandnote.home.HomeScreen + +class MainActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + + setContent { + HighlightAndNoteTheme { + val navController = rememberNavController() + + NavHost( + navController = navController, + startDestination = HomeRoute + ) { + composable{ + HomeScreen() + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/main/MainRoute.kt b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainRoute.kt new file mode 100644 index 0000000..5caa34e --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainRoute.kt @@ -0,0 +1,6 @@ +package com.mutkuensert.highlightandnote.main + +import kotlinx.serialization.Serializable + +@Serializable +class MainRoute() diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/theme/Color.kt b/app/src/main/java/com/mutkuensert/highlightandnote/theme/Color.kt new file mode 100644 index 0000000..003e57b --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/theme/Color.kt @@ -0,0 +1,11 @@ +package com.mutkuensert.androidsignatureexample.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/theme/Theme.kt b/app/src/main/java/com/mutkuensert/highlightandnote/theme/Theme.kt new file mode 100644 index 0000000..761e325 --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/theme/Theme.kt @@ -0,0 +1,57 @@ +package com.mutkuensert.androidsignatureexample.ui.theme + +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun HighlightAndNoteTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/theme/Type.kt b/app/src/main/java/com/mutkuensert/highlightandnote/theme/Type.kt new file mode 100644 index 0000000..ac38da8 --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/theme/Type.kt @@ -0,0 +1,34 @@ +package com.mutkuensert.androidsignatureexample.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/view/MainActivity.kt b/app/src/main/java/com/mutkuensert/highlightandnote/view/MainActivity.kt deleted file mode 100644 index a5e6a34..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/view/MainActivity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.mutkuensert.highlightandnote.view - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle -import com.mutkuensert.highlightandnote.R - -class MainActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/MainFragmentViewModel.kt b/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/MainFragmentViewModel.kt index 5a19069..fdf8bf2 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/MainFragmentViewModel.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/MainFragmentViewModel.kt @@ -11,17 +11,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch class MainFragmentViewModel: ViewModel() { - val notes = MutableLiveData>() - lateinit var dao: NoteDAO - fun createDataAccessObject(context: Context){ - dao = NoteDatabase(context).noteDao() - } - - fun getNotes(){ - viewModelScope.launch(Dispatchers.IO) { - notes.postValue(dao.getAll()) - } - } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index dbf7843..81dd0fd 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".view.MainActivity"> + tools:context=".main.MainActivity"> Date: Sat, 24 Aug 2024 23:52:11 +0300 Subject: [PATCH 03/35] Inject dao through dagger --- app/build.gradle.kts | 4 +- .../adapter/NotesRecyclerAdapter.kt | 48 ----- .../highlightandnote/data/NoteDAO.kt | 27 +++ .../highlightandnote/data/NoteDatabase.kt | 10 ++ .../highlightandnote/di/NoteModule.kt | 33 ++++ .../highlightandnote/home/HomeScreen.kt | 48 ++++- .../highlightandnote/home/HomeViewModel.kt | 22 +-- .../highlightandnote/main/MainActivity.kt | 69 ++++++- .../highlightandnote/model/NoteClass.kt | 6 +- .../notedetail/DetailViewModel.kt | 42 +++++ .../highlightandnote/service/NoteDAO.kt | 23 --- .../highlightandnote/service/NoteDatabase.kt | 26 --- .../service/SingletonClass.kt | 9 - .../highlightandnote/util/Constants.kt | 6 - .../highlightandnote/view/DetailFragment.kt | 170 ------------------ .../highlightandnote/view/MainFragment.kt | 139 -------------- .../viewmodel/DetailFragmentViewModel.kt | 50 ------ .../viewmodel/MainFragmentViewModel.kt | 16 -- gradle/libs.versions.toml | 2 + 19 files changed, 235 insertions(+), 515 deletions(-) delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/adapter/NotesRecyclerAdapter.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDAO.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDatabase.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/di/NoteModule.kt create mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/notedetail/DetailViewModel.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/service/NoteDAO.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/service/NoteDatabase.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/service/SingletonClass.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/util/Constants.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/view/DetailFragment.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/view/MainFragment.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/DetailFragmentViewModel.kt delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/MainFragmentViewModel.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7a5c3c0..c083db5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { implementation(libs.compose.material3) implementation(libs.compose.preview) implementation(libs.compose.navigation) - implementation((libs.compose.view.model)) + implementation(libs.compose.view.model) implementation(libs.androidx.activity) testImplementation(libs.junit) @@ -68,4 +68,6 @@ dependencies { implementation(libs.navigation.ui) implementation(libs.kotlin.serialization) + + implementation(libs.room) } \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/adapter/NotesRecyclerAdapter.kt b/app/src/main/java/com/mutkuensert/highlightandnote/adapter/NotesRecyclerAdapter.kt deleted file mode 100644 index af4d9ec..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/adapter/NotesRecyclerAdapter.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.mutkuensert.highlightandnote.adapter - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.navigation.Navigation -import androidx.recyclerview.widget.RecyclerView -import com.mutkuensert.highlightandnote.databinding.NotesRowBinding -import com.mutkuensert.highlightandnote.model.NoteClass -import com.mutkuensert.highlightandnote.util.FROM_APP_AND_RECYCLERVIEW -import com.mutkuensert.highlightandnote.util.FROM_INTENT_AND_RECYCLERVIEW -import com.mutkuensert.highlightandnote.view.MainFragmentDirections - -class NotesRecyclerAdapter(val notes : ArrayList) : RecyclerView.Adapter(){ - var fromIntentOrApp: Int = FROM_APP_AND_RECYCLERVIEW - class NotesViewHolder(val binding : NotesRowBinding): RecyclerView.ViewHolder(binding.root) { - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotesViewHolder { - val binding = NotesRowBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return NotesViewHolder(binding) - } - - override fun onBindViewHolder(holder: NotesViewHolder, position: Int) { - holder.binding.textView.text = notes.get(position).note - - holder.itemView.setOnClickListener { - val action = MainFragmentDirections.actionMainFragmentToDetailFragment(notes.get(position).uid, fromIntentOrApp) - Navigation.findNavController(it).navigate(action) - } - } - - override fun getItemCount(): Int { - return notes.size - } - fun appHasBeenExecutedByIntent(isTrue: Boolean){ - if(isTrue){ - fromIntentOrApp = FROM_INTENT_AND_RECYCLERVIEW - }else{ - fromIntentOrApp = FROM_APP_AND_RECYCLERVIEW - } - } - - fun submitList(newListOfNote : List){ - notes.clear() - notes.addAll(newListOfNote) - notifyDataSetChanged() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDAO.kt b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDAO.kt new file mode 100644 index 0000000..0666344 --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDAO.kt @@ -0,0 +1,27 @@ +package com.mutkuensert.highlightandnote.data + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.Query +import androidx.room.Update +import com.mutkuensert.highlightandnote.model.NoteClass + +@Dao +interface NoteDAO { + + @Query("SELECT * FROM noteclass ORDER BY uid DESC") + suspend fun getAll(): List + + @Query("SELECT * FROM noteclass WHERE uid IN (:noteId)") + suspend fun loadById(noteId: Int): NoteClass + + @Insert + suspend fun insert(vararg notes: NoteClass) + + @Update + suspend fun update(vararg note: NoteClass) + + @Delete + suspend fun delete(uid: Int) +} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDatabase.kt b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDatabase.kt new file mode 100644 index 0000000..95073f9 --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDatabase.kt @@ -0,0 +1,10 @@ +package com.mutkuensert.highlightandnote.data + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.mutkuensert.highlightandnote.model.NoteClass + +@Database(entities = [NoteClass::class], version = 1) +abstract class NoteDatabase : RoomDatabase() { + abstract fun noteDao(): NoteDAO +} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/di/NoteModule.kt b/app/src/main/java/com/mutkuensert/highlightandnote/di/NoteModule.kt new file mode 100644 index 0000000..5fe7239 --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/di/NoteModule.kt @@ -0,0 +1,33 @@ +package com.mutkuensert.highlightandnote.di + +import android.content.Context +import androidx.room.Room +import com.mutkuensert.highlightandnote.data.NoteDAO +import com.mutkuensert.highlightandnote.data.NoteDatabase +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +interface NoteModule { + + @Provides + @Singleton + fun provideNoteDatabase(@ApplicationContext context: Context): NoteDatabase { + return Room.databaseBuilder( + context.applicationContext, + NoteDatabase::class.java, + "notedatabase" + ).build() + } + + @Provides + @Singleton + fun provideNoteDao(database: NoteDatabase): NoteDAO { + return database.noteDao() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt index 34315c3..43d7329 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt @@ -1,12 +1,58 @@ package com.mutkuensert.highlightandnote.home +import androidx.compose.foundation.clickable +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel +import com.mutkuensert.highlightandnote.model.NoteClass @Composable fun HomeScreen( - navigateToNote: (id: Int) -> Unit, + onNavigateToNote: (id: Int) -> Unit, + selectedText: String? = null, viewModel: HomeViewModel = viewModel() ) { + val notes by viewModel.notes.collectAsStateWithLifecycle() + Home(notes, onNavigateToNote) + + LaunchedEffect(Unit) { + viewModel.getNotes() + } +} + +@Composable +private fun Home( + notes: List, + onClickNote: (id: Int) -> Unit +) { + LazyColumn { + items(notes.size) { + val note = notes[it] + + if (note.note != null) { + Text( + modifier = Modifier.clickable { onClickNote.invoke(note.uid) }, + text = note.note + ) + } + } + } +} + +@Preview +@Composable +private fun HomePreview() { + val fakeNotes = listOf( + NoteClass("First note"), + NoteClass("First note") + ) + + Home(fakeNotes, {}) } \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt index d0fcf33..21aa249 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt @@ -1,33 +1,21 @@ package com.mutkuensert.highlightandnote.home -import android.content.Context import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.mutkuensert.highlightandnote.data.NoteDAO import com.mutkuensert.highlightandnote.model.NoteClass -import com.mutkuensert.highlightandnote.service.NoteDAO -import com.mutkuensert.highlightandnote.service.NoteDatabase import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @HiltViewModel -class HomeViewModel : ViewModel() { +class HomeViewModel @Inject constructor(private val dao: NoteDAO) : ViewModel() { private val _notes = MutableStateFlow>(emptyList()) - val notes: StateFlow> get() = _notes - - private lateinit var dao: NoteDAO - - fun initScreen(context: Context) { - createDataAccessObject(context) - getNotes() - } - - private fun createDataAccessObject(context: Context) { - dao = NoteDatabase(context).noteDao() - } + val notes = _notes.asStateFlow() fun getNotes() { viewModelScope.launch(Dispatchers.IO) { diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt index d80520d..cc09be8 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt @@ -1,13 +1,26 @@ package com.mutkuensert.highlightandnote.main +import android.content.Intent import android.os.Bundle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.SnackbarResult +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.navigation.NavController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.mutkuensert.androidsignatureexample.ui.theme.HighlightAndNoteTheme +import com.mutkuensert.highlightandnote.R import com.mutkuensert.highlightandnote.home.HomeRoute import com.mutkuensert.highlightandnote.home.HomeScreen @@ -19,16 +32,60 @@ class MainActivity : AppCompatActivity() { setContent { HighlightAndNoteTheme { val navController = rememberNavController() + val snackbarHostState = remember { SnackbarHostState() } - NavHost( - navController = navController, - startDestination = HomeRoute - ) { - composable{ - HomeScreen() + Scaffold( + snackbarHost = { + SnackbarHost(hostState = snackbarHostState) + }) { + NavHost( + modifier = Modifier.padding(it), + navController = navController, + startDestination = HomeRoute + ) { + composable { + HomeScreen({}, getSelectedText()) + } } } + + SelectedTextHandler(snackbarHostState, navController) + } + } + } + + @Composable + private fun SelectedTextHandler( + snackbarHostState: SnackbarHostState, + navController: NavController + ) { + LaunchedEffect(Unit) { + val selectedText = getSelectedText() + + if (selectedText != null) { + val result = snackbarHostState + .showSnackbar( + message = getString(R.string.snack_message), + actionLabel = getString(R.string.menu_new), + duration = SnackbarDuration.Indefinite + ) + + if (result == SnackbarResult.ActionPerformed) { + navController.navigate(HomeRoute(selectedText)) //To be detail route + } } } } + + private fun getSelectedText(): String? { + val action = intent.action + + if (action.equals(Intent.ACTION_PROCESS_TEXT) || action.equals(Intent.ACTION_SEND)) { + return intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT) + ?: intent.getStringExtra(Intent.EXTRA_TEXT) + + } + + return null + } } \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/model/NoteClass.kt b/app/src/main/java/com/mutkuensert/highlightandnote/model/NoteClass.kt index 5eafd8b..ab33689 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/model/NoteClass.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/model/NoteClass.kt @@ -7,8 +7,8 @@ import androidx.room.PrimaryKey @Entity data class NoteClass( @ColumnInfo(name = "note") - val note : String?) { - + val note: String? +) { @PrimaryKey(autoGenerate = true) - var uid : Int = 0 + var uid: Int = 0 } diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/notedetail/DetailViewModel.kt b/app/src/main/java/com/mutkuensert/highlightandnote/notedetail/DetailViewModel.kt new file mode 100644 index 0000000..6165f7b --- /dev/null +++ b/app/src/main/java/com/mutkuensert/highlightandnote/notedetail/DetailViewModel.kt @@ -0,0 +1,42 @@ +package com.mutkuensert.highlightandnote.notedetail + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.mutkuensert.highlightandnote.data.NoteDAO +import com.mutkuensert.highlightandnote.model.NoteClass +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch + +@HiltViewModel +class DetailViewModel constructor(private val dao: NoteDAO) : ViewModel() { + private val _uiModel = MutableStateFlow("") + val uiModel = _uiModel.asStateFlow() + + fun deleteNote(id: Int) { + viewModelScope.launch(Dispatchers.IO) { + dao.delete(id) + } + } + + fun getNote(id: Int) { + viewModelScope.launch(Dispatchers.IO) { + _uiModel.update { dao.loadById(id).note ?: "" } + } + } + + fun saveNewNote(text: String) { + viewModelScope.launch(Dispatchers.IO) { + dao.insert(NoteClass(text)) + } + } + + fun updateNote(id: Int, text: String) { + viewModelScope.launch(Dispatchers.IO) { + dao.update(NoteClass(text).apply { uid = id }) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/service/NoteDAO.kt b/app/src/main/java/com/mutkuensert/highlightandnote/service/NoteDAO.kt deleted file mode 100644 index 941088b..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/service/NoteDAO.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.mutkuensert.highlightandnote.service - -import androidx.room.* -import com.mutkuensert.highlightandnote.model.NoteClass - -@Dao -interface NoteDAO { - - @Query("SELECT * FROM noteclass ORDER BY uid DESC") - suspend fun getAll(): List - - @Query("SELECT * FROM noteclass WHERE uid IN (:noteId)") - suspend fun loadById(noteId: Int) : NoteClass - - @Insert - suspend fun insert(vararg notes : NoteClass) - - @Update - suspend fun update(vararg note : NoteClass) - - @Delete - suspend fun delete(note : NoteClass) -} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/service/NoteDatabase.kt b/app/src/main/java/com/mutkuensert/highlightandnote/service/NoteDatabase.kt deleted file mode 100644 index 68312a4..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/service/NoteDatabase.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.mutkuensert.highlightandnote.service - -import android.content.Context -import androidx.room.Database -import androidx.room.Room -import androidx.room.RoomDatabase -import com.mutkuensert.highlightandnote.model.NoteClass - -@Database(entities = [NoteClass::class], version = 1) -abstract class NoteDatabase : RoomDatabase() { - abstract fun noteDao() : NoteDAO - - companion object{ - @Volatile private var instance : NoteDatabase? = null - - private val lock = Any() - operator fun invoke(context: Context) = instance ?: synchronized(lock){ - instance ?: createDatabase(context).also { - instance = it - } - } - - private fun createDatabase(context: Context) = Room.databaseBuilder(context.applicationContext, - NoteDatabase::class.java,"notedatabase").build() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/service/SingletonClass.kt b/app/src/main/java/com/mutkuensert/highlightandnote/service/SingletonClass.kt deleted file mode 100644 index df1109c..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/service/SingletonClass.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.mutkuensert.highlightandnote.service - -class SingletonClass { - - companion object Arguments { - var receivedText : String? = null - var source : Int = 0 - } -} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/util/Constants.kt b/app/src/main/java/com/mutkuensert/highlightandnote/util/Constants.kt deleted file mode 100644 index dd86593..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/util/Constants.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mutkuensert.highlightandnote.util - -const val FROM_APP_AND_NEW_BUTTON = 0 -const val FROM_APP_AND_RECYCLERVIEW = 1 -const val FROM_INTENT_AND_SNACKBAR_NEW_BUTTON = 2 -const val FROM_INTENT_AND_RECYCLERVIEW = 3 \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/view/DetailFragment.kt b/app/src/main/java/com/mutkuensert/highlightandnote/view/DetailFragment.kt deleted file mode 100644 index 08fde8c..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/view/DetailFragment.kt +++ /dev/null @@ -1,170 +0,0 @@ -package com.mutkuensert.highlightandnote.view - -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.view.* -import android.widget.Toast -import androidx.fragment.app.Fragment -import androidx.activity.addCallback -import androidx.core.view.MenuHost -import androidx.core.view.MenuProvider -import androidx.core.widget.addTextChangedListener -import androidx.core.widget.doAfterTextChanged -import androidx.fragment.app.viewModels -import androidx.lifecycle.Lifecycle -import androidx.navigation.fragment.findNavController -import androidx.navigation.fragment.navArgs -import com.mutkuensert.highlightandnote.R -import com.mutkuensert.highlightandnote.databinding.FragmentDetailBinding -import com.mutkuensert.highlightandnote.model.NoteClass -import com.mutkuensert.highlightandnote.service.SingletonClass -import com.mutkuensert.highlightandnote.util.FROM_APP_AND_NEW_BUTTON -import com.mutkuensert.highlightandnote.util.FROM_APP_AND_RECYCLERVIEW -import com.mutkuensert.highlightandnote.util.FROM_INTENT_AND_RECYCLERVIEW -import com.mutkuensert.highlightandnote.util.FROM_INTENT_AND_SNACKBAR_NEW_BUTTON -import com.mutkuensert.highlightandnote.viewmodel.DetailFragmentViewModel - - -class DetailFragment : Fragment() { - private var _binding : FragmentDetailBinding? = null - private val binding get() = _binding!! - private val viewModel: DetailFragmentViewModel by viewModels() - private val args: DetailFragmentArgs by navArgs() - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - _binding = FragmentDetailBinding.inflate(inflater, container, false) - val view = binding.root - return view - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - viewModel.createDataAccessObject(requireContext()) - - setMenu() - setBackButtonCallback() - getNoteOrReceivedTextToScreen() - } - - override fun onPause() { - super.onPause() - viewModel.noteBackupForActivityDestruction = binding.editText.text.toString() - viewModel.cursorPositionBackupForActivityDestruction = binding.editText.selectionStart - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - - private fun setBackButtonCallback(){ - val callback = requireActivity().onBackPressedDispatcher.addCallback(this) { - - if(args.source == FROM_APP_AND_NEW_BUTTON){ - val action = DetailFragmentDirections.actionDetailFragmentToMainFragment() - if(binding.editText.text.isNotEmpty()){ - val newNote = NoteClass(binding.editText.text.toString()) - viewModel.newNote(newNote) - viewModel.processIsDone.observe(viewLifecycleOwner){ - if(it){ - Toast.makeText(context,R.string.note_saved,Toast.LENGTH_SHORT).show() - findNavController().navigate(action) - } - } - } else{ - findNavController().navigate(action) - } - - }else if(args.source == FROM_APP_AND_RECYCLERVIEW){ - val noteFromRecyclerView = NoteClass(binding.editText.text.toString()) - noteFromRecyclerView.uid = args.noteId - viewModel.updateNote(noteFromRecyclerView) - viewModel.processIsDone.observe(viewLifecycleOwner){ - if(it){ - Toast.makeText(context,R.string.note_saved,Toast.LENGTH_SHORT).show() - val action = DetailFragmentDirections.actionDetailFragmentToMainFragment() - findNavController().navigate(action) - } - } - - }else if(args.source == FROM_INTENT_AND_SNACKBAR_NEW_BUTTON){ - val newNote = NoteClass(binding.editText.text.toString()) - viewModel.newNote(newNote) - viewModel.processIsDone.observe(viewLifecycleOwner){ - if(it){ - Toast.makeText(context,R.string.note_saved,Toast.LENGTH_SHORT).show() - activity?.finish() - } - } - - }else if(args.source == FROM_INTENT_AND_RECYCLERVIEW){ - val newNote = NoteClass(binding.editText.text.toString()) - newNote.uid = args.noteId - viewModel.updateNote(newNote) - viewModel.processIsDone.observe(viewLifecycleOwner){ - if(it){ - Toast.makeText(context,R.string.note_saved,Toast.LENGTH_SHORT).show() - activity?.finish() - } - } - } - } - callback.isEnabled - } - - private fun getNoteOrReceivedTextToScreen(){ - - if(args.source == FROM_INTENT_AND_SNACKBAR_NEW_BUTTON){ - binding.editText.setText(SingletonClass.receivedText) - getEditTextStatesIfActivityDestroyed() - - }else if (args.source == FROM_APP_AND_RECYCLERVIEW){ - viewModel.getNote(args.noteId) - viewModel.note.observe(viewLifecycleOwner) { - binding.editText.setText(it.note) - getEditTextStatesIfActivityDestroyed() - } - }else if(args.source == FROM_INTENT_AND_RECYCLERVIEW){ - viewModel.getNote(args.noteId) - viewModel.note.observe(viewLifecycleOwner) { - val oldNoteAndNewText = it.note + "\n" + "\n${SingletonClass.receivedText}" - binding.editText.setText(oldNoteAndNewText) - getEditTextStatesIfActivityDestroyed() - } - } - } - - private fun getEditTextStatesIfActivityDestroyed(){ - viewModel.noteBackupForActivityDestruction?.let { binding.editText.setText(it) } - viewModel.cursorPositionBackupForActivityDestruction?.let { binding.editText.setSelection(it) } - } - - - private fun setMenu(){ - val menuHost: MenuHost = requireActivity() - menuHost.addMenuProvider(object: MenuProvider{ - override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { - if(!menu.hasVisibleItems()){menuInflater.inflate(R.menu.optionsmenu,menu)} - menu.findItem(R.id.deleteNote).isVisible = true - menu.findItem(R.id.newNote).isVisible = false - } - - override fun onMenuItemSelected(menuItem: MenuItem): Boolean { - if (menuItem.itemId == R.id.deleteNote) { - if (args.source == FROM_APP_AND_RECYCLERVIEW || args.source == FROM_INTENT_AND_RECYCLERVIEW) { - viewModel.deleteNote(viewModel.note.value!!) - Toast.makeText(context,R.string.note_deleted,Toast.LENGTH_SHORT).show() - } - val action = DetailFragmentDirections.actionDetailFragmentToMainFragment() - findNavController().navigate(action) - } - return true - } - }, viewLifecycleOwner, Lifecycle.State.RESUMED) - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/view/MainFragment.kt b/app/src/main/java/com/mutkuensert/highlightandnote/view/MainFragment.kt deleted file mode 100644 index a7e5e3c..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/view/MainFragment.kt +++ /dev/null @@ -1,139 +0,0 @@ -package com.mutkuensert.highlightandnote.view - -import android.content.Intent -import android.os.Bundle -import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import android.view.ViewGroup -import androidx.activity.addCallback -import androidx.core.view.MenuHost -import androidx.core.view.MenuProvider -import androidx.fragment.app.Fragment -import androidx.fragment.app.viewModels -import androidx.lifecycle.Lifecycle -import androidx.navigation.fragment.findNavController -import androidx.recyclerview.widget.LinearLayoutManager -import com.google.android.material.snackbar.Snackbar -import com.mutkuensert.highlightandnote.R -import com.mutkuensert.highlightandnote.adapter.NotesRecyclerAdapter -import com.mutkuensert.highlightandnote.databinding.FragmentMainBinding -import com.mutkuensert.highlightandnote.service.SingletonClass -import com.mutkuensert.highlightandnote.util.FROM_APP_AND_NEW_BUTTON -import com.mutkuensert.highlightandnote.util.FROM_INTENT_AND_SNACKBAR_NEW_BUTTON -import com.mutkuensert.highlightandnote.viewmodel.MainFragmentViewModel - - -class MainFragment : Fragment() { - private var _binding: FragmentMainBinding? = null - private val binding get() = _binding!! - private val viewModel: MainFragmentViewModel by viewModels() - private val recyclerAdapter = NotesRecyclerAdapter(arrayListOf()) - private var snackBar: Snackbar? = null - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = FragmentMainBinding.inflate(inflater, container, false) - val view = binding.root - return view - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - viewModel.createDataAccessObject(requireContext()) - - setMenus() - - val callback = requireActivity().onBackPressedDispatcher.addCallback(this) { - activity?.finish() - } - callback.isEnabled - - binding.recycler.layoutManager = LinearLayoutManager(context) - binding.recycler.adapter = recyclerAdapter - - viewModel.getNotes() - - observeLiveData() - checkIntent() - - } - - override fun onDestroyView() { - super.onDestroyView() - snackBar?.dismiss() - _binding = null - } - - private fun askToCreateNewNoteWithTheReceivedText() { - recyclerAdapter.appHasBeenExecutedByIntent(true) - snackBar = Snackbar.make(binding.root, R.string.snack_message, Snackbar.LENGTH_INDEFINITE) - .setAction(R.string.menu_new) { - val action = MainFragmentDirections.actionMainFragmentToDetailFragment( - 0, - FROM_INTENT_AND_SNACKBAR_NEW_BUTTON - ) //Note id is 0 because a new note is going to be created. - findNavController().navigate(action) - } - snackBar!!.show() - } - - private fun checkIntent() { - if (requireActivity().intent.action != null && - (requireActivity().intent.action.equals(Intent.ACTION_PROCESS_TEXT) || requireActivity().intent.action.equals( - Intent.ACTION_SEND - )) - ) { - - if (requireActivity().intent.hasExtra(Intent.EXTRA_PROCESS_TEXT)) { - SingletonClass.receivedText = - requireActivity().intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT) - askToCreateNewNoteWithTheReceivedText() - } else if (requireActivity().intent.hasExtra(Intent.EXTRA_TEXT)) { - SingletonClass.receivedText = - requireActivity().intent.getStringExtra(Intent.EXTRA_TEXT) - askToCreateNewNoteWithTheReceivedText() - } - } - } - - - private fun observeLiveData() { - viewModel.notes.observe(viewLifecycleOwner) { - recyclerAdapter.submitList(it) - } - } - - - private fun setMenus() { - val menuHost: MenuHost = requireActivity() - - menuHost.addMenuProvider(object : MenuProvider { - override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { - if (!menu.hasVisibleItems()) { - menuInflater.inflate(R.menu.optionsmenu, menu) - } - menu.findItem(R.id.newNote).isVisible = true - menu.findItem(R.id.deleteNote).isVisible = false - } - - override fun onMenuItemSelected(menuItem: MenuItem): Boolean { - if (menuItem.itemId == R.id.newNote) { - val action = MainFragmentDirections.actionMainFragmentToDetailFragment( - 0, - FROM_APP_AND_NEW_BUTTON - ) //noteId is 0 because this is not an existing note. - findNavController().navigate(action) - } - return true - } - - }, viewLifecycleOwner, Lifecycle.State.RESUMED) - } - - -} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/DetailFragmentViewModel.kt b/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/DetailFragmentViewModel.kt deleted file mode 100644 index 4a7ad06..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/DetailFragmentViewModel.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.mutkuensert.highlightandnote.viewmodel - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.mutkuensert.highlightandnote.model.NoteClass -import com.mutkuensert.highlightandnote.service.NoteDAO -import com.mutkuensert.highlightandnote.service.NoteDatabase -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class DetailFragmentViewModel: ViewModel() { - lateinit var dao: NoteDAO - val note = MutableLiveData() - val processIsDone = MutableLiveData(false) - var noteBackupForActivityDestruction: String? = null - var cursorPositionBackupForActivityDestruction: Int? = null - - fun createDataAccessObject(context: Context){ - dao = NoteDatabase(context).noteDao() - } - - - fun deleteNote(note: NoteClass){ - viewModelScope.launch(Dispatchers.IO) { - dao.delete(note) - processIsDone.postValue(true) - } - } - fun getNote(id: Int){ - viewModelScope.launch(Dispatchers.IO) { - note.postValue(dao.loadById(id)) - } - } - fun newNote(note : NoteClass){ - viewModelScope.launch(Dispatchers.IO) { - dao.insert(note) - processIsDone.postValue(true) - } - } - - fun updateNote(note : NoteClass){ - viewModelScope.launch(Dispatchers.IO) { - dao.update(note) - processIsDone.postValue(true) - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/MainFragmentViewModel.kt b/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/MainFragmentViewModel.kt deleted file mode 100644 index fdf8bf2..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/viewmodel/MainFragmentViewModel.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.mutkuensert.highlightandnote.viewmodel - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.mutkuensert.highlightandnote.model.NoteClass -import com.mutkuensert.highlightandnote.service.NoteDAO -import com.mutkuensert.highlightandnote.service.NoteDatabase -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class MainFragmentViewModel: ViewModel() { - - -} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 817b80f..d2fc15c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,6 +13,7 @@ kotlin = "2.0.20" kotlinKsp = "2.0.20-1.0.24" kotlinSerialization = "1.7.1" navigation = "2.8.0-rc01" +room = "2.6.1" [libraries] androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } @@ -31,6 +32,7 @@ dagger-hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", ve junit = { group = "junit", name = "junit", version.ref = "junit" } kotlin-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinSerialization" } navigation-ui = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigation" } +room = { group = "androidx.room", name = "room-runtime", version.ref = "room"} [plugins] android-application = { id = "com.android.application", version.ref = "agp" } From 3f3119fcd7a118082fb7748c29a490fca4ef2363 Mon Sep 17 00:00:00 2001 From: "M. Utku Ensert" Date: Sun, 25 Aug 2024 22:25:26 +0300 Subject: [PATCH 04/35] Complete Home ui design --- app/build.gradle.kts | 1 + .../{model => data}/NoteClass.kt | 2 +- .../highlightandnote/data/NoteDAO.kt | 1 - .../highlightandnote/data/NoteDatabase.kt | 1 - .../highlightandnote/home/HomeScreen.kt | 97 +++++++++++++++++-- .../highlightandnote/home/HomeViewModel.kt | 21 +++- .../highlightandnote/main/MainActivity.kt | 10 +- .../highlightandnote/main/MainRoute.kt | 6 -- .../notedetail/DetailViewModel.kt | 5 +- app/src/main/res/drawable/ic_add.xml | 4 - app/src/main/res/drawable/ic_delete.xml | 4 - app/src/main/res/drawable/rowdesign.xml | 40 -------- app/src/main/res/layout/activity_main.xml | 24 ----- app/src/main/res/layout/fragment_detail.xml | 19 ---- app/src/main/res/layout/fragment_main.xml | 15 --- app/src/main/res/layout/notes_row.xml | 23 ----- app/src/main/res/menu/optionsmenu.xml | 16 --- app/src/main/res/navigation/navi.xml | 34 ------- app/src/main/res/values-night/themes.xml | 21 ---- app/src/main/res/values/attrs.xml | 8 -- app/src/main/res/values/colors.xml | 10 -- app/src/main/res/values/themes.xml | 23 +---- gradle/libs.versions.toml | 2 + 23 files changed, 125 insertions(+), 262 deletions(-) rename app/src/main/java/com/mutkuensert/highlightandnote/{model => data}/NoteClass.kt (83%) delete mode 100644 app/src/main/java/com/mutkuensert/highlightandnote/main/MainRoute.kt delete mode 100644 app/src/main/res/drawable/ic_add.xml delete mode 100644 app/src/main/res/drawable/ic_delete.xml delete mode 100644 app/src/main/res/drawable/rowdesign.xml delete mode 100644 app/src/main/res/layout/activity_main.xml delete mode 100644 app/src/main/res/layout/fragment_detail.xml delete mode 100644 app/src/main/res/layout/fragment_main.xml delete mode 100644 app/src/main/res/layout/notes_row.xml delete mode 100644 app/src/main/res/menu/optionsmenu.xml delete mode 100644 app/src/main/res/navigation/navi.xml delete mode 100644 app/src/main/res/values-night/themes.xml delete mode 100644 app/src/main/res/values/attrs.xml delete mode 100644 app/src/main/res/values/colors.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c083db5..caa938a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,6 +63,7 @@ dependencies { androidTestImplementation(libs.androidx.espresso.core) implementation(libs.dagger.hilt) + debugImplementation(libs.androidx.ui.tooling) ksp(libs.dagger.hilt.compiler) implementation(libs.navigation.ui) diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/model/NoteClass.kt b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteClass.kt similarity index 83% rename from app/src/main/java/com/mutkuensert/highlightandnote/model/NoteClass.kt rename to app/src/main/java/com/mutkuensert/highlightandnote/data/NoteClass.kt index ab33689..523d7df 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/model/NoteClass.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteClass.kt @@ -1,4 +1,4 @@ -package com.mutkuensert.highlightandnote.model +package com.mutkuensert.highlightandnote.data import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDAO.kt b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDAO.kt index 0666344..38bd6d9 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDAO.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDAO.kt @@ -5,7 +5,6 @@ import androidx.room.Delete import androidx.room.Insert import androidx.room.Query import androidx.room.Update -import com.mutkuensert.highlightandnote.model.NoteClass @Dao interface NoteDAO { diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDatabase.kt b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDatabase.kt index 95073f9..7aca6f6 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDatabase.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/data/NoteDatabase.kt @@ -2,7 +2,6 @@ package com.mutkuensert.highlightandnote.data import androidx.room.Database import androidx.room.RoomDatabase -import com.mutkuensert.highlightandnote.model.NoteClass @Database(entities = [NoteClass::class], version = 1) abstract class NoteDatabase : RoomDatabase() { diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt index 43d7329..d4e705f 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeScreen.kt @@ -1,26 +1,43 @@ package com.mutkuensert.highlightandnote.home +import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel -import com.mutkuensert.highlightandnote.model.NoteClass +import com.mutkuensert.highlightandnote.data.NoteClass @Composable fun HomeScreen( onNavigateToNote: (id: Int) -> Unit, - selectedText: String? = null, + onNavigateToNewNote: () -> Unit, viewModel: HomeViewModel = viewModel() ) { val notes by viewModel.notes.collectAsStateWithLifecycle() - Home(notes, onNavigateToNote) + Home(notes, onNavigateToNote, onNavigateToNewNote) LaunchedEffect(Unit) { viewModel.getNotes() @@ -30,29 +47,91 @@ fun HomeScreen( @Composable private fun Home( notes: List, - onClickNote: (id: Int) -> Unit + onClickNote: (id: Int) -> Unit, + onClickNewNote: () -> Unit ) { - LazyColumn { + Column( + Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + .padding(horizontal = 16.dp) + ) { + Header(onClickNewNote) + + Notes(notes, onClickNote) + } +} + +@Composable +private fun Notes( + notes: List, + onClickNote: (id: Int) -> Unit, + modifier: Modifier = Modifier +) { + LazyColumn( + modifier = modifier, + contentPadding = PaddingValues(vertical = 10.dp) + ) { items(notes.size) { val note = notes[it] if (note.note != null) { - Text( - modifier = Modifier.clickable { onClickNote.invoke(note.uid) }, + Note( + onClick = { onClickNote.invoke(note.uid) }, text = note.note ) } + + if (it != notes.lastIndex) { + Spacer(Modifier.height(8.dp)) + } } } } +@Composable +private fun Header(onClickNewNote: () -> Unit, modifier: Modifier = Modifier) { + Row(modifier.fillMaxWidth()) { + Spacer(modifier = Modifier.weight(1f)) + + NewButton(onClickNewNote) + } +} + +@Composable +private fun NewButton(onClickNewNote: () -> Unit, modifier: Modifier = Modifier) { + IconButton(onClick = onClickNewNote, modifier = modifier) { + Icon(imageVector = Icons.Filled.Add, contentDescription = null) + } +} + +@Composable +private fun Note(onClick: () -> Unit, text: String, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .fillMaxWidth() + .shadow(5.dp, MaterialTheme.shapes.medium) + .background(MaterialTheme.colorScheme.background) + ) { + Text( + modifier = Modifier + .padding(8.dp) + .clickable(onClick = onClick), + text = text + ) + } +} + @Preview @Composable private fun HomePreview() { val fakeNotes = listOf( - NoteClass("First note"), + NoteClass( + "First note first note first note First note first note first note " + + "First note first note first note First note first note first note" + ), NoteClass("First note") ) - Home(fakeNotes, {}) + Home(fakeNotes, {}, {}) } \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt index 21aa249..5dfe73d 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/home/HomeViewModel.kt @@ -2,24 +2,41 @@ package com.mutkuensert.highlightandnote.home import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.mutkuensert.highlightandnote.data.NoteClass import com.mutkuensert.highlightandnote.data.NoteDAO -import com.mutkuensert.highlightandnote.model.NoteClass import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @HiltViewModel class HomeViewModel @Inject constructor(private val dao: NoteDAO) : ViewModel() { private val _notes = MutableStateFlow>(emptyList()) - val notes = _notes.asStateFlow() + val notes: StateFlow> = _notes.asStateFlow().shortenLongNotes() fun getNotes() { viewModelScope.launch(Dispatchers.IO) { _notes.update { dao.getAll() } } } + + private fun StateFlow>.shortenLongNotes(): StateFlow> { + return map { notes -> + notes.map { note -> + if (note.note != null && note.note.length > 300) { + val notePreview = note.note.substring(0..300) + "..." + note.copy(note = notePreview) + } else { + note + } + } + }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList()) + } } \ No newline at end of file diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt index cc09be8..676d097 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainActivity.kt @@ -44,7 +44,11 @@ class MainActivity : AppCompatActivity() { startDestination = HomeRoute ) { composable { - HomeScreen({}, getSelectedText()) + HomeScreen({}, + { + //navigate to new note, with selected text if exists + } + ) } } } @@ -60,7 +64,7 @@ class MainActivity : AppCompatActivity() { navController: NavController ) { LaunchedEffect(Unit) { - val selectedText = getSelectedText() + val selectedText = getSelectedTextInIntent() if (selectedText != null) { val result = snackbarHostState @@ -77,7 +81,7 @@ class MainActivity : AppCompatActivity() { } } - private fun getSelectedText(): String? { + private fun getSelectedTextInIntent(): String? { val action = intent.action if (action.equals(Intent.ACTION_PROCESS_TEXT) || action.equals(Intent.ACTION_SEND)) { diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/main/MainRoute.kt b/app/src/main/java/com/mutkuensert/highlightandnote/main/MainRoute.kt deleted file mode 100644 index 5caa34e..0000000 --- a/app/src/main/java/com/mutkuensert/highlightandnote/main/MainRoute.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mutkuensert.highlightandnote.main - -import kotlinx.serialization.Serializable - -@Serializable -class MainRoute() diff --git a/app/src/main/java/com/mutkuensert/highlightandnote/notedetail/DetailViewModel.kt b/app/src/main/java/com/mutkuensert/highlightandnote/notedetail/DetailViewModel.kt index 6165f7b..cf876f7 100644 --- a/app/src/main/java/com/mutkuensert/highlightandnote/notedetail/DetailViewModel.kt +++ b/app/src/main/java/com/mutkuensert/highlightandnote/notedetail/DetailViewModel.kt @@ -3,8 +3,9 @@ package com.mutkuensert.highlightandnote.notedetail import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mutkuensert.highlightandnote.data.NoteDAO -import com.mutkuensert.highlightandnote.model.NoteClass +import com.mutkuensert.highlightandnote.data.NoteClass import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -12,7 +13,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @HiltViewModel -class DetailViewModel constructor(private val dao: NoteDAO) : ViewModel() { +class DetailViewModel @Inject constructor(private val dao: NoteDAO) : ViewModel() { private val _uiModel = MutableStateFlow("") val uiModel = _uiModel.asStateFlow() diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index fba6b59..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml deleted file mode 100644 index f80b81f..0000000 --- a/app/src/main/res/drawable/ic_delete.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/rowdesign.xml b/app/src/main/res/drawable/rowdesign.xml deleted file mode 100644 index ede6ef0..0000000 --- a/app/src/main/res/drawable/rowdesign.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 81dd0fd..0000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_detail.xml b/app/src/main/res/layout/fragment_detail.xml deleted file mode 100644 index 3a26d9e..0000000 --- a/app/src/main/res/layout/fragment_detail.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml deleted file mode 100644 index e813087..0000000 --- a/app/src/main/res/layout/fragment_main.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/notes_row.xml b/app/src/main/res/layout/notes_row.xml deleted file mode 100644 index eca87a9..0000000 --- a/app/src/main/res/layout/notes_row.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/optionsmenu.xml b/app/src/main/res/menu/optionsmenu.xml deleted file mode 100644 index ee8336f..0000000 --- a/app/src/main/res/menu/optionsmenu.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/navi.xml b/app/src/main/res/navigation/navi.xml deleted file mode 100644 index b043add..0000000 --- a/app/src/main/res/navigation/navi.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml deleted file mode 100644 index 03d98a9..0000000 --- a/app/src/main/res/values-night/themes.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml deleted file mode 100644 index f460e1d..0000000 --- a/app/src/main/res/values/attrs.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml deleted file mode 100644 index f8c6127..0000000 --- a/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 - #FF000000 - #FFFFFFFF - \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index d6b78f6..33570f2 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,20 +1,5 @@ - - - + + + +