├── .gitignore
├── .idea
├── .gitignore
├── compiler.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── kotlinc.xml
├── misc.xml
└── vcs.xml
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle.kts
├── proguard-rules.pro
├── schemas
│ ├── com.example.learning3.NoteDatabase
│ │ └── 3.json
│ └── com.example.learning3.data.NoteDatabase
│ │ ├── 1.json
│ │ ├── 2.json
│ │ └── 3.json
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── learning3
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-playstore.png
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── learning3
│ │ │ ├── MainActivity.kt
│ │ │ ├── StoreThemePrefs.kt
│ │ │ ├── app
│ │ │ └── NotesApp.kt
│ │ │ ├── composables
│ │ │ └── CustomComposables.kt
│ │ │ ├── data
│ │ │ ├── ColorConfig.kt
│ │ │ ├── DarkThemeConfig.kt
│ │ │ ├── DatabaseProvider.kt
│ │ │ ├── Note.kt
│ │ │ ├── NoteDao.kt
│ │ │ └── NoteDatabase.kt
│ │ │ ├── events
│ │ │ └── NoteEvent.kt
│ │ │ ├── navigation
│ │ │ └── Screen.kt
│ │ │ ├── ui
│ │ │ ├── screens
│ │ │ │ ├── AboutScreen.kt
│ │ │ │ ├── AddNoteScreen.kt
│ │ │ │ ├── EditNoteScreen.kt
│ │ │ │ ├── NotesScreen.kt
│ │ │ │ ├── SettingsScreen.kt
│ │ │ │ └── ViewNoteScreen.kt
│ │ │ ├── state
│ │ │ │ └── NoteState.kt
│ │ │ └── theme
│ │ │ │ ├── Color.kt
│ │ │ │ ├── Theme.kt
│ │ │ │ ├── Type.kt
│ │ │ │ ├── colors
│ │ │ │ ├── BlueColor.kt
│ │ │ │ ├── BrownColor.kt
│ │ │ │ ├── GreenColor.kt
│ │ │ │ ├── PinkColor.kt
│ │ │ │ └── PurpleColor.kt
│ │ │ │ └── themes
│ │ │ │ ├── BlueTheme.kt
│ │ │ │ ├── BrownTheme.kt
│ │ │ │ ├── GreenTheme.kt
│ │ │ │ ├── PinkTheme.kt
│ │ │ │ └── PurpleTheme.kt
│ │ │ ├── utilities
│ │ │ └── UtilityFunctions.kt
│ │ │ └── viewmodel
│ │ │ ├── NotesViewModel.kt
│ │ │ └── NotesViewModelFactory.kt
│ └── res
│ │ ├── drawable
│ │ ├── baseline_check_circle_24.xml
│ │ ├── baseline_delete_forever_40.xml
│ │ ├── ic_launcher_background.xml
│ │ └── ic_launcher_foreground.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ └── ic_launcher_round.webp
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── learning3
│ └── ExampleUnitTest.kt
├── build.gradle.kts
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── images
├── add_note.png
├── note_search.png
├── note_view.png
├── notes_screen.png
└── settings.png
└── settings.gradle.kts
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2023 Krishnaraja Sagar T S
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Material3 Notes
2 | A notes application built using Jetpack Compose, the new declarative framework for native android development.
3 |
4 | (Still in development)
5 |
6 | Notes Screen | Settings
7 | :----------------------------------------:|:------------------------------:
8 |  |
9 |
10 | ## Features
11 | * CRUD operations
12 | * Data persistence with Room
13 | * Material 3 design
14 | * Search
15 | * Pins
16 | * Settings (Theme mode, Color scheme selection)
17 | * Tags (TODO)
18 | * Markdown support (TODO)
19 | * Sharing and exporting (TODO)
20 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application")
3 | id("org.jetbrains.kotlin.android")
4 | kotlin("kapt")
5 | }
6 |
7 | android {
8 | namespace = "com.example.learning3"
9 | compileSdk = 33
10 |
11 | defaultConfig {
12 | applicationId = "com.example.learning3"
13 | minSdk = 24
14 | targetSdk = 33
15 | versionCode = 1
16 | versionName = "1.0"
17 |
18 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
19 | vectorDrawables {
20 | useSupportLibrary = true
21 | }
22 |
23 | kapt {
24 | arguments {
25 | arg("room.schemaLocation", "$projectDir/schemas")
26 | }
27 | }
28 | }
29 |
30 | buildTypes {
31 | release {
32 | isMinifyEnabled = false
33 | proguardFiles(
34 | getDefaultProguardFile("proguard-android-optimize.txt"),
35 | "proguard-rules.pro"
36 | )
37 | }
38 | }
39 | compileOptions {
40 | sourceCompatibility = JavaVersion.VERSION_17
41 | targetCompatibility = JavaVersion.VERSION_17
42 | }
43 | kotlinOptions {
44 | jvmTarget = "17"
45 | }
46 | buildFeatures {
47 | compose = true
48 | }
49 | composeOptions {
50 | kotlinCompilerExtensionVersion = "1.4.3"
51 | }
52 | packaging {
53 | resources {
54 | excludes += "/META-INF/{AL2.0,LGPL2.1}"
55 | }
56 | }
57 | }
58 |
59 | dependencies {
60 |
61 | implementation("androidx.core:core-ktx:1.10.1")
62 | implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
63 | implementation("androidx.activity:activity-compose:1.7.2")
64 | implementation(platform("androidx.compose:compose-bom:2023.03.00"))
65 | implementation("androidx.compose.ui:ui")
66 | implementation("androidx.compose.ui:ui-graphics")
67 | implementation("androidx.compose.ui:ui-tooling-preview")
68 | implementation("androidx.compose.material3:material3")
69 | implementation("androidx.navigation:navigation-compose:2.6.0")
70 | implementation("androidx.compose.material:material-icons-extended:1.4.3")
71 | implementation("androidx.datastore:datastore-preferences:1.0.0")
72 | implementation("androidx.room:room-ktx:2.5.2")
73 | kapt("androidx.room:room-compiler:2.5.2")
74 | testImplementation("junit:junit:4.13.2")
75 | androidTestImplementation("androidx.test.ext:junit:1.1.5")
76 | androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
77 | androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
78 | androidTestImplementation("androidx.compose.ui:ui-test-junit4")
79 | debugImplementation("androidx.compose.ui:ui-tooling")
80 | debugImplementation("androidx.compose.ui:ui-test-manifest")
81 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/schemas/com.example.learning3.NoteDatabase/3.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": 1,
3 | "database": {
4 | "version": 3,
5 | "identityHash": "55c8b898cb3d38b7f55dee9a80d218cc",
6 | "entities": [
7 | {
8 | "tableName": "Note",
9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `lastModified` INTEGER NOT NULL, `isSelected` INTEGER NOT NULL DEFAULT 0, `isPinned` INTEGER NOT NULL DEFAULT 0)",
10 | "fields": [
11 | {
12 | "fieldPath": "id",
13 | "columnName": "id",
14 | "affinity": "INTEGER",
15 | "notNull": true
16 | },
17 | {
18 | "fieldPath": "title",
19 | "columnName": "title",
20 | "affinity": "TEXT",
21 | "notNull": true
22 | },
23 | {
24 | "fieldPath": "content",
25 | "columnName": "content",
26 | "affinity": "TEXT",
27 | "notNull": true
28 | },
29 | {
30 | "fieldPath": "lastModified",
31 | "columnName": "lastModified",
32 | "affinity": "INTEGER",
33 | "notNull": true
34 | },
35 | {
36 | "fieldPath": "isSelected",
37 | "columnName": "isSelected",
38 | "affinity": "INTEGER",
39 | "notNull": true,
40 | "defaultValue": "0"
41 | },
42 | {
43 | "fieldPath": "isPinned",
44 | "columnName": "isPinned",
45 | "affinity": "INTEGER",
46 | "notNull": true,
47 | "defaultValue": "0"
48 | }
49 | ],
50 | "primaryKey": {
51 | "autoGenerate": true,
52 | "columnNames": [
53 | "id"
54 | ]
55 | },
56 | "indices": [],
57 | "foreignKeys": []
58 | }
59 | ],
60 | "views": [],
61 | "setupQueries": [
62 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
63 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '55c8b898cb3d38b7f55dee9a80d218cc')"
64 | ]
65 | }
66 | }
--------------------------------------------------------------------------------
/app/schemas/com.example.learning3.data.NoteDatabase/1.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": 1,
3 | "database": {
4 | "version": 1,
5 | "identityHash": "a31a74ea0fbb0e6ac6de52d77527c387",
6 | "entities": [
7 | {
8 | "tableName": "Note",
9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `lastModified` INTEGER NOT NULL)",
10 | "fields": [
11 | {
12 | "fieldPath": "id",
13 | "columnName": "id",
14 | "affinity": "INTEGER",
15 | "notNull": true
16 | },
17 | {
18 | "fieldPath": "title",
19 | "columnName": "title",
20 | "affinity": "TEXT",
21 | "notNull": true
22 | },
23 | {
24 | "fieldPath": "content",
25 | "columnName": "content",
26 | "affinity": "TEXT",
27 | "notNull": true
28 | },
29 | {
30 | "fieldPath": "lastModified",
31 | "columnName": "lastModified",
32 | "affinity": "INTEGER",
33 | "notNull": true
34 | }
35 | ],
36 | "primaryKey": {
37 | "autoGenerate": true,
38 | "columnNames": [
39 | "id"
40 | ]
41 | },
42 | "indices": [],
43 | "foreignKeys": []
44 | }
45 | ],
46 | "views": [],
47 | "setupQueries": [
48 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
49 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a31a74ea0fbb0e6ac6de52d77527c387')"
50 | ]
51 | }
52 | }
--------------------------------------------------------------------------------
/app/schemas/com.example.learning3.data.NoteDatabase/2.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": 1,
3 | "database": {
4 | "version": 2,
5 | "identityHash": "c878ea480f6586690f442ed2b017836a",
6 | "entities": [
7 | {
8 | "tableName": "Note",
9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `lastModified` INTEGER NOT NULL, `isSelected` INTEGER NOT NULL DEFAULT 0)",
10 | "fields": [
11 | {
12 | "fieldPath": "id",
13 | "columnName": "id",
14 | "affinity": "INTEGER",
15 | "notNull": true
16 | },
17 | {
18 | "fieldPath": "title",
19 | "columnName": "title",
20 | "affinity": "TEXT",
21 | "notNull": true
22 | },
23 | {
24 | "fieldPath": "content",
25 | "columnName": "content",
26 | "affinity": "TEXT",
27 | "notNull": true
28 | },
29 | {
30 | "fieldPath": "lastModified",
31 | "columnName": "lastModified",
32 | "affinity": "INTEGER",
33 | "notNull": true
34 | },
35 | {
36 | "fieldPath": "isSelected",
37 | "columnName": "isSelected",
38 | "affinity": "INTEGER",
39 | "notNull": true,
40 | "defaultValue": "0"
41 | }
42 | ],
43 | "primaryKey": {
44 | "autoGenerate": true,
45 | "columnNames": [
46 | "id"
47 | ]
48 | },
49 | "indices": [],
50 | "foreignKeys": []
51 | }
52 | ],
53 | "views": [],
54 | "setupQueries": [
55 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
56 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c878ea480f6586690f442ed2b017836a')"
57 | ]
58 | }
59 | }
--------------------------------------------------------------------------------
/app/schemas/com.example.learning3.data.NoteDatabase/3.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": 1,
3 | "database": {
4 | "version": 3,
5 | "identityHash": "55c8b898cb3d38b7f55dee9a80d218cc",
6 | "entities": [
7 | {
8 | "tableName": "Note",
9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `lastModified` INTEGER NOT NULL, `isSelected` INTEGER NOT NULL DEFAULT 0, `isPinned` INTEGER NOT NULL DEFAULT 0)",
10 | "fields": [
11 | {
12 | "fieldPath": "id",
13 | "columnName": "id",
14 | "affinity": "INTEGER",
15 | "notNull": true
16 | },
17 | {
18 | "fieldPath": "title",
19 | "columnName": "title",
20 | "affinity": "TEXT",
21 | "notNull": true
22 | },
23 | {
24 | "fieldPath": "content",
25 | "columnName": "content",
26 | "affinity": "TEXT",
27 | "notNull": true
28 | },
29 | {
30 | "fieldPath": "lastModified",
31 | "columnName": "lastModified",
32 | "affinity": "INTEGER",
33 | "notNull": true
34 | },
35 | {
36 | "fieldPath": "isSelected",
37 | "columnName": "isSelected",
38 | "affinity": "INTEGER",
39 | "notNull": true,
40 | "defaultValue": "0"
41 | },
42 | {
43 | "fieldPath": "isPinned",
44 | "columnName": "isPinned",
45 | "affinity": "INTEGER",
46 | "notNull": true,
47 | "defaultValue": "0"
48 | }
49 | ],
50 | "primaryKey": {
51 | "autoGenerate": true,
52 | "columnNames": [
53 | "id"
54 | ]
55 | },
56 | "indices": [],
57 | "foreignKeys": []
58 | }
59 | ],
60 | "views": [],
61 | "setupQueries": [
62 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
63 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '55c8b898cb3d38b7f55dee9a80d218cc')"
64 | ]
65 | }
66 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/example/learning3/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.example.learning3", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/StoreThemePrefs.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3
2 |
3 | import android.content.Context
4 | import androidx.datastore.core.DataStore
5 | import androidx.datastore.preferences.core.Preferences
6 | import androidx.datastore.preferences.core.booleanPreferencesKey
7 | import androidx.datastore.preferences.core.edit
8 | import androidx.datastore.preferences.core.stringPreferencesKey
9 | import androidx.datastore.preferences.preferencesDataStore
10 | import com.example.learning3.data.ColorConfig
11 | import com.example.learning3.data.DarkThemeConfig
12 | import kotlinx.coroutines.flow.Flow
13 | import kotlinx.coroutines.flow.map
14 |
15 | class StoreThemePrefs(private val context: Context) {
16 |
17 | companion object {
18 | private val Context.dataStore: DataStore by preferencesDataStore("themePrefs")
19 | val DYNAMIC_THEME_KEY = booleanPreferencesKey("dynamic_theme")
20 | val THEME_MODE_KEY = stringPreferencesKey("theme_mode")
21 | val COLOR_KEY = stringPreferencesKey("color")
22 | }
23 |
24 | val isDynamicThemeEnabled: Flow = context.dataStore.data
25 | .map {
26 | it[DYNAMIC_THEME_KEY] ?: true
27 | }
28 |
29 | suspend fun setDynamicThemeEnabled(value: Boolean) {
30 | context.dataStore.edit {
31 | it[DYNAMIC_THEME_KEY] = value
32 | }
33 | }
34 |
35 | val getThemeMode: Flow = context.dataStore.data
36 | .map {
37 | it[THEME_MODE_KEY] ?: DarkThemeConfig.AUTO.toString()
38 | }
39 |
40 | suspend fun setThemeMode(value: String) {
41 | context.dataStore.edit {
42 | it[THEME_MODE_KEY] = value
43 | }
44 | }
45 |
46 | val getColor: Flow = context.dataStore.data
47 | .map {
48 | it[COLOR_KEY] ?: ColorConfig.BROWN.toString()
49 | }
50 |
51 | suspend fun setColor(value: String) {
52 | context.dataStore.edit {
53 | it[COLOR_KEY] = value
54 | }
55 | }
56 |
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/app/NotesApp.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.app
2 |
3 | import android.os.Build
4 | import androidx.annotation.RequiresApi
5 | import androidx.compose.runtime.*
6 | import androidx.navigation.NavType
7 | import androidx.navigation.compose.NavHost
8 | import androidx.navigation.compose.composable
9 | import androidx.navigation.compose.rememberNavController
10 | import androidx.navigation.navArgument
11 | import com.example.learning3.ui.screens.AddNoteScreen
12 | import com.example.learning3.ui.screens.EditNoteScreen
13 | import com.example.learning3.ui.screens.NotesScreen
14 | import com.example.learning3.viewmodel.NotesViewModel
15 | import com.example.learning3.navigation.Screen
16 | import com.example.learning3.ui.screens.AboutScreen
17 | import com.example.learning3.ui.screens.SettingsScreen
18 | import com.example.learning3.ui.screens.ViewNoteScreen
19 |
20 | @RequiresApi(Build.VERSION_CODES.O)
21 | @Composable
22 | fun NotesApp(viewModel: NotesViewModel) {
23 | val navController = rememberNavController()
24 |
25 | val state by viewModel.state.collectAsState()
26 |
27 | NavHost(navController, startDestination = Screen.Notes.route) {
28 | composable(Screen.Notes.route) {
29 | NotesScreen(
30 | navController = navController,
31 | state = state,
32 | onEvent = viewModel::onEvent
33 | )
34 | }
35 | composable(Screen.AddNote.route) {
36 | AddNoteScreen(
37 | navController = navController,
38 | state = state,
39 | onEvent = viewModel::onEvent
40 | )
41 | }
42 | composable(
43 | route = "${Screen.ViewNote.route}/{selectedId}",
44 | arguments = listOf(navArgument("selectedId") {type = NavType.LongType})
45 | ) { backStackEntry ->
46 | val noteId = backStackEntry.arguments?.getLong("selectedId")
47 | noteId?.let {
48 | ViewNoteScreen(
49 | navController = navController,
50 | selectedNoteId = noteId,
51 | state = state,
52 | onEvent = viewModel::onEvent
53 | )
54 | }
55 | }
56 | composable(
57 | route = "${Screen.EditNote.route}/{selectedId}",
58 | arguments = listOf(navArgument("selectedId") { type = NavType.LongType })
59 | ) { backStackEntry ->
60 | val noteId = backStackEntry.arguments?.getLong("selectedId")
61 | noteId?.let {
62 | EditNoteScreen(
63 | navController = navController,
64 | selectedNoteId = noteId,
65 | state = state,
66 | onEvent = viewModel::onEvent
67 | )
68 | }
69 | }
70 | composable(Screen.Settings.route) {
71 | SettingsScreen(
72 | navController = navController,
73 | onEvent = viewModel::onEvent
74 | )
75 | }
76 | composable(Screen.About.route) {
77 | AboutScreen(
78 | navController = navController
79 | )
80 | }
81 | }
82 | }
83 |
84 | //@Preview(showBackground = true)
85 | //@Composable
86 | //fun NotesScreenPreview() {
87 | // Learning3Theme {
88 | // val notes: List = mutableListOf(
89 | // Note(title = "Note 1", content = "Content"),
90 | // Note(title = "Note 2", content = "Content"),
91 | // Note(title = "Note 3", content = "Content"),
92 | // Note(title = "Note 4", content = "Content")
93 | // )
94 | // val onNoteClicked: (Note) -> Unit = { clickedNote ->
95 | //
96 | // }
97 | // NotesScreen(notes = notes, onNoteClicked = onNoteClicked)
98 | // }
99 | //}
100 |
101 | //@Preview(showBackground = true)
102 | //@Composable
103 | //fun AddNoteScreenPreview() {
104 | // Learning3Theme {
105 | // val note: Note = Note("Note 1", "Content")
106 | // val onSaveNote: (Note) -> Unit = {}
107 | // AddNoteScreen(onSaveNote = onSaveNote)
108 | // }
109 | //}
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/composables/CustomComposables.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.composables
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Build
5 | import androidx.annotation.RequiresApi
6 | import androidx.compose.animation.core.tween
7 | import androidx.compose.foundation.ExperimentalFoundationApi
8 | import androidx.compose.foundation.combinedClickable
9 | import androidx.compose.foundation.layout.Column
10 | import androidx.compose.foundation.layout.Spacer
11 | import androidx.compose.foundation.layout.fillMaxHeight
12 | import androidx.compose.foundation.layout.fillMaxWidth
13 | import androidx.compose.foundation.layout.height
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
16 | import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
17 | import androidx.compose.foundation.lazy.staggeredgrid.items
18 | import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
19 | import androidx.compose.foundation.shape.RoundedCornerShape
20 | import androidx.compose.material3.AlertDialog
21 | import androidx.compose.material3.Button
22 | import androidx.compose.material3.ButtonDefaults
23 | import androidx.compose.material3.Card
24 | import androidx.compose.material3.CardDefaults
25 | import androidx.compose.material3.ExperimentalMaterial3Api
26 | import androidx.compose.material3.ListItem
27 | import androidx.compose.material3.ListItemDefaults
28 | import androidx.compose.material3.MaterialTheme
29 | import androidx.compose.material3.Surface
30 | import androidx.compose.material3.Text
31 | import androidx.compose.material3.TextButton
32 | import androidx.compose.material3.TextField
33 | import androidx.compose.material3.TextFieldDefaults
34 | import androidx.compose.runtime.Composable
35 | import androidx.compose.ui.Modifier
36 | import androidx.compose.ui.graphics.Color
37 | import androidx.compose.ui.graphics.graphicsLayer
38 | import androidx.compose.ui.text.font.FontWeight
39 | import androidx.compose.ui.text.style.TextOverflow
40 | import androidx.compose.ui.tooling.preview.Preview
41 | import androidx.compose.ui.unit.dp
42 | import androidx.compose.ui.unit.sp
43 | import com.example.learning3.data.Note
44 | import com.example.learning3.ui.theme.Learning3Theme
45 | import com.example.learning3.utilities.UtilityFunctions
46 | import com.example.learning3.utilities.UtilityFunctions.calculateDelayAndEasing
47 | import com.example.learning3.utilities.UtilityFunctions.scaleAndAlpha
48 |
49 | @OptIn(ExperimentalMaterial3Api::class)
50 | @Composable
51 | fun SearchBar(
52 | modifier: Modifier = Modifier,
53 | query: String,
54 | onQueryChange: (String) -> Unit,
55 | leadingIcon: @Composable (() -> Unit)?,
56 | trailingIcon: @Composable (() -> Unit)?,
57 | ) {
58 | Surface(
59 | modifier = modifier
60 | .fillMaxWidth(),
61 | shape = RoundedCornerShape(50),
62 | color = Color.Transparent,
63 | ) {
64 | TextField(
65 | value = query,
66 | onValueChange = onQueryChange,
67 | placeholder = {
68 | Text(
69 | "Search notes...", style = MaterialTheme.typography.bodyMedium.copy(
70 | fontSize = 16.sp,
71 | color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f)
72 | )
73 | )
74 | },
75 | singleLine = true,
76 | colors = TextFieldDefaults.textFieldColors(
77 | containerColor = MaterialTheme.colorScheme.surfaceVariant,
78 | textColor = MaterialTheme.colorScheme.onSurfaceVariant,
79 | focusedIndicatorColor = Color.Transparent,
80 | unfocusedIndicatorColor = Color.Transparent,
81 | disabledIndicatorColor = Color.Transparent
82 | ),
83 | textStyle = MaterialTheme.typography.bodyMedium.copy(
84 | fontSize = 16.sp,
85 | ),
86 | modifier = Modifier
87 | .fillMaxWidth(),
88 | leadingIcon = leadingIcon,
89 | trailingIcon = trailingIcon,
90 | )
91 | }
92 | }
93 |
94 | @Composable
95 | fun DeleteDialog(
96 | titleText: String,
97 | bodyText: String,
98 | onDismissRequest: () -> Unit,
99 | onConfirmButtonClick: () -> Unit,
100 | onDismissButtonClick: () -> Unit
101 | ) {
102 | AlertDialog(
103 | title = { Text(titleText) },
104 | text = { Text(bodyText) },
105 | onDismissRequest = onDismissRequest,
106 | confirmButton = {
107 | Button(
108 | colors = ButtonDefaults.buttonColors(
109 | containerColor = MaterialTheme.colorScheme.error,
110 | contentColor = MaterialTheme.colorScheme.onError
111 | ),
112 | onClick = onConfirmButtonClick
113 | ) {
114 | Text("Delete")
115 | }
116 | },
117 | dismissButton = {
118 | TextButton(
119 | onClick = onDismissButtonClick
120 | ) {
121 | Text("Cancel")
122 | }
123 | }
124 | )
125 | }
126 |
127 | //@OptIn(ExperimentalMaterial3Api::class)
128 | //@Composable
129 | //fun CustomNavigationDrawer(
130 | // drawerState: DrawerState,
131 | // menuList: List>,
132 | // selectedDrawerItem: Pair,
133 | // itemOnClick: () -> Unit,
134 | // contentOnClick: () -> Unit,
135 | //) {
136 | // ModalNavigationDrawer(
137 | // drawerState = drawerState,
138 | // drawerContent = {
139 | // ModalDrawerSheet {
140 | // Spacer(modifier = Modifier.height(12.dp))
141 | // menuList.forEachIndexed { index, data ->
142 | // NavigationDrawerItem(
143 | // label = {
144 | // Text(text = data.second)
145 | // },
146 | // icon = {
147 | // Icon(
148 | // imageVector = data.first,
149 | // contentDescription = "Drawer icon $index"
150 | // )
151 | // },
152 | // modifier = Modifier
153 | // .padding(NavigationDrawerItemDefaults.ItemPadding),
154 | // selected = selectedDrawerItem == index,
155 | // onClick = itemOnClick,
156 | // )
157 | // }
158 | // }
159 | // },
160 | // content = {
161 | // Column(
162 | // modifier = Modifier
163 | // .fillMaxSize()
164 | // .padding(16.dp),
165 | // horizontalAlignment = Alignment.CenterHorizontally
166 | // ) {
167 | // Text(text = if (drawerState.isClosed) ">>> Swipe >>>" else "<<< Swipe <<<")
168 | // Spacer(Modifier.height(20.dp))
169 | // Button(onClick = { scope.launch { drawerState.open() } }) {
170 | // Text("Click to open")
171 | // }
172 | // }
173 | // }
174 | // ) {
175 | //
176 | // }
177 | //}
178 |
179 | @RequiresApi(Build.VERSION_CODES.O)
180 | @OptIn(ExperimentalFoundationApi::class)
181 | @Composable
182 | fun NotesGrid(
183 | notes: List,
184 | onNoteClick: (Note) -> Unit,
185 | onNoteLongClick: (Note) -> Unit
186 | ) {
187 | val lazyStaggeredListState = rememberLazyStaggeredGridState()
188 | LazyVerticalStaggeredGrid(
189 | columns = StaggeredGridCells.Fixed(2),
190 | modifier = Modifier.padding(
191 | horizontal = 12.dp
192 | ),
193 | state = lazyStaggeredListState
194 | ) {
195 | items(notes) { note ->
196 | val index = notes.indexOf(note)
197 | val (delay, easing) = lazyStaggeredListState.calculateDelayAndEasing(index, 3)
198 | val animation = tween(durationMillis = 150, delayMillis = delay, easing = easing)
199 | val args = UtilityFunctions.ScaleAndAlphaArgs(
200 | fromScale = 2f,
201 | toScale = 1f,
202 | fromAlpha = 0f,
203 | toAlpha = 1f
204 | )
205 | val (scale, alpha) = scaleAndAlpha(args = args, animation = animation)
206 | Card(
207 | modifier = Modifier
208 | .padding(4.dp)
209 | .combinedClickable(
210 | onClick = { onNoteClick(note) },
211 | onLongClick = { onNoteLongClick(note) }
212 | )
213 | .graphicsLayer(alpha = alpha, scaleX = scale, scaleY = scale),
214 | colors = CardDefaults.cardColors(
215 | containerColor = if (!note.isSelected) MaterialTheme.colorScheme.surfaceVariant else MaterialTheme.colorScheme.primaryContainer,
216 | contentColor = if (!note.isSelected) MaterialTheme.colorScheme.onSurfaceVariant else MaterialTheme.colorScheme.onPrimaryContainer
217 | ),
218 | border = CardDefaults.outlinedCardBorder(
219 | note.isPinned
220 | )
221 | ) {
222 | Column(
223 | modifier = Modifier
224 | .padding(16.dp)
225 | .fillMaxHeight(),
226 | ) {
227 | Text(
228 | text = note.title,
229 | maxLines = 2,
230 | overflow = TextOverflow.Ellipsis,
231 | style = MaterialTheme.typography.bodyLarge.copy(
232 | fontSize = 18.sp,
233 | fontWeight = FontWeight.SemiBold,
234 | lineHeight = 22.sp
235 | ),
236 | )
237 | Spacer(
238 | modifier = Modifier
239 | .height(8.dp)
240 | )
241 | Text(
242 | text = note.content,
243 | maxLines = 8,
244 | overflow = TextOverflow.Ellipsis,
245 | style = MaterialTheme.typography.bodyMedium.copy(
246 | fontSize = 16.sp,
247 | )
248 | )
249 | Spacer(
250 | modifier = Modifier
251 | .height(8.dp)
252 | )
253 | Text(
254 | text = UtilityFunctions.formatDateAndTime(note.lastModified),
255 | maxLines = 1,
256 | style = MaterialTheme.typography.bodySmall.copy(
257 | fontSize = 12.sp,
258 | ),
259 | )
260 | }
261 | }
262 | }
263 | }
264 | }
265 |
266 | @OptIn(ExperimentalMaterial3Api::class)
267 | @Composable
268 | fun SettingsListItem(
269 | title: String,
270 | trailingContent: @Composable (() -> Unit)?
271 | ) {
272 | ListItem(
273 | headlineText = {
274 | Text(
275 | text = title,
276 | style = MaterialTheme.typography.titleLarge.copy(
277 | fontSize = 20.sp
278 |
279 | )
280 | )
281 | },
282 | trailingContent = trailingContent,
283 | colors = ListItemDefaults.colors(
284 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
285 | headlineColor = MaterialTheme.colorScheme.inverseSurface,
286 | disabledHeadlineColor = MaterialTheme.colorScheme.inverseSurface.copy(alpha = 0.6f)
287 | ),
288 | // modifier = Modifier
289 | // .padding(
290 | // top = 12.dp
291 | // )
292 | )
293 | }
294 |
295 | @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
296 | @Preview(showBackground = true)
297 | @Composable
298 | fun CustomComposablePreview() {
299 | Learning3Theme {
300 |
301 | }
302 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/data/ColorConfig.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.data
2 |
3 | enum class ColorConfig {
4 | PINK,
5 | BROWN,
6 | GREEN,
7 | BLUE,
8 | PURPLE
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/data/DarkThemeConfig.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.data
2 |
3 | enum class DarkThemeConfig {
4 | AUTO, LIGHT, DARK
5 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/data/DatabaseProvider.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.data
2 |
3 | import android.content.Context
4 | import androidx.room.Room
5 |
6 | object DatabaseProvider {
7 | private var database: NoteDatabase?= null
8 |
9 | fun getDatabase(context: Context): NoteDatabase {
10 | return database ?: synchronized(this) {
11 | val instance = Room.databaseBuilder(
12 | context.applicationContext,
13 | NoteDatabase::class.java,
14 | "notes_database"
15 | ).build()
16 | database = instance
17 | instance
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/data/Note.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.data
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.PrimaryKey
6 |
7 | @Entity
8 | data class Note(
9 | @PrimaryKey(autoGenerate = true)
10 | val id: Long = 0,
11 | val title: String,
12 | val content: String,
13 | val lastModified: Long,
14 | @ColumnInfo("isSelected", defaultValue = "0")
15 | var isSelected: Boolean = false,
16 | @ColumnInfo("isPinned", defaultValue = "0")
17 | var isPinned: Boolean = false
18 | ) {
19 | fun doesMatchSearchQuery(query: String): Boolean {
20 | val matchingCombinations = listOf(
21 | "$title$content",
22 | "$title $content",
23 | "${title.first()} ${content.first()}"
24 | )
25 | return matchingCombinations.any {
26 | it.contains(query, true)
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/data/NoteDao.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.data
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Delete
5 | import androidx.room.Upsert
6 | import androidx.room.Query
7 | import kotlinx.coroutines.flow.Flow
8 |
9 | @Dao
10 | interface NoteDao {
11 |
12 | @Upsert
13 | suspend fun upsertNote(note: Note)
14 |
15 | @Delete
16 | suspend fun deleteNote(note: Note)
17 |
18 | @Query("SELECT * FROM note")
19 | fun getNotes(): Flow>
20 |
21 | @Query("SELECT * FROM note WHERE note.title LIKE ('%' || :query || '%') OR note.content LIKE ('%' || :query || '%')")
22 | fun getNotesFromQuery(query: String): Flow>
23 |
24 | @Query("DELETE FROM note")
25 | fun clearAllNotes()
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/data/NoteDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.data
2 |
3 | import androidx.room.AutoMigration
4 | import androidx.room.Database
5 | import androidx.room.RoomDatabase
6 |
7 | @Database(
8 | entities = [Note::class],
9 | version = 3,
10 | autoMigrations = [
11 | AutoMigration(1,2),
12 | AutoMigration(2,3)
13 | ]
14 | )
15 | abstract class NoteDatabase : RoomDatabase() {
16 | abstract val noteDao: NoteDao
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/events/NoteEvent.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.events
2 |
3 | import com.example.learning3.data.Note
4 |
5 | sealed interface NoteEvent {
6 | object SaveNote: NoteEvent
7 | object ClearAllNotes: NoteEvent
8 | // data class SaveEditedNote(val note: Note): NoteEvent
9 | data class SetTitle(val title: String): NoteEvent
10 | data class SetContent(val content: String): NoteEvent
11 | data class SetSearchQuery(val query: String): NoteEvent
12 | // object SearchNotes: NoteEvent
13 | data class EnableIsSelected(val note: Note): NoteEvent
14 | data class DisableIsSelected(val note: Note): NoteEvent
15 | data class PinNote(val note: Note): NoteEvent
16 | data class UnpinNote(val note: Note): NoteEvent
17 | data class DeleteNote(val note: Note): NoteEvent
18 | data class StartEditing(val note: Note): NoteEvent
19 | // object StopEditing: NoteEvent
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/navigation/Screen.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.navigation
2 |
3 | sealed class Screen(val route: String) {
4 | object Notes: Screen("notes")
5 | object AddNote: Screen("add-note")
6 | object ViewNote: Screen("viewNote/{noteId}")
7 | object EditNote: Screen("editNote/{noteId}")
8 | object Settings: Screen("settings")
9 | object About: Screen("about")
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/screens/AboutScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.screens
2 |
3 | import androidx.compose.foundation.layout.Column
4 | import androidx.compose.foundation.layout.Row
5 | import androidx.compose.foundation.layout.fillMaxWidth
6 | import androidx.compose.foundation.layout.padding
7 | import androidx.compose.material.icons.Icons
8 | import androidx.compose.material.icons.filled.ArrowBack
9 | import androidx.compose.material3.ButtonDefaults
10 | import androidx.compose.material3.Card
11 | import androidx.compose.material3.ExperimentalMaterial3Api
12 | import androidx.compose.material3.Icon
13 | import androidx.compose.material3.IconButton
14 | import androidx.compose.material3.MaterialTheme
15 | import androidx.compose.material3.Scaffold
16 | import androidx.compose.material3.Text
17 | import androidx.compose.material3.TextButton
18 | import androidx.compose.material3.TopAppBar
19 | import androidx.compose.material3.TopAppBarDefaults
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.platform.LocalUriHandler
23 | import androidx.compose.ui.unit.dp
24 | import androidx.navigation.NavController
25 |
26 | @OptIn(ExperimentalMaterial3Api::class)
27 | @Composable
28 | fun AboutScreen(
29 | navController: NavController
30 | ) {
31 | val uriHandler = LocalUriHandler.current
32 | Scaffold(
33 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
34 | contentColor = MaterialTheme.colorScheme.inverseSurface,
35 | topBar = {
36 | TopAppBar(
37 | title = {},
38 | colors = TopAppBarDefaults.smallTopAppBarColors(
39 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
40 | navigationIconContentColor = MaterialTheme.colorScheme.inverseSurface,
41 | titleContentColor = MaterialTheme.colorScheme.inverseSurface
42 | ),
43 | navigationIcon = {
44 | IconButton(
45 | onClick = {
46 | navController.popBackStack()
47 | }
48 | ) {
49 | Icon(Icons.Default.ArrowBack,contentDescription = "Back")
50 | }
51 | }
52 | )
53 | }
54 | ) { padding ->
55 | Card(
56 | modifier = Modifier
57 | .padding(padding)
58 | .padding(
59 | horizontal = 16.dp,
60 | vertical = 24.dp
61 | )
62 | .padding(top = 48.dp),
63 | ) {
64 | Column(
65 | modifier = Modifier
66 | .fillMaxWidth()
67 | ) {
68 | Text(
69 | "Developed by Krishnaraja Sagar",
70 | style = MaterialTheme.typography.titleMedium,
71 | modifier = Modifier
72 | .padding(16.dp)
73 | )
74 | Row {
75 | TextButton(
76 | onClick = {
77 | uriHandler.openUri("https://github.com/KrishnarajaSagar")
78 | },
79 | modifier = Modifier
80 | .padding(16.dp),
81 | colors = ButtonDefaults.textButtonColors(
82 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
83 | contentColor = MaterialTheme.colorScheme.inverseSurface
84 | )
85 | ) {
86 | Text("Github")
87 | }
88 | TextButton(
89 | onClick = {
90 | uriHandler.openUri("https://www.linkedin.com/in/krsagarts/")
91 | },
92 | modifier = Modifier
93 | .padding(16.dp),
94 | colors = ButtonDefaults.textButtonColors(
95 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
96 | contentColor = MaterialTheme.colorScheme.inverseSurface
97 | )
98 | ) {
99 | Text("LinkedIn")
100 | }
101 | }
102 | }
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/screens/AddNoteScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.screens
2 |
3 | import androidx.compose.foundation.layout.Column
4 | import androidx.compose.foundation.layout.Spacer
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.foundation.layout.fillMaxWidth
7 | import androidx.compose.foundation.layout.height
8 | import androidx.compose.foundation.layout.imePadding
9 | import androidx.compose.foundation.layout.padding
10 | import androidx.compose.foundation.rememberScrollState
11 | import androidx.compose.foundation.text.KeyboardOptions
12 | import androidx.compose.foundation.verticalScroll
13 | import androidx.compose.material.icons.Icons
14 | import androidx.compose.material.icons.filled.ArrowBack
15 | import androidx.compose.material.icons.filled.Check
16 | import androidx.compose.material3.ExperimentalMaterial3Api
17 | import androidx.compose.material3.ExtendedFloatingActionButton
18 | import androidx.compose.material3.FabPosition
19 | import androidx.compose.material3.Icon
20 | import androidx.compose.material3.IconButton
21 | import androidx.compose.material3.MaterialTheme
22 | import androidx.compose.material3.Scaffold
23 | import androidx.compose.material3.Text
24 | import androidx.compose.material3.TextField
25 | import androidx.compose.material3.TextFieldDefaults
26 | import androidx.compose.material3.TopAppBar
27 | import androidx.compose.material3.TopAppBarDefaults
28 | import androidx.compose.runtime.Composable
29 | import androidx.compose.ui.Modifier
30 | import androidx.compose.ui.graphics.Color
31 | import androidx.compose.ui.text.font.FontWeight
32 | import androidx.compose.ui.text.input.ImeAction
33 | import androidx.compose.ui.unit.dp
34 | import androidx.compose.ui.unit.sp
35 | import androidx.navigation.NavController
36 | import com.example.learning3.events.NoteEvent
37 | import com.example.learning3.ui.state.NoteState
38 |
39 | @OptIn(ExperimentalMaterial3Api::class)
40 | @Composable
41 | fun AddNoteScreen(
42 | navController: NavController,
43 | state: NoteState,
44 | onEvent: (NoteEvent) -> Unit
45 | ) {
46 | Scaffold(
47 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
48 | contentColor = MaterialTheme.colorScheme.inverseSurface,
49 | topBar = {
50 | TopAppBar(
51 | title = {},
52 | colors = TopAppBarDefaults.smallTopAppBarColors(
53 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
54 | navigationIconContentColor = MaterialTheme.colorScheme.inverseSurface,
55 | actionIconContentColor = MaterialTheme.colorScheme.inverseSurface,
56 | titleContentColor = MaterialTheme.colorScheme.inverseSurface
57 | ),
58 | navigationIcon = {
59 | IconButton(
60 | onClick = {
61 | navController.popBackStack()
62 | }
63 | ) {
64 | Icon(Icons.Default.ArrowBack,contentDescription = "Back")
65 | }
66 | }
67 | )
68 | },
69 | floatingActionButton = {
70 | ExtendedFloatingActionButton(
71 | onClick = {
72 | onEvent(NoteEvent.SaveNote)
73 | navController.popBackStack()
74 | },
75 | containerColor = MaterialTheme.colorScheme.tertiaryContainer,
76 | contentColor = MaterialTheme.colorScheme.onTertiaryContainer
77 | ) {
78 | Icon(Icons.Filled.Check, contentDescription = "Save Note")
79 | Text("Save Note")
80 | }
81 | },
82 | floatingActionButtonPosition = FabPosition.End
83 | ) { padding ->
84 | Column(
85 | modifier = Modifier
86 | .padding(padding)
87 | .verticalScroll(rememberScrollState())
88 | .imePadding()
89 | ) {
90 | TextField(
91 | value = state.title,
92 | onValueChange = { onEvent(NoteEvent.SetTitle(it)) },
93 | placeholder = { Text("Title", style = MaterialTheme.typography.bodyLarge.copy(
94 | fontSize = 18.sp,
95 | fontWeight = FontWeight.SemiBold,
96 | lineHeight = 22.sp,
97 | color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
98 | ),) },
99 | colors = TextFieldDefaults.textFieldColors(
100 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
101 | textColor = MaterialTheme.colorScheme.inverseSurface,
102 | focusedIndicatorColor = Color.Transparent,
103 | unfocusedIndicatorColor = Color.Transparent,
104 | disabledIndicatorColor = Color.Transparent
105 | ),
106 | textStyle = MaterialTheme.typography.bodyLarge.copy(
107 | fontSize = 18.sp,
108 | fontWeight = FontWeight.SemiBold,
109 | lineHeight = 22.sp
110 | ),
111 | modifier = Modifier
112 | .fillMaxWidth(),
113 | keyboardOptions = KeyboardOptions.Default.copy(
114 | imeAction = ImeAction.Next
115 | )
116 | )
117 | Spacer(
118 | modifier = Modifier
119 | .height(16.dp)
120 | )
121 | TextField(
122 | value = state.content,
123 | onValueChange = { onEvent(NoteEvent.SetContent(it)) },
124 | placeholder = { Text("Content", style = MaterialTheme.typography.bodyMedium.copy(
125 | fontSize = 16.sp,
126 | color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
127 | )) },
128 | colors = TextFieldDefaults.textFieldColors(
129 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
130 | textColor = MaterialTheme.colorScheme.inverseSurface,
131 | focusedIndicatorColor = Color.Transparent,
132 | unfocusedIndicatorColor = Color.Transparent,
133 | disabledIndicatorColor = Color.Transparent
134 | ),
135 | textStyle = MaterialTheme.typography.bodyMedium.copy(
136 | fontSize = 16.sp,
137 | ),
138 | modifier = Modifier
139 | .fillMaxSize(),
140 | keyboardOptions = KeyboardOptions.Default.copy(
141 | imeAction = ImeAction.Done
142 | )
143 | )
144 | Spacer(
145 | modifier = Modifier
146 | .height(16.dp)
147 | )
148 | }
149 | }
150 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/screens/EditNoteScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.screens
2 |
3 | import androidx.compose.foundation.layout.Column
4 | import androidx.compose.foundation.layout.Spacer
5 | import androidx.compose.foundation.layout.fillMaxWidth
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.imePadding
8 | import androidx.compose.foundation.layout.padding
9 | import androidx.compose.foundation.rememberScrollState
10 | import androidx.compose.foundation.text.KeyboardOptions
11 | import androidx.compose.foundation.verticalScroll
12 | import androidx.compose.material.icons.Icons
13 | import androidx.compose.material.icons.filled.ArrowBack
14 | import androidx.compose.material.icons.filled.Check
15 | import androidx.compose.material3.ExperimentalMaterial3Api
16 | import androidx.compose.material3.ExtendedFloatingActionButton
17 | import androidx.compose.material3.FabPosition
18 | import androidx.compose.material3.Icon
19 | import androidx.compose.material3.IconButton
20 | import androidx.compose.material3.MaterialTheme
21 | import androidx.compose.material3.Scaffold
22 | import androidx.compose.material3.Text
23 | import androidx.compose.material3.TextField
24 | import androidx.compose.material3.TextFieldDefaults
25 | import androidx.compose.material3.TopAppBar
26 | import androidx.compose.material3.TopAppBarDefaults
27 | import androidx.compose.runtime.Composable
28 | import androidx.compose.ui.Modifier
29 | import androidx.compose.ui.graphics.Color
30 | import androidx.compose.ui.text.font.FontWeight
31 | import androidx.compose.ui.text.input.ImeAction
32 | import androidx.compose.ui.unit.dp
33 | import androidx.compose.ui.unit.sp
34 | import androidx.navigation.NavController
35 | import com.example.learning3.events.NoteEvent
36 | import com.example.learning3.ui.state.NoteState
37 |
38 | @OptIn(ExperimentalMaterial3Api::class)
39 | @Composable
40 | fun EditNoteScreen(
41 | navController: NavController,
42 | selectedNoteId: Long,
43 | state: NoteState,
44 | onEvent: (NoteEvent) -> Unit
45 | ) {
46 | Scaffold(
47 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
48 | contentColor = MaterialTheme.colorScheme.inverseSurface,
49 | topBar = {
50 | TopAppBar(
51 | title = {},
52 | colors = TopAppBarDefaults.smallTopAppBarColors(
53 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
54 | navigationIconContentColor = MaterialTheme.colorScheme.inverseSurface,
55 | actionIconContentColor = MaterialTheme.colorScheme.inverseSurface,
56 | titleContentColor = MaterialTheme.colorScheme.inverseSurface
57 | ),
58 | navigationIcon = {
59 | IconButton(
60 | onClick = {
61 | navController.popBackStack()
62 | }
63 | ) {
64 | Icon(Icons.Default.ArrowBack,contentDescription = "Back")
65 | }
66 | }
67 | )
68 | },
69 | floatingActionButton = {
70 | ExtendedFloatingActionButton(
71 | onClick = {
72 | onEvent(NoteEvent.SaveNote)
73 | navController.popBackStack()
74 | },
75 | containerColor = MaterialTheme.colorScheme.tertiaryContainer,
76 | contentColor = MaterialTheme.colorScheme.onTertiaryContainer
77 | ) {
78 | Icon(Icons.Filled.Check, contentDescription = "Save Note")
79 | Text("Save Note")
80 | }
81 | },
82 | floatingActionButtonPosition = FabPosition.End
83 | ) { padding ->
84 | Column(
85 | modifier = Modifier
86 | .padding(padding)
87 | .verticalScroll(rememberScrollState())
88 | .imePadding()
89 | ) {
90 | TextField(
91 | value = state.title,
92 | onValueChange = { newTitle ->
93 | onEvent(NoteEvent.SetTitle(newTitle))
94 | },
95 | placeholder = { Text("Title", style = MaterialTheme.typography.bodyLarge.copy(
96 | fontSize = 18.sp,
97 | fontWeight = FontWeight.SemiBold,
98 | lineHeight = 22.sp,
99 | color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
100 | ),) },
101 | colors = TextFieldDefaults.textFieldColors(
102 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
103 | textColor = MaterialTheme.colorScheme.inverseSurface,
104 | focusedIndicatorColor = Color.Transparent,
105 | unfocusedIndicatorColor = Color.Transparent,
106 | disabledIndicatorColor = Color.Transparent
107 | ),
108 | textStyle = MaterialTheme.typography.bodyLarge.copy(
109 | fontSize = 18.sp,
110 | fontWeight = FontWeight.SemiBold,
111 | lineHeight = 22.sp
112 | ),
113 | modifier = Modifier
114 | .fillMaxWidth(),
115 | keyboardOptions = KeyboardOptions.Default.copy(
116 | imeAction = ImeAction.Next
117 | )
118 | )
119 | Spacer(
120 | modifier = Modifier
121 | .height(16.dp)
122 | )
123 | TextField(
124 | value = state.content,
125 | onValueChange = { newContent ->
126 | onEvent(NoteEvent.SetContent(newContent))
127 | },
128 | placeholder = { Text("Content", style = MaterialTheme.typography.bodyMedium.copy(
129 | fontSize = 16.sp,
130 | color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
131 | )) },
132 | colors = TextFieldDefaults.textFieldColors(
133 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
134 | textColor = MaterialTheme.colorScheme.inverseSurface,
135 | focusedIndicatorColor = Color.Transparent,
136 | unfocusedIndicatorColor = Color.Transparent,
137 | disabledIndicatorColor = Color.Transparent
138 | ),
139 | textStyle = MaterialTheme.typography.bodyMedium.copy(
140 | fontSize = 16.sp,
141 | ),
142 | modifier = Modifier
143 | .fillMaxWidth(),
144 | keyboardOptions = KeyboardOptions.Default.copy(
145 | imeAction = ImeAction.Done
146 | )
147 | )
148 | Spacer(
149 | modifier = Modifier
150 | .height(16.dp)
151 | )
152 | }
153 | }
154 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/screens/NotesScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.screens
2 |
3 | import android.os.Build
4 | import android.util.Log
5 | import android.widget.Toast
6 | import androidx.annotation.RequiresApi
7 | import androidx.compose.animation.AnimatedVisibility
8 | import androidx.compose.foundation.clickable
9 | import androidx.compose.foundation.interaction.MutableInteractionSource
10 | import androidx.compose.foundation.layout.Column
11 | import androidx.compose.foundation.layout.fillMaxSize
12 | import androidx.compose.foundation.layout.padding
13 | import androidx.compose.foundation.shape.RoundedCornerShape
14 | import androidx.compose.material.icons.Icons
15 | import androidx.compose.material.icons.filled.Add
16 | import androidx.compose.material.icons.filled.ArrowBack
17 | import androidx.compose.material.icons.filled.Clear
18 | import androidx.compose.material.icons.filled.Delete
19 | import androidx.compose.material.icons.filled.Menu
20 | import androidx.compose.material.icons.filled.MoreVert
21 | import androidx.compose.material.icons.filled.PushPin
22 | import androidx.compose.material.icons.outlined.PushPin
23 | import androidx.compose.material3.DropdownMenu
24 | import androidx.compose.material3.DropdownMenuItem
25 | import androidx.compose.material3.ExperimentalMaterial3Api
26 | import androidx.compose.material3.ExtendedFloatingActionButton
27 | import androidx.compose.material3.FabPosition
28 | import androidx.compose.material3.Icon
29 | import androidx.compose.material3.IconButton
30 | import androidx.compose.material3.MaterialTheme
31 | import androidx.compose.material3.Scaffold
32 | import androidx.compose.material3.Text
33 | import androidx.compose.material3.TopAppBar
34 | import androidx.compose.material3.TopAppBarDefaults
35 | import androidx.compose.runtime.Composable
36 | import androidx.compose.runtime.LaunchedEffect
37 | import androidx.compose.runtime.getValue
38 | import androidx.compose.runtime.mutableStateListOf
39 | import androidx.compose.runtime.mutableStateOf
40 | import androidx.compose.runtime.remember
41 | import androidx.compose.runtime.setValue
42 | import androidx.compose.ui.Alignment
43 | import androidx.compose.ui.Modifier
44 | import androidx.compose.ui.platform.LocalContext
45 | import androidx.compose.ui.platform.LocalFocusManager
46 | import androidx.compose.ui.text.font.FontWeight
47 | import androidx.compose.ui.unit.DpOffset
48 | import androidx.compose.ui.unit.dp
49 | import androidx.compose.ui.unit.sp
50 | import androidx.navigation.NavController
51 | import com.example.learning3.composables.DeleteDialog
52 | import com.example.learning3.composables.NotesGrid
53 | import com.example.learning3.data.Note
54 | import com.example.learning3.events.NoteEvent
55 | import com.example.learning3.ui.state.NoteState
56 | import com.example.learning3.navigation.Screen
57 | import com.example.learning3.composables.SearchBar
58 | import kotlinx.coroutines.delay
59 |
60 |
61 | @RequiresApi(Build.VERSION_CODES.O)
62 | @OptIn(ExperimentalMaterial3Api::class)
63 | @Composable
64 | fun NotesScreen(
65 | navController: NavController,
66 | state: NoteState,
67 | onEvent: (NoteEvent) -> Unit
68 | ) {
69 | val context = LocalContext.current
70 | var expanded by remember { mutableStateOf(false) }
71 | val selectedNotes = remember { mutableStateListOf() }
72 | val pinnedNotes = remember { mutableStateListOf() }
73 | var showDeleteDialog by remember { mutableStateOf(false) }
74 | var showScreen by remember { mutableStateOf(false) }
75 |
76 | val focusManager = LocalFocusManager.current
77 | val interactionSource = remember { MutableInteractionSource() }
78 |
79 | if (showDeleteDialog) {
80 | DeleteDialog(
81 | titleText = "Confirm deletion?",
82 | bodyText = "The selected notes will be deleted permanently",
83 | onDismissRequest = { showDeleteDialog = false },
84 | onConfirmButtonClick = {
85 | selectedNotes.forEach {
86 | onEvent(NoteEvent.DeleteNote(it))
87 | }
88 | selectedNotes.clear()
89 | showDeleteDialog = false
90 | },
91 | onDismissButtonClick = {
92 | showDeleteDialog = false
93 | }
94 | )
95 | }
96 |
97 | Scaffold(
98 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
99 | contentColor = MaterialTheme.colorScheme.inverseSurface,
100 | floatingActionButton = {
101 | ExtendedFloatingActionButton(
102 | onClick = {
103 | navController.navigate(Screen.AddNote.route)
104 | onEvent(NoteEvent.SetSearchQuery(""))
105 | },
106 | containerColor = MaterialTheme.colorScheme.tertiaryContainer,
107 | contentColor = MaterialTheme.colorScheme.onTertiaryContainer
108 | ) {
109 | Icon(Icons.Filled.Add, contentDescription = "Add Note")
110 | Text("Add Note")
111 | }
112 | },
113 | floatingActionButtonPosition = FabPosition.End
114 | ) {
115 | Column(
116 | horizontalAlignment = Alignment.CenterHorizontally,
117 | modifier = Modifier
118 | .padding(it)
119 | .fillMaxSize()
120 | .clickable(
121 | interactionSource = interactionSource,
122 | indication = null
123 | ) {
124 | focusManager.clearFocus()
125 | }) {
126 | if (selectedNotes.isEmpty()) {
127 | SearchBar(
128 | modifier = Modifier.padding(16.dp),
129 | query = state.searchQuery,
130 | onQueryChange = { str ->
131 | onEvent(NoteEvent.SetSearchQuery(str))
132 | // Log.d(state.searchQuery,"")
133 | },
134 | leadingIcon = {
135 | IconButton(
136 | onClick = {
137 | Toast.makeText(
138 | context,
139 | "Feature under development",
140 | Toast.LENGTH_SHORT
141 | ).show()
142 | }
143 | )
144 | {
145 | Icon(imageVector = Icons.Default.Menu, contentDescription = "Menu")
146 | }
147 | },
148 | trailingIcon = {
149 | if (state.searchQuery.isBlank()) {
150 | IconButton(
151 | onClick = {
152 | expanded = true
153 | }
154 | ) {
155 | Icon(
156 | imageVector = Icons.Default.MoreVert,
157 | contentDescription = "More options"
158 | )
159 | }
160 | MaterialTheme(
161 | shapes = MaterialTheme.shapes.copy(
162 | extraSmall = RoundedCornerShape(16.dp)
163 | ),
164 | ) {
165 | DropdownMenu(
166 | expanded = expanded,
167 | offset = DpOffset(10.dp, 0.dp),
168 | onDismissRequest = { expanded = false }
169 | ) {
170 | DropdownMenuItem(
171 | text = { Text("Settings") },
172 | onClick = {
173 | expanded = false
174 | navController.navigate(Screen.Settings.route)
175 | }
176 | )
177 | DropdownMenuItem(
178 | text = { Text("About") },
179 | onClick = {
180 | expanded = false
181 | navController.navigate(Screen.About.route)
182 | }
183 | )
184 | }
185 | }
186 | } else {
187 | IconButton(
188 | onClick = {
189 | onEvent(NoteEvent.SetSearchQuery(""))
190 | }
191 | ) {
192 | Icon(
193 | imageVector = Icons.Default.Clear,
194 | contentDescription = "Clear search query"
195 | )
196 | }
197 | }
198 | }
199 | )
200 | } else {
201 | TopAppBar(
202 | title = {
203 | Text(
204 | "${selectedNotes.size} items selected",
205 | style = MaterialTheme.typography.bodyLarge.copy(
206 | fontSize = 18.sp,
207 | fontWeight = FontWeight.SemiBold
208 | )
209 | )
210 | },
211 | colors = TopAppBarDefaults.smallTopAppBarColors(
212 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
213 | navigationIconContentColor = MaterialTheme.colorScheme.inverseSurface,
214 | actionIconContentColor = MaterialTheme.colorScheme.inverseSurface,
215 | titleContentColor = MaterialTheme.colorScheme.inverseSurface
216 | ),
217 | navigationIcon = {
218 | IconButton(
219 | onClick = {
220 | selectedNotes.forEach { note ->
221 | onEvent(NoteEvent.DisableIsSelected(note))
222 | }
223 | selectedNotes.clear()
224 | }
225 | ) {
226 | Icon(
227 | imageVector = Icons.Default.ArrowBack,
228 | contentDescription = "Unselect all"
229 | )
230 | }
231 | },
232 | actions = {
233 | IconButton(
234 | onClick = {
235 | showDeleteDialog = showDeleteDialog.not()
236 | }
237 | ) {
238 | Icon(
239 | imageVector = Icons.Default.Delete,
240 | contentDescription = "Delete notes"
241 | )
242 | }
243 | if (selectedNotes.all { note ->
244 | note.isPinned
245 | }) {
246 | // Unpin note
247 | IconButton(
248 | onClick = {
249 | selectedNotes.forEach { note ->
250 | onEvent(NoteEvent.UnpinNote(note))
251 | pinnedNotes.remove(note)
252 | onEvent(NoteEvent.DisableIsSelected(note))
253 | }
254 | Log.d("pin", pinnedNotes.size.toString())
255 | selectedNotes.clear()
256 | }
257 | ) {
258 | Icon(
259 | imageVector = Icons.Filled.PushPin,
260 | contentDescription = "Unpin notes"
261 | )
262 | }
263 | } else if (selectedNotes.all { note ->
264 | !note.isPinned
265 | }) {
266 | // Pin note
267 | IconButton(
268 | onClick = {
269 | selectedNotes.forEach { note ->
270 | onEvent(NoteEvent.PinNote(note))
271 | pinnedNotes.add(note)
272 | onEvent(NoteEvent.DisableIsSelected(note))
273 | }
274 | selectedNotes.clear()
275 | }
276 | ) {
277 | Icon(
278 | imageVector = Icons.Outlined.PushPin,
279 | contentDescription = "Pin notes"
280 | )
281 | }
282 | }
283 | }
284 | )
285 | }
286 |
287 | LaunchedEffect(key1 = 1, block = {
288 | delay(50)
289 | showScreen = true
290 | })
291 |
292 | if (state.notes.isEmpty()) {
293 | AnimatedVisibility(visible = showScreen) {
294 | Text(
295 | text = "No Notes Saved",
296 | style = MaterialTheme.typography.titleMedium.copy(
297 | color = MaterialTheme.colorScheme.inverseSurface.copy(
298 | alpha = 0.6f
299 | )
300 | )
301 | )
302 | }
303 | } else {
304 | val pinnedNotesList = state.notes.filter { note -> note.isPinned }
305 | val unPinnedNotesList = state.notes.filter { note -> !note.isPinned }
306 | val list = mutableListOf()
307 | list.addAll(pinnedNotesList.reversed())
308 | list.addAll(unPinnedNotesList.reversed())
309 | NotesGrid(
310 | notes = list,
311 | onNoteClick = { note ->
312 | if (selectedNotes.size >= 1) {
313 | if (note.isSelected) {
314 | onEvent(NoteEvent.DisableIsSelected(note))
315 | selectedNotes.remove(note)
316 | } else {
317 | onEvent(NoteEvent.EnableIsSelected(note))
318 | selectedNotes.add(note)
319 | }
320 | } else {
321 | navController.navigate("${Screen.ViewNote.route}/${note.id}")
322 | }
323 | },
324 | onNoteLongClick = { note ->
325 | if (note.isSelected) {
326 | onEvent(NoteEvent.DisableIsSelected(note))
327 | selectedNotes.remove(note)
328 | } else {
329 | onEvent(NoteEvent.EnableIsSelected(note))
330 | selectedNotes.add(note)
331 | }
332 | }
333 | )
334 | }
335 | }
336 | }
337 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/screens/SettingsScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.screens
2 |
3 | import androidx.compose.animation.AnimatedVisibility
4 | import androidx.compose.foundation.clickable
5 | import androidx.compose.foundation.horizontalScroll
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.Row
8 | import androidx.compose.foundation.layout.Spacer
9 | import androidx.compose.foundation.layout.fillMaxWidth
10 | import androidx.compose.foundation.layout.height
11 | import androidx.compose.foundation.layout.padding
12 | import androidx.compose.foundation.layout.width
13 | import androidx.compose.foundation.rememberScrollState
14 | import androidx.compose.foundation.shape.RoundedCornerShape
15 | import androidx.compose.foundation.verticalScroll
16 | import androidx.compose.material.icons.Icons
17 | import androidx.compose.material.icons.filled.ArrowBack
18 | import androidx.compose.material3.Card
19 | import androidx.compose.material3.CardDefaults
20 | import androidx.compose.material3.DropdownMenuItem
21 | import androidx.compose.material3.ExperimentalMaterial3Api
22 | import androidx.compose.material3.ExposedDropdownMenuBox
23 | import androidx.compose.material3.ExposedDropdownMenuDefaults
24 | import androidx.compose.material3.Icon
25 | import androidx.compose.material3.IconButton
26 | import androidx.compose.material3.MaterialTheme
27 | import androidx.compose.material3.Scaffold
28 | import androidx.compose.material3.Switch
29 | import androidx.compose.material3.Text
30 | import androidx.compose.material3.TextField
31 | import androidx.compose.material3.TopAppBar
32 | import androidx.compose.material3.TopAppBarDefaults
33 | import androidx.compose.runtime.Composable
34 | import androidx.compose.runtime.collectAsState
35 | import androidx.compose.runtime.getValue
36 | import androidx.compose.runtime.mutableStateOf
37 | import androidx.compose.runtime.remember
38 | import androidx.compose.runtime.rememberCoroutineScope
39 | import androidx.compose.runtime.setValue
40 | import androidx.compose.ui.Modifier
41 | import androidx.compose.ui.graphics.Color
42 | import androidx.compose.ui.platform.LocalContext
43 | import androidx.compose.ui.res.painterResource
44 | import androidx.compose.ui.unit.dp
45 | import androidx.navigation.NavController
46 | import com.example.learning3.R
47 | import com.example.learning3.StoreThemePrefs
48 | import com.example.learning3.composables.DeleteDialog
49 | import com.example.learning3.composables.SettingsListItem
50 | import com.example.learning3.data.DarkThemeConfig
51 | import com.example.learning3.events.NoteEvent
52 | import kotlinx.coroutines.delay
53 | import kotlinx.coroutines.launch
54 |
55 | @OptIn(ExperimentalMaterial3Api::class)
56 | @Composable
57 | fun SettingsScreen(
58 | navController: NavController,
59 | onEvent: (NoteEvent) -> Unit
60 | ) {
61 | val context = LocalContext.current
62 | val scope = rememberCoroutineScope()
63 | val dataStore = StoreThemePrefs(context)
64 | var useDynamicThemeChecked by remember { mutableStateOf(true) }
65 | var themeModeExpanded by remember { mutableStateOf(false) }
66 | val themeModeOptions = listOf(
67 | "AUTO",
68 | "LIGHT",
69 | "DARK"
70 | )
71 | var selectedOptionText by remember { mutableStateOf(themeModeOptions[0]) }
72 |
73 | var showDeleteDialog by remember { mutableStateOf(false) }
74 | var showDeleteCompleteIcon by remember { mutableStateOf(false) }
75 |
76 | if (showDeleteDialog) {
77 | DeleteDialog(
78 | titleText = "Confirm deletion?",
79 | bodyText = "All notes will be deleted permanently",
80 | onDismissRequest = { showDeleteDialog = false },
81 | onConfirmButtonClick = {
82 | onEvent(NoteEvent.ClearAllNotes)
83 | showDeleteDialog = false
84 | showDeleteCompleteIcon = true
85 | scope.launch {
86 | delay(1500)
87 | showDeleteCompleteIcon = false
88 | }
89 | },
90 | onDismissButtonClick = {
91 | showDeleteDialog = false
92 | }
93 | )
94 | }
95 |
96 | Scaffold(
97 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
98 | contentColor = MaterialTheme.colorScheme.inverseSurface,
99 | topBar = {
100 | TopAppBar(
101 | title = {},
102 | colors = TopAppBarDefaults.smallTopAppBarColors(
103 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
104 | navigationIconContentColor = MaterialTheme.colorScheme.inverseSurface,
105 | titleContentColor = MaterialTheme.colorScheme.inverseSurface
106 | ),
107 | navigationIcon = {
108 | IconButton(
109 | onClick = {
110 | navController.popBackStack()
111 | }
112 | ) {
113 | Icon(Icons.Default.ArrowBack, contentDescription = "Back")
114 | }
115 | }
116 | )
117 | }
118 | ) { padding ->
119 | Column(
120 | modifier = Modifier
121 | .padding(padding)
122 | .verticalScroll(rememberScrollState())
123 | .fillMaxWidth()
124 | ) {
125 | Text(
126 | text = "Settings",
127 | style = MaterialTheme.typography.headlineLarge,
128 | modifier = Modifier
129 | .padding(
130 | horizontal = 16.dp,
131 | vertical = 24.dp
132 | )
133 | .padding(top = 48.dp)
134 | )
135 | SettingsListItem(
136 | title = "Dynamic Theme",
137 | trailingContent = {
138 | Switch(
139 | checked = dataStore.isDynamicThemeEnabled.collectAsState(initial = true).value,
140 | onCheckedChange = {
141 | useDynamicThemeChecked = it
142 | scope.launch {
143 | dataStore.setDynamicThemeEnabled(it)
144 | }
145 | }
146 | )
147 | }
148 | )
149 | if (!dataStore.isDynamicThemeEnabled.collectAsState(initial = true).value) {
150 | SettingsListItem(
151 | title = "Theme Mode",
152 | trailingContent = {
153 | MaterialTheme(
154 | shapes = MaterialTheme.shapes.copy(
155 | extraSmall = RoundedCornerShape(16.dp)
156 | ),
157 | ) {
158 | ExposedDropdownMenuBox(
159 | expanded = themeModeExpanded,
160 | onExpandedChange = {
161 | themeModeExpanded = !themeModeExpanded
162 | }
163 | ) {
164 | TextField(
165 | readOnly = true,
166 | value = dataStore.getThemeMode.collectAsState(initial = DarkThemeConfig.AUTO.toString()).value,
167 | onValueChange = { },
168 | trailingIcon = {
169 | ExposedDropdownMenuDefaults.TrailingIcon(
170 | expanded = themeModeExpanded
171 | )
172 | },
173 | colors = ExposedDropdownMenuDefaults.textFieldColors(
174 | focusedIndicatorColor = Color.Transparent,
175 | unfocusedIndicatorColor = Color.Transparent,
176 | disabledIndicatorColor = Color.Transparent
177 | ),
178 | modifier = Modifier
179 | .menuAnchor()
180 | .width(140.dp)
181 | )
182 | ExposedDropdownMenu(
183 | expanded = themeModeExpanded,
184 | onDismissRequest = { themeModeExpanded = false }
185 | ) {
186 | themeModeOptions.forEach {
187 | DropdownMenuItem(
188 | text = {
189 | Text(
190 | it,
191 | style = MaterialTheme.typography.bodyLarge
192 | )
193 | },
194 | onClick = {
195 | selectedOptionText = it
196 | scope.launch {
197 | dataStore.setThemeMode(it)
198 | }
199 | themeModeExpanded = false
200 | }
201 | )
202 | }
203 | }
204 | }
205 | }
206 | }
207 | )
208 | SettingsListItem(
209 | title = "Color Scheme",
210 | trailingContent = null
211 | )
212 | Row(
213 | modifier = Modifier
214 | .padding(
215 | horizontal = 16.dp,
216 | vertical = 16.dp
217 | )
218 | .horizontalScroll(rememberScrollState())
219 | ) {
220 | // Brown
221 | Card(
222 | modifier = Modifier
223 | .height(200.dp)
224 | .width(96.dp),
225 | colors = CardDefaults.cardColors(
226 | containerColor = Color(0xFFFFDDB0),
227 | ),
228 | onClick = {
229 | scope.launch {
230 | dataStore.setColor("BROWN")
231 | }
232 | },
233 | border = CardDefaults.outlinedCardBorder(
234 | dataStore.getColor.collectAsState(initial = "BROWN").value == "BROWN"
235 | )
236 | ) {
237 |
238 | }
239 | Spacer(modifier = Modifier.width(24.dp))
240 | // Green
241 | Card(
242 | modifier = Modifier
243 | .height(200.dp)
244 | .width(96.dp),
245 | colors = CardDefaults.cardColors(
246 | containerColor = Color(0xFF9EF981),
247 | ),
248 | onClick = {
249 | scope.launch {
250 | dataStore.setColor("GREEN")
251 | }
252 | },
253 | border = CardDefaults.outlinedCardBorder(
254 | dataStore.getColor.collectAsState(initial = "BROWN").value == "GREEN"
255 | )
256 | ) {
257 |
258 | }
259 | Spacer(modifier = Modifier.width(24.dp))
260 | // Blue
261 | Card(
262 | modifier = Modifier
263 | .height(200.dp)
264 | .width(96.dp),
265 | colors = CardDefaults.cardColors(
266 | containerColor = Color(0xFFC9E6FF),
267 | ),
268 | onClick = {
269 | scope.launch {
270 | dataStore.setColor("BLUE")
271 | }
272 | },
273 | border = CardDefaults.outlinedCardBorder(
274 | dataStore.getColor.collectAsState(initial = "BROWN").value == "BLUE"
275 | )
276 | ) {
277 |
278 | }
279 | Spacer(modifier = Modifier.width(24.dp))
280 | // Purple
281 | Card(
282 | modifier = Modifier
283 | .height(200.dp)
284 | .width(96.dp),
285 | colors = CardDefaults.cardColors(
286 | containerColor = Color(0xFFF2DAFF),
287 | ),
288 | onClick = {
289 | scope.launch {
290 | dataStore.setColor("PURPLE")
291 | }
292 | },
293 | border = CardDefaults.outlinedCardBorder(
294 | dataStore.getColor.collectAsState(initial = "BROWN").value == "PURPLE"
295 | )
296 | ) {
297 |
298 | }
299 | Spacer(modifier = Modifier.width(24.dp))
300 | // Pink
301 | Card(
302 | modifier = Modifier
303 | .height(200.dp)
304 | .width(96.dp),
305 | colors = CardDefaults.cardColors(
306 | containerColor = Color(0xFFFFD9E2),
307 | ),
308 | onClick = {
309 | scope.launch {
310 | dataStore.setColor("PINK")
311 | }
312 | },
313 | border = CardDefaults.outlinedCardBorder(
314 | dataStore.getColor.collectAsState(initial = "BROWN").value == "PINK"
315 | )
316 | ) {
317 |
318 | }
319 | Spacer(modifier = Modifier.width(24.dp))
320 | }
321 | }
322 | SettingsListItem(
323 | title = "Clear All Notes",
324 | trailingContent = {
325 | Row {
326 | AnimatedVisibility(visible = showDeleteCompleteIcon) {
327 | Icon(
328 | painter = painterResource(id = R.drawable.baseline_check_circle_24),
329 | contentDescription = "Deletion Complete",
330 | tint = MaterialTheme.colorScheme.primary,
331 | )
332 | }
333 | AnimatedVisibility(visible = !showDeleteCompleteIcon) {
334 | Icon(
335 | painter = painterResource(id = R.drawable.baseline_delete_forever_40),
336 | contentDescription = "Clear All Notes",
337 | tint = MaterialTheme.colorScheme.primary,
338 | modifier = Modifier.clickable {
339 | showDeleteDialog = true
340 | }
341 | )
342 | }
343 | }
344 | }
345 | )
346 | }
347 | }
348 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/screens/ViewNoteScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.screens
2 |
3 | import android.os.Build
4 | import androidx.annotation.RequiresApi
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.Spacer
8 | import androidx.compose.foundation.layout.height
9 | import androidx.compose.foundation.layout.padding
10 | import androidx.compose.foundation.rememberScrollState
11 | import androidx.compose.foundation.shape.RoundedCornerShape
12 | import androidx.compose.foundation.verticalScroll
13 | import androidx.compose.material.icons.Icons
14 | import androidx.compose.material.icons.filled.ArrowBack
15 | import androidx.compose.material.icons.filled.MoreVert
16 | import androidx.compose.material3.CenterAlignedTopAppBar
17 | import androidx.compose.material3.DropdownMenu
18 | import androidx.compose.material3.DropdownMenuItem
19 | import androidx.compose.material3.ExperimentalMaterial3Api
20 | import androidx.compose.material3.Icon
21 | import androidx.compose.material3.IconButton
22 | import androidx.compose.material3.MaterialTheme
23 | import androidx.compose.material3.Scaffold
24 | import androidx.compose.material3.Text
25 | import androidx.compose.material3.TopAppBarDefaults
26 | import androidx.compose.runtime.Composable
27 | import androidx.compose.runtime.getValue
28 | import androidx.compose.runtime.mutableStateOf
29 | import androidx.compose.runtime.remember
30 | import androidx.compose.runtime.setValue
31 | import androidx.compose.ui.Modifier
32 | import androidx.compose.ui.text.font.FontWeight
33 | import androidx.compose.ui.unit.DpOffset
34 | import androidx.compose.ui.unit.dp
35 | import androidx.compose.ui.unit.sp
36 | import androidx.navigation.NavController
37 | import com.example.learning3.composables.DeleteDialog
38 | import com.example.learning3.data.Note
39 | import com.example.learning3.events.NoteEvent
40 | import com.example.learning3.ui.state.NoteState
41 | import com.example.learning3.navigation.Screen
42 | import com.example.learning3.utilities.UtilityFunctions
43 |
44 | @RequiresApi(Build.VERSION_CODES.O)
45 | @OptIn(ExperimentalMaterial3Api::class)
46 | @Composable
47 | fun ViewNoteScreen(
48 | navController: NavController,
49 | selectedNoteId: Long,
50 | state: NoteState,
51 | onEvent: (NoteEvent) -> Unit
52 | ) {
53 | val note: Note? = state.notes.find { note ->
54 | note.id == selectedNoteId
55 | }
56 | var expanded by remember { mutableStateOf(false) }
57 | var showDeleteDialog by remember { mutableStateOf(false) }
58 | val menuItems = listOf(
59 | "Edit note",
60 | "Delete note"
61 | )
62 | if (showDeleteDialog) {
63 | DeleteDialog(
64 | titleText = "Confirm deletion?",
65 | bodyText = "The note will be deleted permanently",
66 | onDismissRequest = { showDeleteDialog = false },
67 | onConfirmButtonClick = {
68 | onEvent(NoteEvent.DeleteNote(note!!))
69 | navController.navigate(Screen.Notes.route) {
70 | popUpTo(Screen.Notes.route) {
71 | inclusive = true
72 | }
73 | }
74 | },
75 | onDismissButtonClick = {
76 | showDeleteDialog = false
77 | }
78 | )
79 | }
80 | Scaffold(
81 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
82 | contentColor = MaterialTheme.colorScheme.inverseSurface,
83 | topBar = {
84 | CenterAlignedTopAppBar(
85 | title = { Text(
86 | text = "Last modified on ${UtilityFunctions.formatDateAndTime(note?.lastModified ?: 0)}",
87 | style = MaterialTheme.typography.bodySmall.copy(
88 | fontSize = 12.sp,
89 | )) },
90 | colors = TopAppBarDefaults.smallTopAppBarColors(
91 | containerColor = MaterialTheme.colorScheme.inverseOnSurface,
92 | navigationIconContentColor = MaterialTheme.colorScheme.inverseSurface,
93 | actionIconContentColor = MaterialTheme.colorScheme.inverseSurface,
94 | titleContentColor = MaterialTheme.colorScheme.inverseSurface
95 | ),
96 | navigationIcon = {
97 | IconButton(
98 | onClick = {
99 | navController.popBackStack()
100 | }
101 | ) {
102 | Icon(Icons.Default.ArrowBack,contentDescription = "Back")
103 | }
104 | },
105 | actions = {
106 | IconButton(
107 | onClick = {
108 | expanded = true
109 | }
110 | ) {
111 | Icon(Icons.Default.MoreVert,
112 | contentDescription = "More options")
113 | }
114 | MaterialTheme(
115 | shapes = MaterialTheme.shapes.copy(
116 | extraSmall = RoundedCornerShape(16.dp)
117 | ),
118 | ) {
119 | DropdownMenu(
120 | expanded = expanded,
121 | offset = DpOffset(10.dp,0.dp),
122 | onDismissRequest = { expanded = false }
123 | ) {
124 | DropdownMenuItem(
125 | text = { Text("Edit") },
126 | onClick = {
127 | expanded = false
128 | onEvent(NoteEvent.StartEditing(note!!))
129 | navController.navigate("${Screen.EditNote.route}/${selectedNoteId}")
130 | }
131 | )
132 | DropdownMenuItem(
133 | text = { Text("Delete") },
134 | onClick = {
135 | expanded = false
136 | showDeleteDialog = showDeleteDialog.not()
137 | }
138 | )
139 | }
140 | }
141 | }
142 | )
143 | }
144 | ) { padding ->
145 | Column(
146 | modifier = Modifier
147 | .padding(padding)
148 | .padding(
149 | horizontal = 16.dp,
150 | )
151 | .verticalScroll(rememberScrollState())
152 | ) {
153 | Text(
154 | text = note?.title ?: "",
155 | style = MaterialTheme.typography.bodyLarge.copy(
156 | fontSize = 18.sp,
157 | fontWeight = FontWeight.SemiBold,
158 | lineHeight = 22.sp
159 | ),
160 | )
161 | Spacer(
162 | modifier = Modifier
163 | .height(16.dp)
164 | )
165 | Text(
166 | text = note?.content ?: "",
167 | style = MaterialTheme.typography.bodyMedium.copy(
168 | fontSize = 16.sp,
169 | )
170 | )
171 | Spacer(
172 | modifier = Modifier
173 | .height(16.dp)
174 | )
175 | }
176 | }
177 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/state/NoteState.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.state
2 |
3 | import com.example.learning3.data.Note
4 |
5 | data class NoteState(
6 | val notes: List = emptyList(),
7 | val title: String = "",
8 | val content: String = "",
9 | val searchQuery: String = "",
10 | val isSearching: Boolean = false,
11 | val editingNote: Note? = null,
12 | )
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val Purple80 = Color(0xFFD0BCFF)
6 | val PurpleGrey80 = Color(0xFFCCC2DC)
7 | val Pink80 = Color(0xFFEFB8C8)
8 |
9 | val Purple40 = Color(0xFF6650a4)
10 | val PurpleGrey40 = Color(0xFF625b71)
11 | val Pink40 = Color(0xFF7D5260)
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme
2 |
3 | import android.app.Activity
4 | import android.os.Build
5 | import androidx.compose.foundation.isSystemInDarkTheme
6 | import androidx.compose.material3.MaterialTheme
7 | import androidx.compose.material3.darkColorScheme
8 | import androidx.compose.material3.dynamicDarkColorScheme
9 | import androidx.compose.material3.dynamicLightColorScheme
10 | import androidx.compose.material3.lightColorScheme
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.SideEffect
13 | import androidx.compose.runtime.collectAsState
14 | import androidx.compose.runtime.rememberCoroutineScope
15 | import androidx.compose.ui.graphics.toArgb
16 | import androidx.compose.ui.platform.LocalContext
17 | import androidx.compose.ui.platform.LocalView
18 | import androidx.core.view.WindowCompat
19 | import com.example.learning3.StoreThemePrefs
20 | import com.example.learning3.ui.theme.themes.BlueDarkColors
21 | import com.example.learning3.ui.theme.themes.BlueLightColors
22 | import com.example.learning3.ui.theme.themes.BrownDarkColors
23 | import com.example.learning3.ui.theme.themes.BrownLightColors
24 | import com.example.learning3.ui.theme.themes.GreenDarkColors
25 | import com.example.learning3.ui.theme.themes.GreenLightColors
26 | import com.example.learning3.ui.theme.themes.PinkDarkColors
27 | import com.example.learning3.ui.theme.themes.PinkLightColors
28 | import com.example.learning3.ui.theme.themes.PurpleDarkColors
29 | import com.example.learning3.ui.theme.themes.PurpleLightColors
30 |
31 | private val DarkColorScheme = darkColorScheme(
32 | primary = Purple80,
33 | secondary = PurpleGrey80,
34 | tertiary = Pink80
35 | )
36 |
37 | private val LightColorScheme = lightColorScheme(
38 | primary = Purple40,
39 | secondary = PurpleGrey40,
40 | tertiary = Pink40
41 |
42 | /* Other default colors to override
43 | background = Color(0xFFFFFBFE),
44 | surface = Color(0xFFFFFBFE),
45 | onPrimary = Color.White,
46 | onSecondary = Color.White,
47 | onTertiary = Color.White,
48 | onBackground = Color(0xFF1C1B1F),
49 | onSurface = Color(0xFF1C1B1F),
50 | */
51 | )
52 |
53 | @Composable
54 | fun Learning3Theme(
55 | // darkTheme: Boolean = isSystemInDarkTheme(),
56 | // Dynamic color is available on Android 12+
57 | // dynamicColor: Boolean = true,
58 | content: @Composable () -> Unit
59 | ) {
60 | val context = LocalContext.current
61 | val dataStore = StoreThemePrefs(context)
62 | val dynamicColor = dataStore.isDynamicThemeEnabled.collectAsState(initial = true)
63 | val themeMode = dataStore.getThemeMode.collectAsState(initial = "AUTO")
64 | val darkTheme = isSystemInDarkTheme()
65 | val color = dataStore.getColor.collectAsState(initial = "BROWN")
66 |
67 | val colorScheme = when {
68 | dynamicColor.value && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
69 | // val context = LocalContext.current
70 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
71 | }
72 |
73 | themeMode.value == "AUTO" && darkTheme && color.value == "BROWN" -> BrownDarkColors
74 | themeMode.value == "AUTO" && darkTheme && color.value == "GREEN" -> GreenDarkColors
75 | themeMode.value == "AUTO" && darkTheme && color.value == "BLUE" -> BlueDarkColors
76 | themeMode.value == "AUTO" && darkTheme && color.value == "PURPLE" -> PurpleDarkColors
77 | themeMode.value == "AUTO" && darkTheme && color.value == "PINK" -> PinkDarkColors
78 |
79 | themeMode.value == "AUTO" && !darkTheme && color.value == "BROWN" -> BrownLightColors
80 | themeMode.value == "AUTO" && !darkTheme && color.value == "GREEN" -> GreenLightColors
81 | themeMode.value == "AUTO" && !darkTheme && color.value == "BLUE" -> BlueLightColors
82 | themeMode.value == "AUTO" && !darkTheme && color.value == "PURPLE" -> PurpleLightColors
83 | themeMode.value == "AUTO" && !darkTheme && color.value == "PINK" -> PinkLightColors
84 | themeMode.value == "AUTO" && !darkTheme -> PinkLightColors
85 |
86 | themeMode.value == "DARK" && color.value == "BROWN" -> BrownDarkColors
87 | themeMode.value == "DARK" && color.value == "GREEN" -> GreenDarkColors
88 | themeMode.value == "DARK" && color.value == "BLUE" -> BlueDarkColors
89 | themeMode.value == "DARK" && color.value == "PURPLE" -> PurpleDarkColors
90 | themeMode.value == "DARK" && color.value == "PINK" -> PinkDarkColors
91 |
92 | themeMode.value == "LIGHT" && color.value == "BROWN" -> BrownLightColors
93 | themeMode.value == "LIGHT" && color.value == "GREEN" -> GreenLightColors
94 | themeMode.value == "LIGHT" && color.value == "BLUE" -> BlueLightColors
95 | themeMode.value == "LIGHT" && color.value == "PURPLE" -> PurpleLightColors
96 | themeMode.value == "LIGHT" && color.value == "PINK" -> PinkLightColors
97 |
98 | else -> BrownLightColors
99 | }
100 | val view = LocalView.current
101 | if (!view.isInEditMode) {
102 | SideEffect {
103 | val window = (view.context as Activity).window
104 | window.statusBarColor = colorScheme.primary.toArgb()
105 | WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
106 | }
107 | }
108 |
109 | MaterialTheme(
110 | colorScheme = colorScheme,
111 | typography = Typography,
112 | content = content
113 | )
114 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme
2 |
3 | import androidx.compose.material3.Typography
4 | import androidx.compose.ui.text.TextStyle
5 | import androidx.compose.ui.text.font.FontFamily
6 | import androidx.compose.ui.text.font.FontWeight
7 | import androidx.compose.ui.unit.sp
8 |
9 | // Set of Material typography styles to start with
10 | val Typography = Typography(
11 | bodyLarge = TextStyle(
12 | fontFamily = FontFamily.Default,
13 | fontWeight = FontWeight.Normal,
14 | fontSize = 16.sp,
15 | lineHeight = 24.sp,
16 | letterSpacing = 0.5.sp
17 | )
18 | /* Other default text styles to override
19 | titleLarge = TextStyle(
20 | fontFamily = FontFamily.Default,
21 | fontWeight = FontWeight.Normal,
22 | fontSize = 22.sp,
23 | lineHeight = 28.sp,
24 | letterSpacing = 0.sp
25 | ),
26 | labelSmall = TextStyle(
27 | fontFamily = FontFamily.Default,
28 | fontWeight = FontWeight.Medium,
29 | fontSize = 11.sp,
30 | lineHeight = 16.sp,
31 | letterSpacing = 0.5.sp
32 | )
33 | */
34 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/colors/BlueColor.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.colors
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val blue_theme_light_primary = Color(0xFF006492)
6 | val blue_theme_light_onPrimary = Color(0xFFFFFFFF)
7 | val blue_theme_light_primaryContainer = Color(0xFFC9E6FF)
8 | val blue_theme_light_onPrimaryContainer = Color(0xFF001E2F)
9 | val blue_theme_light_secondary = Color(0xFF50606E)
10 | val blue_theme_light_onSecondary = Color(0xFFFFFFFF)
11 | val blue_theme_light_secondaryContainer = Color(0xFFD3E5F5)
12 | val blue_theme_light_onSecondaryContainer = Color(0xFF0C1D29)
13 | val blue_theme_light_tertiary = Color(0xFF64597B)
14 | val blue_theme_light_onTertiary = Color(0xFFFFFFFF)
15 | val blue_theme_light_tertiaryContainer = Color(0xFFEADDFF)
16 | val blue_theme_light_onTertiaryContainer = Color(0xFF201634)
17 | val blue_theme_light_error = Color(0xFFBA1A1A)
18 | val blue_theme_light_errorContainer = Color(0xFFFFDAD6)
19 | val blue_theme_light_onError = Color(0xFFFFFFFF)
20 | val blue_theme_light_onErrorContainer = Color(0xFF410002)
21 | val blue_theme_light_background = Color(0xFFFCFCFF)
22 | val blue_theme_light_onBackground = Color(0xFF1A1C1E)
23 | val blue_theme_light_surface = Color(0xFFFCFCFF)
24 | val blue_theme_light_onSurface = Color(0xFF1A1C1E)
25 | val blue_theme_light_surfaceVariant = Color(0xFFDDE3EA)
26 | val blue_theme_light_onSurfaceVariant = Color(0xFF41474D)
27 | val blue_theme_light_outline = Color(0xFF72787E)
28 | val blue_theme_light_inverseOnSurface = Color(0xFFF0F0F3)
29 | val blue_theme_light_inverseSurface = Color(0xFF2E3133)
30 | val blue_theme_light_inversePrimary = Color(0xFF8BCEFF)
31 | val blue_theme_light_shadow = Color(0xFF000000)
32 | val blue_theme_light_surfaceTint = Color(0xFF006492)
33 | val blue_theme_light_outlineVariant = Color(0xFFC1C7CE)
34 | val blue_theme_light_scrim = Color(0xFF000000)
35 |
36 | val blue_theme_dark_primary = Color(0xFF8BCEFF)
37 | val blue_theme_dark_onPrimary = Color(0xFF00344E)
38 | val blue_theme_dark_primaryContainer = Color(0xFF004B6F)
39 | val blue_theme_dark_onPrimaryContainer = Color(0xFFC9E6FF)
40 | val blue_theme_dark_secondary = Color(0xFFB7C9D9)
41 | val blue_theme_dark_onSecondary = Color(0xFF22323F)
42 | val blue_theme_dark_secondaryContainer = Color(0xFF384956)
43 | val blue_theme_dark_onSecondaryContainer = Color(0xFFD3E5F5)
44 | val blue_theme_dark_tertiary = Color(0xFFCFC0E8)
45 | val blue_theme_dark_onTertiary = Color(0xFF352B4B)
46 | val blue_theme_dark_tertiaryContainer = Color(0xFF4C4162)
47 | val blue_theme_dark_onTertiaryContainer = Color(0xFFEADDFF)
48 | val blue_theme_dark_error = Color(0xFFFFB4AB)
49 | val blue_theme_dark_errorContainer = Color(0xFF93000A)
50 | val blue_theme_dark_onError = Color(0xFF690005)
51 | val blue_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
52 | val blue_theme_dark_background = Color(0xFF1A1C1E)
53 | val blue_theme_dark_onBackground = Color(0xFFE2E2E5)
54 | val blue_theme_dark_surface = Color(0xFF1A1C1E)
55 | val blue_theme_dark_onSurface = Color(0xFFE2E2E5)
56 | val blue_theme_dark_surfaceVariant = Color(0xFF41474D)
57 | val blue_theme_dark_onSurfaceVariant = Color(0xFFC1C7CE)
58 | val blue_theme_dark_outline = Color(0xFF8B9198)
59 | val blue_theme_dark_inverseOnSurface = Color(0xFF1A1C1E)
60 | val blue_theme_dark_inverseSurface = Color(0xFFE2E2E5)
61 | val blue_theme_dark_inversePrimary = Color(0xFF006492)
62 | val blue_theme_dark_shadow = Color(0xFF000000)
63 | val blue_theme_dark_surfaceTint = Color(0xFF8BCEFF)
64 | val blue_theme_dark_outlineVariant = Color(0xFF41474D)
65 | val blue_theme_dark_scrim = Color(0xFF000000)
66 |
67 |
68 | val blue_seed = Color(0xFF006593)
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/colors/BrownColor.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.colors
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val brown_theme_light_primary = Color(0xFF805600)
6 | val brown_theme_light_onPrimary = Color(0xFFFFFFFF)
7 | val brown_theme_light_primaryContainer = Color(0xFFFFDDB0)
8 | val brown_theme_light_onPrimaryContainer = Color(0xFF281800)
9 | val brown_theme_light_secondary = Color(0xFF6F5B40)
10 | val brown_theme_light_onSecondary = Color(0xFFFFFFFF)
11 | val brown_theme_light_secondaryContainer = Color(0xFFF9DEBB)
12 | val brown_theme_light_onSecondaryContainer = Color(0xFF261904)
13 | val brown_theme_light_tertiary = Color(0xFF506441)
14 | val brown_theme_light_onTertiary = Color(0xFFFFFFFF)
15 | val brown_theme_light_tertiaryContainer = Color(0xFFD2EABD)
16 | val brown_theme_light_onTertiaryContainer = Color(0xFF0E2004)
17 | val brown_theme_light_error = Color(0xFFBA1A1A)
18 | val brown_theme_light_errorContainer = Color(0xFFFFDAD6)
19 | val brown_theme_light_onError = Color(0xFFFFFFFF)
20 | val brown_theme_light_onErrorContainer = Color(0xFF410002)
21 | val brown_theme_light_background = Color(0xFFFFFBFF)
22 | val brown_theme_light_onBackground = Color(0xFF1F1B16)
23 | val brown_theme_light_surface = Color(0xFFFFFBFF)
24 | val brown_theme_light_onSurface = Color(0xFF1F1B16)
25 | val brown_theme_light_surfaceVariant = Color(0xFFEFE0CF)
26 | val brown_theme_light_onSurfaceVariant = Color(0xFF4F4539)
27 | val brown_theme_light_outline = Color(0xFF817567)
28 | val brown_theme_light_inverseOnSurface = Color(0xFFF9EFE7)
29 | val brown_theme_light_inverseSurface = Color(0xFF34302A)
30 | val brown_theme_light_inversePrimary = Color(0xFFFDBA4B)
31 | val brown_theme_light_shadow = Color(0xFF000000)
32 | val brown_theme_light_surfaceTint = Color(0xFF805600)
33 | val brown_theme_light_outlineVariant = Color(0xFFD2C4B4)
34 | val brown_theme_light_scrim = Color(0xFF000000)
35 |
36 | val brown_theme_dark_primary = Color(0xFFFDBA4B)
37 | val brown_theme_dark_onPrimary = Color(0xFF442C00)
38 | val brown_theme_dark_primaryContainer = Color(0xFF614000)
39 | val brown_theme_dark_onPrimaryContainer = Color(0xFFFFDDB0)
40 | val brown_theme_dark_secondary = Color(0xFFDCC3A1)
41 | val brown_theme_dark_onSecondary = Color(0xFF3D2E16)
42 | val brown_theme_dark_secondaryContainer = Color(0xFF55442A)
43 | val brown_theme_dark_onSecondaryContainer = Color(0xFFF9DEBB)
44 | val brown_theme_dark_tertiary = Color(0xFFB6CEA3)
45 | val brown_theme_dark_onTertiary = Color(0xFF233517)
46 | val brown_theme_dark_tertiaryContainer = Color(0xFF394C2B)
47 | val brown_theme_dark_onTertiaryContainer = Color(0xFFD2EABD)
48 | val brown_theme_dark_error = Color(0xFFFFB4AB)
49 | val brown_theme_dark_errorContainer = Color(0xFF93000A)
50 | val brown_theme_dark_onError = Color(0xFF690005)
51 | val brown_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
52 | val brown_theme_dark_background = Color(0xFF1F1B16)
53 | val brown_theme_dark_onBackground = Color(0xFFEAE1D9)
54 | val brown_theme_dark_surface = Color(0xFF1F1B16)
55 | val brown_theme_dark_onSurface = Color(0xFFEAE1D9)
56 | val brown_theme_dark_surfaceVariant = Color(0xFF4F4539)
57 | val brown_theme_dark_onSurfaceVariant = Color(0xFFD2C4B4)
58 | val brown_theme_dark_outline = Color(0xFF9B8F80)
59 | val brown_theme_dark_inverseOnSurface = Color(0xFF1F1B16)
60 | val brown_theme_dark_inverseSurface = Color(0xFFEAE1D9)
61 | val brown_theme_dark_inversePrimary = Color(0xFF805600)
62 | val brown_theme_dark_shadow = Color(0xFF000000)
63 | val brown_theme_dark_surfaceTint = Color(0xFFFDBA4B)
64 | val brown_theme_dark_outlineVariant = Color(0xFF4F4539)
65 | val brown_theme_dark_scrim = Color(0xFF000000)
66 |
67 |
68 | val brown_seed = Color(0xFF805600)
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/colors/GreenColor.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.colors
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val green_theme_light_primary = Color(0xFF146E00)
6 | val green_theme_light_onPrimary = Color(0xFFFFFFFF)
7 | val green_theme_light_primaryContainer = Color(0xFF9EF981)
8 | val green_theme_light_onPrimaryContainer = Color(0xFF022100)
9 | val green_theme_light_secondary = Color(0xFF54624D)
10 | val green_theme_light_onSecondary = Color(0xFFFFFFFF)
11 | val green_theme_light_secondaryContainer = Color(0xFFD7E8CC)
12 | val green_theme_light_onSecondaryContainer = Color(0xFF121F0E)
13 | val green_theme_light_tertiary = Color(0xFF386668)
14 | val green_theme_light_onTertiary = Color(0xFFFFFFFF)
15 | val green_theme_light_tertiaryContainer = Color(0xFFBCEBED)
16 | val green_theme_light_onTertiaryContainer = Color(0xFF002021)
17 | val green_theme_light_error = Color(0xFFBA1A1A)
18 | val green_theme_light_errorContainer = Color(0xFFFFDAD6)
19 | val green_theme_light_onError = Color(0xFFFFFFFF)
20 | val green_theme_light_onErrorContainer = Color(0xFF410002)
21 | val green_theme_light_background = Color(0xFFFDFDF6)
22 | val green_theme_light_onBackground = Color(0xFF1A1C18)
23 | val green_theme_light_surface = Color(0xFFFDFDF6)
24 | val green_theme_light_onSurface = Color(0xFF1A1C18)
25 | val green_theme_light_surfaceVariant = Color(0xFFDFE4D7)
26 | val green_theme_light_onSurfaceVariant = Color(0xFF43483F)
27 | val green_theme_light_outline = Color(0xFF73796E)
28 | val green_theme_light_inverseOnSurface = Color(0xFFF1F1EA)
29 | val green_theme_light_inverseSurface = Color(0xFF2F312D)
30 | val green_theme_light_inversePrimary = Color(0xFF83DB68)
31 | val green_theme_light_shadow = Color(0xFF000000)
32 | val green_theme_light_surfaceTint = Color(0xFF146E00)
33 | val green_theme_light_outlineVariant = Color(0xFFC3C8BC)
34 | val green_theme_light_scrim = Color(0xFF000000)
35 |
36 | val green_theme_dark_primary = Color(0xFF83DB68)
37 | val green_theme_dark_onPrimary = Color(0xFF063900)
38 | val green_theme_dark_primaryContainer = Color(0xFF0D5300)
39 | val green_theme_dark_onPrimaryContainer = Color(0xFF9EF981)
40 | val green_theme_dark_secondary = Color(0xFFBBCBB1)
41 | val green_theme_dark_onSecondary = Color(0xFF273421)
42 | val green_theme_dark_secondaryContainer = Color(0xFF3D4B36)
43 | val green_theme_dark_onSecondaryContainer = Color(0xFFD7E8CC)
44 | val green_theme_dark_tertiary = Color(0xFFA0CFD1)
45 | val green_theme_dark_onTertiary = Color(0xFF003739)
46 | val green_theme_dark_tertiaryContainer = Color(0xFF1E4E50)
47 | val green_theme_dark_onTertiaryContainer = Color(0xFFBCEBED)
48 | val green_theme_dark_error = Color(0xFFFFB4AB)
49 | val green_theme_dark_errorContainer = Color(0xFF93000A)
50 | val green_theme_dark_onError = Color(0xFF690005)
51 | val green_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
52 | val green_theme_dark_background = Color(0xFF1A1C18)
53 | val green_theme_dark_onBackground = Color(0xFFE2E3DC)
54 | val green_theme_dark_surface = Color(0xFF1A1C18)
55 | val green_theme_dark_onSurface = Color(0xFFE2E3DC)
56 | val green_theme_dark_surfaceVariant = Color(0xFF43483F)
57 | val green_theme_dark_onSurfaceVariant = Color(0xFFC3C8BC)
58 | val green_theme_dark_outline = Color(0xFF8D9387)
59 | val green_theme_dark_inverseOnSurface = Color(0xFF1A1C18)
60 | val green_theme_dark_inverseSurface = Color(0xFFE2E3DC)
61 | val green_theme_dark_inversePrimary = Color(0xFF146E00)
62 | val green_theme_dark_shadow = Color(0xFF000000)
63 | val green_theme_dark_surfaceTint = Color(0xFF83DB68)
64 | val green_theme_dark_outlineVariant = Color(0xFF43483F)
65 | val green_theme_dark_scrim = Color(0xFF000000)
66 |
67 |
68 | val green_seed = Color(0xFF146E00)
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/colors/PinkColor.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.colors
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val pink_theme_light_primary = Color(0xFFB80A63)
6 | val pink_theme_light_onPrimary = Color(0xFFFFFFFF)
7 | val pink_theme_light_primaryContainer = Color(0xFFFFD9E2)
8 | val pink_theme_light_onPrimaryContainer = Color(0xFF3E001D)
9 | val pink_theme_light_secondary = Color(0xFF74565F)
10 | val pink_theme_light_onSecondary = Color(0xFFFFFFFF)
11 | val pink_theme_light_secondaryContainer = Color(0xFFFFD9E2)
12 | val pink_theme_light_onSecondaryContainer = Color(0xFF2B151C)
13 | val pink_theme_light_tertiary = Color(0xFF7C5635)
14 | val pink_theme_light_onTertiary = Color(0xFFFFFFFF)
15 | val pink_theme_light_tertiaryContainer = Color(0xFFFFDCC1)
16 | val pink_theme_light_onTertiaryContainer = Color(0xFF2E1500)
17 | val pink_theme_light_error = Color(0xFFBA1A1A)
18 | val pink_theme_light_errorContainer = Color(0xFFFFDAD6)
19 | val pink_theme_light_onError = Color(0xFFFFFFFF)
20 | val pink_theme_light_onErrorContainer = Color(0xFF410002)
21 | val pink_theme_light_background = Color(0xFFFFFBFF)
22 | val pink_theme_light_onBackground = Color(0xFF201A1B)
23 | val pink_theme_light_surface = Color(0xFFFFFBFF)
24 | val pink_theme_light_onSurface = Color(0xFF201A1B)
25 | val pink_theme_light_surfaceVariant = Color(0xFFF2DDE1)
26 | val pink_theme_light_onSurfaceVariant = Color(0xFF514347)
27 | val pink_theme_light_outline = Color(0xFF837377)
28 | val pink_theme_light_inverseOnSurface = Color(0xFFFAEEEF)
29 | val pink_theme_light_inverseSurface = Color(0xFF352F30)
30 | val pink_theme_light_inversePrimary = Color(0xFFFFB1C8)
31 | val pink_theme_light_shadow = Color(0xFF000000)
32 | val pink_theme_light_surfaceTint = Color(0xFFB80A63)
33 | val pink_theme_light_outlineVariant = Color(0xFFD5C2C6)
34 | val pink_theme_light_scrim = Color(0xFF000000)
35 |
36 | val pink_theme_dark_primary = Color(0xFFFFB1C8)
37 | val pink_theme_dark_onPrimary = Color(0xFF650033)
38 | val pink_theme_dark_primaryContainer = Color(0xFF8E004A)
39 | val pink_theme_dark_onPrimaryContainer = Color(0xFFFFD9E2)
40 | val pink_theme_dark_secondary = Color(0xFFE3BDC6)
41 | val pink_theme_dark_onSecondary = Color(0xFF422931)
42 | val pink_theme_dark_secondaryContainer = Color(0xFF5A3F47)
43 | val pink_theme_dark_onSecondaryContainer = Color(0xFFFFD9E2)
44 | val pink_theme_dark_tertiary = Color(0xFFEFBD94)
45 | val pink_theme_dark_onTertiary = Color(0xFF48290B)
46 | val pink_theme_dark_tertiaryContainer = Color(0xFF613F20)
47 | val pink_theme_dark_onTertiaryContainer = Color(0xFFFFDCC1)
48 | val pink_theme_dark_error = Color(0xFFFFB4AB)
49 | val pink_theme_dark_errorContainer = Color(0xFF93000A)
50 | val pink_theme_dark_onError = Color(0xFF690005)
51 | val pink_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
52 | val pink_theme_dark_background = Color(0xFF201A1B)
53 | val pink_theme_dark_onBackground = Color(0xFFEBE0E1)
54 | val pink_theme_dark_surface = Color(0xFF201A1B)
55 | val pink_theme_dark_onSurface = Color(0xFFEBE0E1)
56 | val pink_theme_dark_surfaceVariant = Color(0xFF514347)
57 | val pink_theme_dark_onSurfaceVariant = Color(0xFFD5C2C6)
58 | val pink_theme_dark_outline = Color(0xFF9E8C90)
59 | val pink_theme_dark_inverseOnSurface = Color(0xFF201A1B)
60 | val pink_theme_dark_inverseSurface = Color(0xFFEBE0E1)
61 | val pink_theme_dark_inversePrimary = Color(0xFFB80A63)
62 | val pink_theme_dark_shadow = Color(0xFF000000)
63 | val pink_theme_dark_surfaceTint = Color(0xFFFFB1C8)
64 | val pink_theme_dark_outlineVariant = Color(0xFF514347)
65 | val pink_theme_dark_scrim = Color(0xFF000000)
66 |
67 |
68 | val pink_seed = Color(0xFFB80B63)
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/colors/PurpleColor.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.colors
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val purple_theme_light_primary = Color(0xFF8B1BD9)
6 | val purple_theme_light_onPrimary = Color(0xFFFFFFFF)
7 | val purple_theme_light_primaryContainer = Color(0xFFF2DAFF)
8 | val purple_theme_light_onPrimaryContainer = Color(0xFF2E004E)
9 | val purple_theme_light_secondary = Color(0xFF675A6E)
10 | val purple_theme_light_onSecondary = Color(0xFFFFFFFF)
11 | val purple_theme_light_secondaryContainer = Color(0xFFEEDDF6)
12 | val purple_theme_light_onSecondaryContainer = Color(0xFF221829)
13 | val purple_theme_light_tertiary = Color(0xFF815155)
14 | val purple_theme_light_onTertiary = Color(0xFFFFFFFF)
15 | val purple_theme_light_tertiaryContainer = Color(0xFFFFDADB)
16 | val purple_theme_light_onTertiaryContainer = Color(0xFF321015)
17 | val purple_theme_light_error = Color(0xFFBA1A1A)
18 | val purple_theme_light_errorContainer = Color(0xFFFFDAD6)
19 | val purple_theme_light_onError = Color(0xFFFFFFFF)
20 | val purple_theme_light_onErrorContainer = Color(0xFF410002)
21 | val purple_theme_light_background = Color(0xFFFFFBFF)
22 | val purple_theme_light_onBackground = Color(0xFF1D1B1E)
23 | val purple_theme_light_surface = Color(0xFFFFFBFF)
24 | val purple_theme_light_onSurface = Color(0xFF1D1B1E)
25 | val purple_theme_light_surfaceVariant = Color(0xFFE9DFEA)
26 | val purple_theme_light_onSurfaceVariant = Color(0xFF4B454D)
27 | val purple_theme_light_outline = Color(0xFF7C757E)
28 | val purple_theme_light_inverseOnSurface = Color(0xFFF6EFF3)
29 | val purple_theme_light_inverseSurface = Color(0xFF322F33)
30 | val purple_theme_light_inversePrimary = Color(0xFFE0B6FF)
31 | val purple_theme_light_shadow = Color(0xFF000000)
32 | val purple_theme_light_surfaceTint = Color(0xFF8B1BD9)
33 | val purple_theme_light_outlineVariant = Color(0xFFCDC3CE)
34 | val purple_theme_light_scrim = Color(0xFF000000)
35 |
36 | val purple_theme_dark_primary = Color(0xFFE0B6FF)
37 | val purple_theme_dark_onPrimary = Color(0xFF4C007C)
38 | val purple_theme_dark_primaryContainer = Color(0xFF6C00AE)
39 | val purple_theme_dark_onPrimaryContainer = Color(0xFFF2DAFF)
40 | val purple_theme_dark_secondary = Color(0xFFD1C1D9)
41 | val purple_theme_dark_onSecondary = Color(0xFF372C3F)
42 | val purple_theme_dark_secondaryContainer = Color(0xFF4E4256)
43 | val purple_theme_dark_onSecondaryContainer = Color(0xFFEEDDF6)
44 | val purple_theme_dark_tertiary = Color(0xFFF4B7BB)
45 | val purple_theme_dark_onTertiary = Color(0xFF4C2529)
46 | val purple_theme_dark_tertiaryContainer = Color(0xFF663A3F)
47 | val purple_theme_dark_onTertiaryContainer = Color(0xFFFFDADB)
48 | val purple_theme_dark_error = Color(0xFFFFB4AB)
49 | val purple_theme_dark_errorContainer = Color(0xFF93000A)
50 | val purple_theme_dark_onError = Color(0xFF690005)
51 | val purple_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
52 | val purple_theme_dark_background = Color(0xFF1D1B1E)
53 | val purple_theme_dark_onBackground = Color(0xFFE7E1E5)
54 | val purple_theme_dark_surface = Color(0xFF1D1B1E)
55 | val purple_theme_dark_onSurface = Color(0xFFE7E1E5)
56 | val purple_theme_dark_surfaceVariant = Color(0xFF4B454D)
57 | val purple_theme_dark_onSurfaceVariant = Color(0xFFCDC3CE)
58 | val purple_theme_dark_outline = Color(0xFF968E98)
59 | val purple_theme_dark_inverseOnSurface = Color(0xFF1D1B1E)
60 | val purple_theme_dark_inverseSurface = Color(0xFFE7E1E5)
61 | val purple_theme_dark_inversePrimary = Color(0xFF8B1BD9)
62 | val purple_theme_dark_shadow = Color(0xFF000000)
63 | val purple_theme_dark_surfaceTint = Color(0xFFE0B6FF)
64 | val purple_theme_dark_outlineVariant = Color(0xFF4B454D)
65 | val purple_theme_dark_scrim = Color(0xFF000000)
66 |
67 |
68 | val purple_seed = Color(0xFF8B1CD9)
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/themes/BlueTheme.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.themes
2 |
3 | import androidx.compose.material3.darkColorScheme
4 | import androidx.compose.material3.lightColorScheme
5 | import com.example.learning3.ui.theme.colors.blue_theme_dark_background
6 | import com.example.learning3.ui.theme.colors.blue_theme_dark_error
7 | import com.example.learning3.ui.theme.colors.blue_theme_dark_errorContainer
8 | import com.example.learning3.ui.theme.colors.blue_theme_dark_inverseOnSurface
9 | import com.example.learning3.ui.theme.colors.blue_theme_dark_inversePrimary
10 | import com.example.learning3.ui.theme.colors.blue_theme_dark_inverseSurface
11 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onBackground
12 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onError
13 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onErrorContainer
14 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onPrimary
15 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onPrimaryContainer
16 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onSecondary
17 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onSecondaryContainer
18 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onSurface
19 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onSurfaceVariant
20 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onTertiary
21 | import com.example.learning3.ui.theme.colors.blue_theme_dark_onTertiaryContainer
22 | import com.example.learning3.ui.theme.colors.blue_theme_dark_outline
23 | import com.example.learning3.ui.theme.colors.blue_theme_dark_outlineVariant
24 | import com.example.learning3.ui.theme.colors.blue_theme_dark_primary
25 | import com.example.learning3.ui.theme.colors.blue_theme_dark_primaryContainer
26 | import com.example.learning3.ui.theme.colors.blue_theme_dark_scrim
27 | import com.example.learning3.ui.theme.colors.blue_theme_dark_secondary
28 | import com.example.learning3.ui.theme.colors.blue_theme_dark_secondaryContainer
29 | import com.example.learning3.ui.theme.colors.blue_theme_dark_surface
30 | import com.example.learning3.ui.theme.colors.blue_theme_dark_surfaceTint
31 | import com.example.learning3.ui.theme.colors.blue_theme_dark_surfaceVariant
32 | import com.example.learning3.ui.theme.colors.blue_theme_dark_tertiary
33 | import com.example.learning3.ui.theme.colors.blue_theme_dark_tertiaryContainer
34 | import com.example.learning3.ui.theme.colors.blue_theme_light_background
35 | import com.example.learning3.ui.theme.colors.blue_theme_light_error
36 | import com.example.learning3.ui.theme.colors.blue_theme_light_errorContainer
37 | import com.example.learning3.ui.theme.colors.blue_theme_light_inverseOnSurface
38 | import com.example.learning3.ui.theme.colors.blue_theme_light_inversePrimary
39 | import com.example.learning3.ui.theme.colors.blue_theme_light_inverseSurface
40 | import com.example.learning3.ui.theme.colors.blue_theme_light_onBackground
41 | import com.example.learning3.ui.theme.colors.blue_theme_light_onError
42 | import com.example.learning3.ui.theme.colors.blue_theme_light_onErrorContainer
43 | import com.example.learning3.ui.theme.colors.blue_theme_light_onPrimary
44 | import com.example.learning3.ui.theme.colors.blue_theme_light_onPrimaryContainer
45 | import com.example.learning3.ui.theme.colors.blue_theme_light_onSecondary
46 | import com.example.learning3.ui.theme.colors.blue_theme_light_onSecondaryContainer
47 | import com.example.learning3.ui.theme.colors.blue_theme_light_onSurface
48 | import com.example.learning3.ui.theme.colors.blue_theme_light_onSurfaceVariant
49 | import com.example.learning3.ui.theme.colors.blue_theme_light_onTertiary
50 | import com.example.learning3.ui.theme.colors.blue_theme_light_onTertiaryContainer
51 | import com.example.learning3.ui.theme.colors.blue_theme_light_outline
52 | import com.example.learning3.ui.theme.colors.blue_theme_light_outlineVariant
53 | import com.example.learning3.ui.theme.colors.blue_theme_light_primary
54 | import com.example.learning3.ui.theme.colors.blue_theme_light_primaryContainer
55 | import com.example.learning3.ui.theme.colors.blue_theme_light_scrim
56 | import com.example.learning3.ui.theme.colors.blue_theme_light_secondary
57 | import com.example.learning3.ui.theme.colors.blue_theme_light_secondaryContainer
58 | import com.example.learning3.ui.theme.colors.blue_theme_light_surface
59 | import com.example.learning3.ui.theme.colors.blue_theme_light_surfaceTint
60 | import com.example.learning3.ui.theme.colors.blue_theme_light_surfaceVariant
61 | import com.example.learning3.ui.theme.colors.blue_theme_light_tertiary
62 | import com.example.learning3.ui.theme.colors.blue_theme_light_tertiaryContainer
63 |
64 | public val BlueLightColors = lightColorScheme(
65 | primary = blue_theme_light_primary,
66 | onPrimary = blue_theme_light_onPrimary,
67 | primaryContainer = blue_theme_light_primaryContainer,
68 | onPrimaryContainer = blue_theme_light_onPrimaryContainer,
69 | secondary = blue_theme_light_secondary,
70 | onSecondary = blue_theme_light_onSecondary,
71 | secondaryContainer = blue_theme_light_secondaryContainer,
72 | onSecondaryContainer = blue_theme_light_onSecondaryContainer,
73 | tertiary = blue_theme_light_tertiary,
74 | onTertiary = blue_theme_light_onTertiary,
75 | tertiaryContainer = blue_theme_light_tertiaryContainer,
76 | onTertiaryContainer = blue_theme_light_onTertiaryContainer,
77 | error = blue_theme_light_error,
78 | errorContainer = blue_theme_light_errorContainer,
79 | onError = blue_theme_light_onError,
80 | onErrorContainer = blue_theme_light_onErrorContainer,
81 | background = blue_theme_light_background,
82 | onBackground = blue_theme_light_onBackground,
83 | surface = blue_theme_light_surface,
84 | onSurface = blue_theme_light_onSurface,
85 | surfaceVariant = blue_theme_light_surfaceVariant,
86 | onSurfaceVariant = blue_theme_light_onSurfaceVariant,
87 | outline = blue_theme_light_outline,
88 | inverseOnSurface = blue_theme_light_inverseOnSurface,
89 | inverseSurface = blue_theme_light_inverseSurface,
90 | inversePrimary = blue_theme_light_inversePrimary,
91 | surfaceTint = blue_theme_light_surfaceTint,
92 | outlineVariant = blue_theme_light_outlineVariant,
93 | scrim = blue_theme_light_scrim,
94 | )
95 |
96 |
97 | public val BlueDarkColors = darkColorScheme(
98 | primary = blue_theme_dark_primary,
99 | onPrimary = blue_theme_dark_onPrimary,
100 | primaryContainer = blue_theme_dark_primaryContainer,
101 | onPrimaryContainer = blue_theme_dark_onPrimaryContainer,
102 | secondary = blue_theme_dark_secondary,
103 | onSecondary = blue_theme_dark_onSecondary,
104 | secondaryContainer = blue_theme_dark_secondaryContainer,
105 | onSecondaryContainer = blue_theme_dark_onSecondaryContainer,
106 | tertiary = blue_theme_dark_tertiary,
107 | onTertiary = blue_theme_dark_onTertiary,
108 | tertiaryContainer = blue_theme_dark_tertiaryContainer,
109 | onTertiaryContainer = blue_theme_dark_onTertiaryContainer,
110 | error = blue_theme_dark_error,
111 | errorContainer = blue_theme_dark_errorContainer,
112 | onError = blue_theme_dark_onError,
113 | onErrorContainer = blue_theme_dark_onErrorContainer,
114 | background = blue_theme_dark_background,
115 | onBackground = blue_theme_dark_onBackground,
116 | surface = blue_theme_dark_surface,
117 | onSurface = blue_theme_dark_onSurface,
118 | surfaceVariant = blue_theme_dark_surfaceVariant,
119 | onSurfaceVariant = blue_theme_dark_onSurfaceVariant,
120 | outline = blue_theme_dark_outline,
121 | inverseOnSurface = blue_theme_dark_inverseOnSurface,
122 | inverseSurface = blue_theme_dark_inverseSurface,
123 | inversePrimary = blue_theme_dark_inversePrimary,
124 | surfaceTint = blue_theme_dark_surfaceTint,
125 | outlineVariant = blue_theme_dark_outlineVariant,
126 | scrim = blue_theme_dark_scrim,
127 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/themes/BrownTheme.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.themes
2 |
3 | import androidx.compose.material3.darkColorScheme
4 | import androidx.compose.material3.lightColorScheme
5 | import com.example.learning3.ui.theme.colors.brown_theme_dark_background
6 | import com.example.learning3.ui.theme.colors.brown_theme_dark_error
7 | import com.example.learning3.ui.theme.colors.brown_theme_dark_errorContainer
8 | import com.example.learning3.ui.theme.colors.brown_theme_dark_inverseOnSurface
9 | import com.example.learning3.ui.theme.colors.brown_theme_dark_inversePrimary
10 | import com.example.learning3.ui.theme.colors.brown_theme_dark_inverseSurface
11 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onBackground
12 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onError
13 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onErrorContainer
14 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onPrimary
15 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onPrimaryContainer
16 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onSecondary
17 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onSecondaryContainer
18 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onSurface
19 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onSurfaceVariant
20 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onTertiary
21 | import com.example.learning3.ui.theme.colors.brown_theme_dark_onTertiaryContainer
22 | import com.example.learning3.ui.theme.colors.brown_theme_dark_outline
23 | import com.example.learning3.ui.theme.colors.brown_theme_dark_outlineVariant
24 | import com.example.learning3.ui.theme.colors.brown_theme_dark_primary
25 | import com.example.learning3.ui.theme.colors.brown_theme_dark_primaryContainer
26 | import com.example.learning3.ui.theme.colors.brown_theme_dark_scrim
27 | import com.example.learning3.ui.theme.colors.brown_theme_dark_secondary
28 | import com.example.learning3.ui.theme.colors.brown_theme_dark_secondaryContainer
29 | import com.example.learning3.ui.theme.colors.brown_theme_dark_surface
30 | import com.example.learning3.ui.theme.colors.brown_theme_dark_surfaceTint
31 | import com.example.learning3.ui.theme.colors.brown_theme_dark_surfaceVariant
32 | import com.example.learning3.ui.theme.colors.brown_theme_dark_tertiary
33 | import com.example.learning3.ui.theme.colors.brown_theme_dark_tertiaryContainer
34 | import com.example.learning3.ui.theme.colors.brown_theme_light_background
35 | import com.example.learning3.ui.theme.colors.brown_theme_light_error
36 | import com.example.learning3.ui.theme.colors.brown_theme_light_errorContainer
37 | import com.example.learning3.ui.theme.colors.brown_theme_light_inverseOnSurface
38 | import com.example.learning3.ui.theme.colors.brown_theme_light_inversePrimary
39 | import com.example.learning3.ui.theme.colors.brown_theme_light_inverseSurface
40 | import com.example.learning3.ui.theme.colors.brown_theme_light_onBackground
41 | import com.example.learning3.ui.theme.colors.brown_theme_light_onError
42 | import com.example.learning3.ui.theme.colors.brown_theme_light_onErrorContainer
43 | import com.example.learning3.ui.theme.colors.brown_theme_light_onPrimary
44 | import com.example.learning3.ui.theme.colors.brown_theme_light_onPrimaryContainer
45 | import com.example.learning3.ui.theme.colors.brown_theme_light_onSecondary
46 | import com.example.learning3.ui.theme.colors.brown_theme_light_onSecondaryContainer
47 | import com.example.learning3.ui.theme.colors.brown_theme_light_onSurface
48 | import com.example.learning3.ui.theme.colors.brown_theme_light_onSurfaceVariant
49 | import com.example.learning3.ui.theme.colors.brown_theme_light_onTertiary
50 | import com.example.learning3.ui.theme.colors.brown_theme_light_onTertiaryContainer
51 | import com.example.learning3.ui.theme.colors.brown_theme_light_outline
52 | import com.example.learning3.ui.theme.colors.brown_theme_light_outlineVariant
53 | import com.example.learning3.ui.theme.colors.brown_theme_light_primary
54 | import com.example.learning3.ui.theme.colors.brown_theme_light_primaryContainer
55 | import com.example.learning3.ui.theme.colors.brown_theme_light_scrim
56 | import com.example.learning3.ui.theme.colors.brown_theme_light_secondary
57 | import com.example.learning3.ui.theme.colors.brown_theme_light_secondaryContainer
58 | import com.example.learning3.ui.theme.colors.brown_theme_light_surface
59 | import com.example.learning3.ui.theme.colors.brown_theme_light_surfaceTint
60 | import com.example.learning3.ui.theme.colors.brown_theme_light_surfaceVariant
61 | import com.example.learning3.ui.theme.colors.brown_theme_light_tertiary
62 | import com.example.learning3.ui.theme.colors.brown_theme_light_tertiaryContainer
63 |
64 | public val BrownLightColors = lightColorScheme(
65 | primary = brown_theme_light_primary,
66 | onPrimary = brown_theme_light_onPrimary,
67 | primaryContainer = brown_theme_light_primaryContainer,
68 | onPrimaryContainer = brown_theme_light_onPrimaryContainer,
69 | secondary = brown_theme_light_secondary,
70 | onSecondary = brown_theme_light_onSecondary,
71 | secondaryContainer = brown_theme_light_secondaryContainer,
72 | onSecondaryContainer = brown_theme_light_onSecondaryContainer,
73 | tertiary = brown_theme_light_tertiary,
74 | onTertiary = brown_theme_light_onTertiary,
75 | tertiaryContainer = brown_theme_light_tertiaryContainer,
76 | onTertiaryContainer = brown_theme_light_onTertiaryContainer,
77 | error = brown_theme_light_error,
78 | errorContainer = brown_theme_light_errorContainer,
79 | onError = brown_theme_light_onError,
80 | onErrorContainer = brown_theme_light_onErrorContainer,
81 | background = brown_theme_light_background,
82 | onBackground = brown_theme_light_onBackground,
83 | surface = brown_theme_light_surface,
84 | onSurface = brown_theme_light_onSurface,
85 | surfaceVariant = brown_theme_light_surfaceVariant,
86 | onSurfaceVariant = brown_theme_light_onSurfaceVariant,
87 | outline = brown_theme_light_outline,
88 | inverseOnSurface = brown_theme_light_inverseOnSurface,
89 | inverseSurface = brown_theme_light_inverseSurface,
90 | inversePrimary = brown_theme_light_inversePrimary,
91 | surfaceTint = brown_theme_light_surfaceTint,
92 | outlineVariant = brown_theme_light_outlineVariant,
93 | scrim = brown_theme_light_scrim,
94 | )
95 |
96 |
97 | public val BrownDarkColors = darkColorScheme(
98 | primary = brown_theme_dark_primary,
99 | onPrimary = brown_theme_dark_onPrimary,
100 | primaryContainer = brown_theme_dark_primaryContainer,
101 | onPrimaryContainer = brown_theme_dark_onPrimaryContainer,
102 | secondary = brown_theme_dark_secondary,
103 | onSecondary = brown_theme_dark_onSecondary,
104 | secondaryContainer = brown_theme_dark_secondaryContainer,
105 | onSecondaryContainer = brown_theme_dark_onSecondaryContainer,
106 | tertiary = brown_theme_dark_tertiary,
107 | onTertiary = brown_theme_dark_onTertiary,
108 | tertiaryContainer = brown_theme_dark_tertiaryContainer,
109 | onTertiaryContainer = brown_theme_dark_onTertiaryContainer,
110 | error = brown_theme_dark_error,
111 | errorContainer = brown_theme_dark_errorContainer,
112 | onError = brown_theme_dark_onError,
113 | onErrorContainer = brown_theme_dark_onErrorContainer,
114 | background = brown_theme_dark_background,
115 | onBackground = brown_theme_dark_onBackground,
116 | surface = brown_theme_dark_surface,
117 | onSurface = brown_theme_dark_onSurface,
118 | surfaceVariant = brown_theme_dark_surfaceVariant,
119 | onSurfaceVariant = brown_theme_dark_onSurfaceVariant,
120 | outline = brown_theme_dark_outline,
121 | inverseOnSurface = brown_theme_dark_inverseOnSurface,
122 | inverseSurface = brown_theme_dark_inverseSurface,
123 | inversePrimary = brown_theme_dark_inversePrimary,
124 | surfaceTint = brown_theme_dark_surfaceTint,
125 | outlineVariant = brown_theme_dark_outlineVariant,
126 | scrim = brown_theme_dark_scrim,
127 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/themes/GreenTheme.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.themes
2 |
3 | import androidx.compose.material3.darkColorScheme
4 | import androidx.compose.material3.lightColorScheme
5 | import com.example.learning3.ui.theme.colors.green_theme_dark_background
6 | import com.example.learning3.ui.theme.colors.green_theme_dark_error
7 | import com.example.learning3.ui.theme.colors.green_theme_dark_errorContainer
8 | import com.example.learning3.ui.theme.colors.green_theme_dark_inverseOnSurface
9 | import com.example.learning3.ui.theme.colors.green_theme_dark_inversePrimary
10 | import com.example.learning3.ui.theme.colors.green_theme_dark_inverseSurface
11 | import com.example.learning3.ui.theme.colors.green_theme_dark_onBackground
12 | import com.example.learning3.ui.theme.colors.green_theme_dark_onError
13 | import com.example.learning3.ui.theme.colors.green_theme_dark_onErrorContainer
14 | import com.example.learning3.ui.theme.colors.green_theme_dark_onPrimary
15 | import com.example.learning3.ui.theme.colors.green_theme_dark_onPrimaryContainer
16 | import com.example.learning3.ui.theme.colors.green_theme_dark_onSecondary
17 | import com.example.learning3.ui.theme.colors.green_theme_dark_onSecondaryContainer
18 | import com.example.learning3.ui.theme.colors.green_theme_dark_onSurface
19 | import com.example.learning3.ui.theme.colors.green_theme_dark_onSurfaceVariant
20 | import com.example.learning3.ui.theme.colors.green_theme_dark_onTertiary
21 | import com.example.learning3.ui.theme.colors.green_theme_dark_onTertiaryContainer
22 | import com.example.learning3.ui.theme.colors.green_theme_dark_outline
23 | import com.example.learning3.ui.theme.colors.green_theme_dark_outlineVariant
24 | import com.example.learning3.ui.theme.colors.green_theme_dark_primary
25 | import com.example.learning3.ui.theme.colors.green_theme_dark_primaryContainer
26 | import com.example.learning3.ui.theme.colors.green_theme_dark_scrim
27 | import com.example.learning3.ui.theme.colors.green_theme_dark_secondary
28 | import com.example.learning3.ui.theme.colors.green_theme_dark_secondaryContainer
29 | import com.example.learning3.ui.theme.colors.green_theme_dark_surface
30 | import com.example.learning3.ui.theme.colors.green_theme_dark_surfaceTint
31 | import com.example.learning3.ui.theme.colors.green_theme_dark_surfaceVariant
32 | import com.example.learning3.ui.theme.colors.green_theme_dark_tertiary
33 | import com.example.learning3.ui.theme.colors.green_theme_dark_tertiaryContainer
34 | import com.example.learning3.ui.theme.colors.green_theme_light_background
35 | import com.example.learning3.ui.theme.colors.green_theme_light_error
36 | import com.example.learning3.ui.theme.colors.green_theme_light_errorContainer
37 | import com.example.learning3.ui.theme.colors.green_theme_light_inverseOnSurface
38 | import com.example.learning3.ui.theme.colors.green_theme_light_inversePrimary
39 | import com.example.learning3.ui.theme.colors.green_theme_light_inverseSurface
40 | import com.example.learning3.ui.theme.colors.green_theme_light_onBackground
41 | import com.example.learning3.ui.theme.colors.green_theme_light_onError
42 | import com.example.learning3.ui.theme.colors.green_theme_light_onErrorContainer
43 | import com.example.learning3.ui.theme.colors.green_theme_light_onPrimary
44 | import com.example.learning3.ui.theme.colors.green_theme_light_onPrimaryContainer
45 | import com.example.learning3.ui.theme.colors.green_theme_light_onSecondary
46 | import com.example.learning3.ui.theme.colors.green_theme_light_onSecondaryContainer
47 | import com.example.learning3.ui.theme.colors.green_theme_light_onSurface
48 | import com.example.learning3.ui.theme.colors.green_theme_light_onSurfaceVariant
49 | import com.example.learning3.ui.theme.colors.green_theme_light_onTertiary
50 | import com.example.learning3.ui.theme.colors.green_theme_light_onTertiaryContainer
51 | import com.example.learning3.ui.theme.colors.green_theme_light_outline
52 | import com.example.learning3.ui.theme.colors.green_theme_light_outlineVariant
53 | import com.example.learning3.ui.theme.colors.green_theme_light_primary
54 | import com.example.learning3.ui.theme.colors.green_theme_light_primaryContainer
55 | import com.example.learning3.ui.theme.colors.green_theme_light_scrim
56 | import com.example.learning3.ui.theme.colors.green_theme_light_secondary
57 | import com.example.learning3.ui.theme.colors.green_theme_light_secondaryContainer
58 | import com.example.learning3.ui.theme.colors.green_theme_light_surface
59 | import com.example.learning3.ui.theme.colors.green_theme_light_surfaceTint
60 | import com.example.learning3.ui.theme.colors.green_theme_light_surfaceVariant
61 | import com.example.learning3.ui.theme.colors.green_theme_light_tertiary
62 | import com.example.learning3.ui.theme.colors.green_theme_light_tertiaryContainer
63 |
64 | public val GreenLightColors = lightColorScheme(
65 | primary = green_theme_light_primary,
66 | onPrimary = green_theme_light_onPrimary,
67 | primaryContainer = green_theme_light_primaryContainer,
68 | onPrimaryContainer = green_theme_light_onPrimaryContainer,
69 | secondary = green_theme_light_secondary,
70 | onSecondary = green_theme_light_onSecondary,
71 | secondaryContainer = green_theme_light_secondaryContainer,
72 | onSecondaryContainer = green_theme_light_onSecondaryContainer,
73 | tertiary = green_theme_light_tertiary,
74 | onTertiary = green_theme_light_onTertiary,
75 | tertiaryContainer = green_theme_light_tertiaryContainer,
76 | onTertiaryContainer = green_theme_light_onTertiaryContainer,
77 | error = green_theme_light_error,
78 | errorContainer = green_theme_light_errorContainer,
79 | onError = green_theme_light_onError,
80 | onErrorContainer = green_theme_light_onErrorContainer,
81 | background = green_theme_light_background,
82 | onBackground = green_theme_light_onBackground,
83 | surface = green_theme_light_surface,
84 | onSurface = green_theme_light_onSurface,
85 | surfaceVariant = green_theme_light_surfaceVariant,
86 | onSurfaceVariant = green_theme_light_onSurfaceVariant,
87 | outline = green_theme_light_outline,
88 | inverseOnSurface = green_theme_light_inverseOnSurface,
89 | inverseSurface = green_theme_light_inverseSurface,
90 | inversePrimary = green_theme_light_inversePrimary,
91 | surfaceTint = green_theme_light_surfaceTint,
92 | outlineVariant = green_theme_light_outlineVariant,
93 | scrim = green_theme_light_scrim,
94 | )
95 |
96 |
97 | public val GreenDarkColors = darkColorScheme(
98 | primary = green_theme_dark_primary,
99 | onPrimary = green_theme_dark_onPrimary,
100 | primaryContainer = green_theme_dark_primaryContainer,
101 | onPrimaryContainer = green_theme_dark_onPrimaryContainer,
102 | secondary = green_theme_dark_secondary,
103 | onSecondary = green_theme_dark_onSecondary,
104 | secondaryContainer = green_theme_dark_secondaryContainer,
105 | onSecondaryContainer = green_theme_dark_onSecondaryContainer,
106 | tertiary = green_theme_dark_tertiary,
107 | onTertiary = green_theme_dark_onTertiary,
108 | tertiaryContainer = green_theme_dark_tertiaryContainer,
109 | onTertiaryContainer = green_theme_dark_onTertiaryContainer,
110 | error = green_theme_dark_error,
111 | errorContainer = green_theme_dark_errorContainer,
112 | onError = green_theme_dark_onError,
113 | onErrorContainer = green_theme_dark_onErrorContainer,
114 | background = green_theme_dark_background,
115 | onBackground = green_theme_dark_onBackground,
116 | surface = green_theme_dark_surface,
117 | onSurface = green_theme_dark_onSurface,
118 | surfaceVariant = green_theme_dark_surfaceVariant,
119 | onSurfaceVariant = green_theme_dark_onSurfaceVariant,
120 | outline = green_theme_dark_outline,
121 | inverseOnSurface = green_theme_dark_inverseOnSurface,
122 | inverseSurface = green_theme_dark_inverseSurface,
123 | inversePrimary = green_theme_dark_inversePrimary,
124 | surfaceTint = green_theme_dark_surfaceTint,
125 | outlineVariant = green_theme_dark_outlineVariant,
126 | scrim = green_theme_dark_scrim,
127 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/themes/PinkTheme.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.themes
2 |
3 | import androidx.compose.material3.darkColorScheme
4 | import androidx.compose.material3.lightColorScheme
5 | import com.example.learning3.ui.theme.colors.pink_theme_dark_background
6 | import com.example.learning3.ui.theme.colors.pink_theme_dark_error
7 | import com.example.learning3.ui.theme.colors.pink_theme_dark_errorContainer
8 | import com.example.learning3.ui.theme.colors.pink_theme_dark_inverseOnSurface
9 | import com.example.learning3.ui.theme.colors.pink_theme_dark_inversePrimary
10 | import com.example.learning3.ui.theme.colors.pink_theme_dark_inverseSurface
11 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onBackground
12 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onError
13 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onErrorContainer
14 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onPrimary
15 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onPrimaryContainer
16 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onSecondary
17 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onSecondaryContainer
18 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onSurface
19 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onSurfaceVariant
20 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onTertiary
21 | import com.example.learning3.ui.theme.colors.pink_theme_dark_onTertiaryContainer
22 | import com.example.learning3.ui.theme.colors.pink_theme_dark_outline
23 | import com.example.learning3.ui.theme.colors.pink_theme_dark_outlineVariant
24 | import com.example.learning3.ui.theme.colors.pink_theme_dark_primary
25 | import com.example.learning3.ui.theme.colors.pink_theme_dark_primaryContainer
26 | import com.example.learning3.ui.theme.colors.pink_theme_dark_scrim
27 | import com.example.learning3.ui.theme.colors.pink_theme_dark_secondary
28 | import com.example.learning3.ui.theme.colors.pink_theme_dark_secondaryContainer
29 | import com.example.learning3.ui.theme.colors.pink_theme_dark_surface
30 | import com.example.learning3.ui.theme.colors.pink_theme_dark_surfaceTint
31 | import com.example.learning3.ui.theme.colors.pink_theme_dark_surfaceVariant
32 | import com.example.learning3.ui.theme.colors.pink_theme_dark_tertiary
33 | import com.example.learning3.ui.theme.colors.pink_theme_dark_tertiaryContainer
34 | import com.example.learning3.ui.theme.colors.pink_theme_light_background
35 | import com.example.learning3.ui.theme.colors.pink_theme_light_error
36 | import com.example.learning3.ui.theme.colors.pink_theme_light_errorContainer
37 | import com.example.learning3.ui.theme.colors.pink_theme_light_inverseOnSurface
38 | import com.example.learning3.ui.theme.colors.pink_theme_light_inversePrimary
39 | import com.example.learning3.ui.theme.colors.pink_theme_light_inverseSurface
40 | import com.example.learning3.ui.theme.colors.pink_theme_light_onBackground
41 | import com.example.learning3.ui.theme.colors.pink_theme_light_onError
42 | import com.example.learning3.ui.theme.colors.pink_theme_light_onErrorContainer
43 | import com.example.learning3.ui.theme.colors.pink_theme_light_onPrimary
44 | import com.example.learning3.ui.theme.colors.pink_theme_light_onPrimaryContainer
45 | import com.example.learning3.ui.theme.colors.pink_theme_light_onSecondary
46 | import com.example.learning3.ui.theme.colors.pink_theme_light_onSecondaryContainer
47 | import com.example.learning3.ui.theme.colors.pink_theme_light_onSurface
48 | import com.example.learning3.ui.theme.colors.pink_theme_light_onSurfaceVariant
49 | import com.example.learning3.ui.theme.colors.pink_theme_light_onTertiary
50 | import com.example.learning3.ui.theme.colors.pink_theme_light_onTertiaryContainer
51 | import com.example.learning3.ui.theme.colors.pink_theme_light_outline
52 | import com.example.learning3.ui.theme.colors.pink_theme_light_outlineVariant
53 | import com.example.learning3.ui.theme.colors.pink_theme_light_primary
54 | import com.example.learning3.ui.theme.colors.pink_theme_light_primaryContainer
55 | import com.example.learning3.ui.theme.colors.pink_theme_light_scrim
56 | import com.example.learning3.ui.theme.colors.pink_theme_light_secondary
57 | import com.example.learning3.ui.theme.colors.pink_theme_light_secondaryContainer
58 | import com.example.learning3.ui.theme.colors.pink_theme_light_surface
59 | import com.example.learning3.ui.theme.colors.pink_theme_light_surfaceTint
60 | import com.example.learning3.ui.theme.colors.pink_theme_light_surfaceVariant
61 | import com.example.learning3.ui.theme.colors.pink_theme_light_tertiary
62 | import com.example.learning3.ui.theme.colors.pink_theme_light_tertiaryContainer
63 |
64 | public val PinkLightColors = lightColorScheme(
65 | primary = pink_theme_light_primary,
66 | onPrimary = pink_theme_light_onPrimary,
67 | primaryContainer = pink_theme_light_primaryContainer,
68 | onPrimaryContainer = pink_theme_light_onPrimaryContainer,
69 | secondary = pink_theme_light_secondary,
70 | onSecondary = pink_theme_light_onSecondary,
71 | secondaryContainer = pink_theme_light_secondaryContainer,
72 | onSecondaryContainer = pink_theme_light_onSecondaryContainer,
73 | tertiary = pink_theme_light_tertiary,
74 | onTertiary = pink_theme_light_onTertiary,
75 | tertiaryContainer = pink_theme_light_tertiaryContainer,
76 | onTertiaryContainer = pink_theme_light_onTertiaryContainer,
77 | error = pink_theme_light_error,
78 | errorContainer = pink_theme_light_errorContainer,
79 | onError = pink_theme_light_onError,
80 | onErrorContainer = pink_theme_light_onErrorContainer,
81 | background = pink_theme_light_background,
82 | onBackground = pink_theme_light_onBackground,
83 | surface = pink_theme_light_surface,
84 | onSurface = pink_theme_light_onSurface,
85 | surfaceVariant = pink_theme_light_surfaceVariant,
86 | onSurfaceVariant = pink_theme_light_onSurfaceVariant,
87 | outline = pink_theme_light_outline,
88 | inverseOnSurface = pink_theme_light_inverseOnSurface,
89 | inverseSurface = pink_theme_light_inverseSurface,
90 | inversePrimary = pink_theme_light_inversePrimary,
91 | surfaceTint = pink_theme_light_surfaceTint,
92 | outlineVariant = pink_theme_light_outlineVariant,
93 | scrim = pink_theme_light_scrim,
94 | )
95 |
96 |
97 | public val PinkDarkColors = darkColorScheme(
98 | primary = pink_theme_dark_primary,
99 | onPrimary = pink_theme_dark_onPrimary,
100 | primaryContainer = pink_theme_dark_primaryContainer,
101 | onPrimaryContainer = pink_theme_dark_onPrimaryContainer,
102 | secondary = pink_theme_dark_secondary,
103 | onSecondary = pink_theme_dark_onSecondary,
104 | secondaryContainer = pink_theme_dark_secondaryContainer,
105 | onSecondaryContainer = pink_theme_dark_onSecondaryContainer,
106 | tertiary = pink_theme_dark_tertiary,
107 | onTertiary = pink_theme_dark_onTertiary,
108 | tertiaryContainer = pink_theme_dark_tertiaryContainer,
109 | onTertiaryContainer = pink_theme_dark_onTertiaryContainer,
110 | error = pink_theme_dark_error,
111 | errorContainer = pink_theme_dark_errorContainer,
112 | onError = pink_theme_dark_onError,
113 | onErrorContainer = pink_theme_dark_onErrorContainer,
114 | background = pink_theme_dark_background,
115 | onBackground = pink_theme_dark_onBackground,
116 | surface = pink_theme_dark_surface,
117 | onSurface = pink_theme_dark_onSurface,
118 | surfaceVariant = pink_theme_dark_surfaceVariant,
119 | onSurfaceVariant = pink_theme_dark_onSurfaceVariant,
120 | outline = pink_theme_dark_outline,
121 | inverseOnSurface = pink_theme_dark_inverseOnSurface,
122 | inverseSurface = pink_theme_dark_inverseSurface,
123 | inversePrimary = pink_theme_dark_inversePrimary,
124 | surfaceTint = pink_theme_dark_surfaceTint,
125 | outlineVariant = pink_theme_dark_outlineVariant,
126 | scrim = pink_theme_dark_scrim,
127 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/ui/theme/themes/PurpleTheme.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.ui.theme.themes
2 |
3 | import androidx.compose.material3.darkColorScheme
4 | import androidx.compose.material3.lightColorScheme
5 | import com.example.learning3.ui.theme.colors.purple_theme_dark_background
6 | import com.example.learning3.ui.theme.colors.purple_theme_dark_error
7 | import com.example.learning3.ui.theme.colors.purple_theme_dark_errorContainer
8 | import com.example.learning3.ui.theme.colors.purple_theme_dark_inverseOnSurface
9 | import com.example.learning3.ui.theme.colors.purple_theme_dark_inversePrimary
10 | import com.example.learning3.ui.theme.colors.purple_theme_dark_inverseSurface
11 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onBackground
12 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onError
13 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onErrorContainer
14 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onPrimary
15 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onPrimaryContainer
16 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onSecondary
17 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onSecondaryContainer
18 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onSurface
19 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onSurfaceVariant
20 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onTertiary
21 | import com.example.learning3.ui.theme.colors.purple_theme_dark_onTertiaryContainer
22 | import com.example.learning3.ui.theme.colors.purple_theme_dark_outline
23 | import com.example.learning3.ui.theme.colors.purple_theme_dark_outlineVariant
24 | import com.example.learning3.ui.theme.colors.purple_theme_dark_primary
25 | import com.example.learning3.ui.theme.colors.purple_theme_dark_primaryContainer
26 | import com.example.learning3.ui.theme.colors.purple_theme_dark_scrim
27 | import com.example.learning3.ui.theme.colors.purple_theme_dark_secondary
28 | import com.example.learning3.ui.theme.colors.purple_theme_dark_secondaryContainer
29 | import com.example.learning3.ui.theme.colors.purple_theme_dark_surface
30 | import com.example.learning3.ui.theme.colors.purple_theme_dark_surfaceTint
31 | import com.example.learning3.ui.theme.colors.purple_theme_dark_surfaceVariant
32 | import com.example.learning3.ui.theme.colors.purple_theme_dark_tertiary
33 | import com.example.learning3.ui.theme.colors.purple_theme_dark_tertiaryContainer
34 | import com.example.learning3.ui.theme.colors.purple_theme_light_background
35 | import com.example.learning3.ui.theme.colors.purple_theme_light_error
36 | import com.example.learning3.ui.theme.colors.purple_theme_light_errorContainer
37 | import com.example.learning3.ui.theme.colors.purple_theme_light_inverseOnSurface
38 | import com.example.learning3.ui.theme.colors.purple_theme_light_inversePrimary
39 | import com.example.learning3.ui.theme.colors.purple_theme_light_inverseSurface
40 | import com.example.learning3.ui.theme.colors.purple_theme_light_onBackground
41 | import com.example.learning3.ui.theme.colors.purple_theme_light_onError
42 | import com.example.learning3.ui.theme.colors.purple_theme_light_onErrorContainer
43 | import com.example.learning3.ui.theme.colors.purple_theme_light_onPrimary
44 | import com.example.learning3.ui.theme.colors.purple_theme_light_onPrimaryContainer
45 | import com.example.learning3.ui.theme.colors.purple_theme_light_onSecondary
46 | import com.example.learning3.ui.theme.colors.purple_theme_light_onSecondaryContainer
47 | import com.example.learning3.ui.theme.colors.purple_theme_light_onSurface
48 | import com.example.learning3.ui.theme.colors.purple_theme_light_onSurfaceVariant
49 | import com.example.learning3.ui.theme.colors.purple_theme_light_onTertiary
50 | import com.example.learning3.ui.theme.colors.purple_theme_light_onTertiaryContainer
51 | import com.example.learning3.ui.theme.colors.purple_theme_light_outline
52 | import com.example.learning3.ui.theme.colors.purple_theme_light_outlineVariant
53 | import com.example.learning3.ui.theme.colors.purple_theme_light_primary
54 | import com.example.learning3.ui.theme.colors.purple_theme_light_primaryContainer
55 | import com.example.learning3.ui.theme.colors.purple_theme_light_scrim
56 | import com.example.learning3.ui.theme.colors.purple_theme_light_secondary
57 | import com.example.learning3.ui.theme.colors.purple_theme_light_secondaryContainer
58 | import com.example.learning3.ui.theme.colors.purple_theme_light_surface
59 | import com.example.learning3.ui.theme.colors.purple_theme_light_surfaceTint
60 | import com.example.learning3.ui.theme.colors.purple_theme_light_surfaceVariant
61 | import com.example.learning3.ui.theme.colors.purple_theme_light_tertiary
62 | import com.example.learning3.ui.theme.colors.purple_theme_light_tertiaryContainer
63 |
64 | public val PurpleLightColors = lightColorScheme(
65 | primary = purple_theme_light_primary,
66 | onPrimary = purple_theme_light_onPrimary,
67 | primaryContainer = purple_theme_light_primaryContainer,
68 | onPrimaryContainer = purple_theme_light_onPrimaryContainer,
69 | secondary = purple_theme_light_secondary,
70 | onSecondary = purple_theme_light_onSecondary,
71 | secondaryContainer = purple_theme_light_secondaryContainer,
72 | onSecondaryContainer = purple_theme_light_onSecondaryContainer,
73 | tertiary = purple_theme_light_tertiary,
74 | onTertiary = purple_theme_light_onTertiary,
75 | tertiaryContainer = purple_theme_light_tertiaryContainer,
76 | onTertiaryContainer = purple_theme_light_onTertiaryContainer,
77 | error = purple_theme_light_error,
78 | errorContainer = purple_theme_light_errorContainer,
79 | onError = purple_theme_light_onError,
80 | onErrorContainer = purple_theme_light_onErrorContainer,
81 | background = purple_theme_light_background,
82 | onBackground = purple_theme_light_onBackground,
83 | surface = purple_theme_light_surface,
84 | onSurface = purple_theme_light_onSurface,
85 | surfaceVariant = purple_theme_light_surfaceVariant,
86 | onSurfaceVariant = purple_theme_light_onSurfaceVariant,
87 | outline = purple_theme_light_outline,
88 | inverseOnSurface = purple_theme_light_inverseOnSurface,
89 | inverseSurface = purple_theme_light_inverseSurface,
90 | inversePrimary = purple_theme_light_inversePrimary,
91 | surfaceTint = purple_theme_light_surfaceTint,
92 | outlineVariant = purple_theme_light_outlineVariant,
93 | scrim = purple_theme_light_scrim,
94 | )
95 |
96 |
97 | public val PurpleDarkColors = darkColorScheme(
98 | primary = purple_theme_dark_primary,
99 | onPrimary = purple_theme_dark_onPrimary,
100 | primaryContainer = purple_theme_dark_primaryContainer,
101 | onPrimaryContainer = purple_theme_dark_onPrimaryContainer,
102 | secondary = purple_theme_dark_secondary,
103 | onSecondary = purple_theme_dark_onSecondary,
104 | secondaryContainer = purple_theme_dark_secondaryContainer,
105 | onSecondaryContainer = purple_theme_dark_onSecondaryContainer,
106 | tertiary = purple_theme_dark_tertiary,
107 | onTertiary = purple_theme_dark_onTertiary,
108 | tertiaryContainer = purple_theme_dark_tertiaryContainer,
109 | onTertiaryContainer = purple_theme_dark_onTertiaryContainer,
110 | error = purple_theme_dark_error,
111 | errorContainer = purple_theme_dark_errorContainer,
112 | onError = purple_theme_dark_onError,
113 | onErrorContainer = purple_theme_dark_onErrorContainer,
114 | background = purple_theme_dark_background,
115 | onBackground = purple_theme_dark_onBackground,
116 | surface = purple_theme_dark_surface,
117 | onSurface = purple_theme_dark_onSurface,
118 | surfaceVariant = purple_theme_dark_surfaceVariant,
119 | onSurfaceVariant = purple_theme_dark_onSurfaceVariant,
120 | outline = purple_theme_dark_outline,
121 | inverseOnSurface = purple_theme_dark_inverseOnSurface,
122 | inverseSurface = purple_theme_dark_inverseSurface,
123 | inversePrimary = purple_theme_dark_inversePrimary,
124 | surfaceTint = purple_theme_dark_surfaceTint,
125 | outlineVariant = purple_theme_dark_outlineVariant,
126 | scrim = purple_theme_dark_scrim,
127 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/utilities/UtilityFunctions.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.utilities
2 |
3 | import android.os.Build
4 | import androidx.annotation.RequiresApi
5 | import androidx.compose.animation.core.Easing
6 | import androidx.compose.animation.core.FastOutSlowInEasing
7 | import androidx.compose.animation.core.FiniteAnimationSpec
8 | import androidx.compose.animation.core.LinearOutSlowInEasing
9 | import androidx.compose.animation.core.MutableTransitionState
10 | import androidx.compose.animation.core.animateFloat
11 | import androidx.compose.animation.core.updateTransition
12 | import androidx.compose.foundation.ExperimentalFoundationApi
13 | import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState
14 | import androidx.compose.runtime.Composable
15 | import androidx.compose.runtime.derivedStateOf
16 | import androidx.compose.runtime.getValue
17 | import androidx.compose.runtime.remember
18 | import java.time.Instant
19 | import java.time.LocalDateTime
20 | import java.time.ZoneId
21 | import java.time.format.DateTimeFormatter
22 | import java.util.Locale
23 |
24 | object UtilityFunctions {
25 | @RequiresApi(Build.VERSION_CODES.O)
26 | fun formatDateAndTime(lastModified: Long): String {
27 | val instant = Instant.ofEpochMilli(lastModified)
28 | val localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())
29 | val dateFormatter = DateTimeFormatter.ofPattern("MMM dd", Locale.getDefault())
30 | return dateFormatter.format(localDateTime)
31 | }
32 |
33 | @OptIn(ExperimentalFoundationApi::class)
34 | @Composable
35 | fun LazyStaggeredGridState.calculateDelayAndEasing(index: Int, columnCount: Int): Pair {
36 | val row = index / columnCount
37 | val column = index % columnCount
38 | val firstVisibleRow = remember { derivedStateOf { firstVisibleItemIndex } }
39 | val visibleRows = layoutInfo.visibleItemsInfo.count()
40 | val scrollingToBottom = firstVisibleRow.value < row
41 | val isFirstLoad = visibleRows == 0
42 | val rowDelay = 200 * when {
43 | isFirstLoad -> row
44 | scrollingToBottom -> 1
45 | else -> 1 // scrolling to top
46 | }
47 | val scrollDirectionMultiplier = if (scrollingToBottom || isFirstLoad) 1 else -1
48 | val columnDelay = column * 150 * scrollDirectionMultiplier
49 | val easing = if (scrollingToBottom || isFirstLoad)
50 | LinearOutSlowInEasing else FastOutSlowInEasing
51 | return rowDelay + columnDelay to easing
52 | }
53 |
54 | private enum class State { PLACING, PLACED }
55 |
56 | data class ScaleAndAlphaArgs(
57 | val fromScale: Float,
58 | val toScale: Float,
59 | val fromAlpha: Float,
60 | val toAlpha: Float
61 | )
62 |
63 | @Composable
64 | fun scaleAndAlpha(
65 | args: ScaleAndAlphaArgs,
66 | animation: FiniteAnimationSpec
67 | ): Pair {
68 | val transitionState =
69 | remember { MutableTransitionState(State.PLACING).apply { targetState = State.PLACED } }
70 | val transition = updateTransition(transitionState, label = "transition")
71 | val alpha by transition.animateFloat(transitionSpec = { animation }, label = "alpha") { state ->
72 | when (state) {
73 | State.PLACING -> args.fromAlpha
74 | State.PLACED -> args.toAlpha
75 | }
76 | }
77 | val scale by transition.animateFloat(transitionSpec = { animation }, label = "scale") { state ->
78 | when (state) {
79 | State.PLACING -> args.fromScale
80 | State.PLACED -> args.toScale
81 | }
82 | }
83 | return alpha to scale
84 | }
85 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/viewmodel/NotesViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.viewmodel
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.viewModelScope
5 | import com.example.learning3.data.Note
6 | import com.example.learning3.data.NoteDao
7 | import com.example.learning3.events.NoteEvent
8 | import com.example.learning3.ui.state.NoteState
9 | import kotlinx.coroutines.Dispatchers
10 | import kotlinx.coroutines.flow.MutableStateFlow
11 | import kotlinx.coroutines.flow.SharingStarted
12 | import kotlinx.coroutines.flow.combine
13 | import kotlinx.coroutines.flow.stateIn
14 | import kotlinx.coroutines.flow.update
15 | import kotlinx.coroutines.launch
16 | import kotlinx.coroutines.withContext
17 |
18 |
19 | class NotesViewModel(private val noteDao: NoteDao) : ViewModel() {
20 |
21 | // private val _notes = noteDao.getNotes()
22 | // .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
23 | private val _notes = noteDao.getNotes().stateIn(
24 | viewModelScope,
25 | SharingStarted.WhileSubscribed(),
26 | emptyList()
27 | )
28 | private val _state = MutableStateFlow(NoteState())
29 |
30 | val state = combine(_state, _notes) { state, notes ->
31 | val sortedNotes = notes.sortedWith(compareByDescending { it.isPinned }.thenBy { it.id })
32 | val filteredNotes = if (state.searchQuery.isBlank()) {
33 | sortedNotes
34 | } else {
35 | sortedNotes.filter { it.doesMatchSearchQuery(state.searchQuery) }
36 | }
37 | state.copy(
38 | notes = filteredNotes
39 | )
40 | }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), NoteState())
41 |
42 |
43 | fun onEvent(event: NoteEvent) {
44 | when(event) {
45 | is NoteEvent.DeleteNote -> {
46 | viewModelScope.launch {
47 | noteDao.deleteNote(event.note)
48 | }
49 | }
50 | is NoteEvent.ClearAllNotes -> {
51 | viewModelScope.launch {
52 | withContext(Dispatchers.IO) {
53 | noteDao.clearAllNotes()
54 | }
55 | }
56 | }
57 | NoteEvent.SaveNote -> {
58 | val title = state.value.title
59 | val content = state.value.content
60 |
61 | if (title.isBlank() || content.isBlank())
62 | return
63 |
64 | if (state.value.editingNote != null) {
65 | val editedNote = Note(
66 | id = state.value.editingNote!!.id,
67 | title = title,
68 | content = content,
69 | lastModified = System.currentTimeMillis()
70 | )
71 | viewModelScope.launch {
72 | noteDao.upsertNote(editedNote)
73 | }
74 | } else {
75 | val note = Note(
76 | title = title,
77 | content = content,
78 | lastModified = System.currentTimeMillis()
79 | )
80 | viewModelScope.launch {
81 | noteDao.upsertNote(note)
82 | }
83 | }
84 | _state.update {
85 | it.copy(
86 | title = "",
87 | content = ""
88 | )
89 | }
90 | }
91 | is NoteEvent.SetContent -> {
92 | _state.update {
93 | it.copy(
94 | content = event.content
95 | )
96 | }
97 | }
98 | is NoteEvent.SetTitle -> {
99 | _state.update {
100 | it.copy(
101 | title = event.title
102 | )
103 | }
104 | }
105 |
106 | is NoteEvent.StartEditing -> {
107 | _state.update {
108 | it.copy(
109 | title = event.note.title,
110 | content = event.note.content,
111 | editingNote = event.note
112 | )
113 | }
114 | }
115 |
116 | is NoteEvent.SetSearchQuery -> {
117 | _state.update {
118 | it.copy(
119 | searchQuery = event.query,
120 | isSearching = event.query.isNotBlank()
121 | )
122 | }
123 | }
124 |
125 | is NoteEvent.EnableIsSelected -> {
126 | val selectedNote = event.note
127 | selectedNote.isSelected = true
128 | viewModelScope.launch {
129 | noteDao.upsertNote(selectedNote)
130 | }
131 | }
132 |
133 | is NoteEvent.DisableIsSelected -> {
134 | val selectedNote = event.note
135 | selectedNote.isSelected = false
136 | viewModelScope.launch {
137 | noteDao.upsertNote(selectedNote)
138 | }
139 | }
140 |
141 | is NoteEvent.PinNote -> {
142 | val toBePinnedNote = event.note
143 | toBePinnedNote.isPinned = true
144 | viewModelScope.launch {
145 | noteDao.upsertNote(toBePinnedNote)
146 | }
147 | }
148 | is NoteEvent.UnpinNote -> {
149 | val toBeUnpinnedNote = event.note
150 | toBeUnpinnedNote.isPinned = false
151 | viewModelScope.launch {
152 | noteDao.upsertNote(toBeUnpinnedNote)
153 | }
154 | }
155 | }
156 | }
157 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/learning3/viewmodel/NotesViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3.viewmodel
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import com.example.learning3.data.NoteDao
6 |
7 | class NotesViewModelFactory(private val noteDao: NoteDao) : ViewModelProvider.Factory {
8 | override fun create(modelClass: Class): T {
9 | if (modelClass.isAssignableFrom(NotesViewModel::class.java)) {
10 | return NotesViewModel(noteDao) as T
11 | }
12 | throw IllegalArgumentException("Unknown ViewModel class")
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_check_circle_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_delete_forever_40.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FAF3F0
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Material3 Notes
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/learning3/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.learning3
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id("com.android.application") version "8.1.0" apply false
4 | id("org.jetbrains.kotlin.android") version "1.8.10" apply false
5 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Jul 27 22:08:14 IST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/images/add_note.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/images/add_note.png
--------------------------------------------------------------------------------
/images/note_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/images/note_search.png
--------------------------------------------------------------------------------
/images/note_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/images/note_view.png
--------------------------------------------------------------------------------
/images/notes_screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/images/notes_screen.png
--------------------------------------------------------------------------------
/images/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KrishnarajaSagar/NotesAppCompose/e1c3b5a59d3c91451210bcf3a5a3b4e9b3859ca6/images/settings.png
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 |
16 | rootProject.name = "Learning3"
17 | include(":app")
18 |
--------------------------------------------------------------------------------