\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 8a758c4..2d40f19 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,10 +3,20 @@
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
index d93f103..ceac91a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -31,6 +31,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
+ lintOptions {
+ abortOnError false
+ }
}
dependencies {
@@ -47,18 +50,20 @@ dependencies {
// implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
// Coroutines
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0"
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2-native-mt'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt'
testImplementation 'junit:junit:4.13.2'
+ testImplementation 'com.google.truth:truth:1.1.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'com.google.truth:truth:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// Like button
implementation 'com.github.jd-alexander:LikeButton:0.2.3'
// Room persistence library
- implementation "androidx.room:room-runtime:2.3.0"
+ implementation "androidx.room:room-ktx:2.3.0"
kapt "androidx.room:room-compiler:2.3.0"
// Paging
@@ -68,10 +73,10 @@ dependencies {
implementation 'com.github.ibrahimsn98:SmoothBottomBar:1.7.6'
// round cardview
- implementation 'com.github.captain-miao:optroundcardview:1.0.0'
+ implementation 'com.github.captain-miao:optroundcardview:1.1.0'
// lottie
- implementation "com.airbnb.android:lottie:3.4.0"
+ implementation 'com.airbnb.android:lottie:4.1.0'
// page indicator
implementation "com.romandanylyk:pageindicatorview:1.0.3@aar"
@@ -83,8 +88,8 @@ dependencies {
implementation 'de.hdodenhof:circleimageview:3.1.0'
// glide
- implementation 'com.github.bumptech.glide:glide:4.11.0'
- kapt 'com.github.bumptech.glide:compiler:4.11.0'
+ implementation 'com.github.bumptech.glide:glide:4.12.0'
+ kapt 'com.github.bumptech.glide:compiler:4.12.0'
// recyclerViewSwipeDecorator
implementation 'it.xabaras.android:recyclerview-swipedecorator:1.2.3'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6cfdc4a..3022970 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -16,7 +16,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.Notes"
tools:replace="android:theme">
-
diff --git a/app/src/main/java/com/certified/notes/adapters/BookMarkRecyclerAdapter.kt b/app/src/main/java/com/certified/notes/adapters/BookMarkRecyclerAdapter.kt
index 85fe432..d8805bf 100644
--- a/app/src/main/java/com/certified/notes/adapters/BookMarkRecyclerAdapter.kt
+++ b/app/src/main/java/com/certified/notes/adapters/BookMarkRecyclerAdapter.kt
@@ -39,19 +39,15 @@ class BookMarkRecyclerAdapter(
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- val noteContent: TextView
- val noteTitle: TextView
- val likeButton: LikeButton
- val ivBookMark: ImageView
- init {
- noteContent = itemView.findViewById(R.id.tv_note_content)
- noteTitle = itemView.findViewById(R.id.tv_note_title)
- likeButton = itemView.findViewById(R.id.likeButton)
- ivBookMark = itemView.findViewById(R.id.iv_bookmark)
+ val noteContent: TextView = itemView.findViewById(R.id.tv_note_content)
+ val noteTitle: TextView = itemView.findViewById(R.id.tv_note_title)
+ val likeButton: LikeButton = itemView.findViewById(R.id.likeButton)
+ val ivBookMark: ImageView = itemView.findViewById(R.id.iv_bookmark)
+ init {
itemView.setOnClickListener {
- val position = adapterPosition
+ val position = absoluteAdapterPosition
if (position != RecyclerView.NO_POSITION) {
listener.onBookMarkClick(getItem(position))
}
@@ -84,6 +80,7 @@ class BookMarkRecyclerAdapter(
holder.noteContent.text = currentBookMark.noteContent
holder.noteTitle.text = currentBookMark.noteTitle
holder.ivBookMark.visibility = View.VISIBLE
+// holder.itemView.setOnClickListener{ onBookMarkClicked?.invoke(currentBookMark)}
// holder.likeButton.isLiked = true
// holder.likeButton.setOnLikeListener(object : OnLikeListener {
// override fun liked(likeButton: LikeButton?) {
diff --git a/app/src/main/java/com/certified/notes/adapters/CourseRecyclerAdapter.kt b/app/src/main/java/com/certified/notes/adapters/CourseRecyclerAdapter.kt
index f2ab630..2d1fba3 100644
--- a/app/src/main/java/com/certified/notes/adapters/CourseRecyclerAdapter.kt
+++ b/app/src/main/java/com/certified/notes/adapters/CourseRecyclerAdapter.kt
@@ -29,8 +29,8 @@ class CourseRecyclerAdapter :
init {
- itemView.setOnClickListener{
- val position = adapterPosition
+ itemView.setOnClickListener {
+ val position = absoluteAdapterPosition
if (position != RecyclerView.NO_POSITION)
listener.onCourseClicked(getItem(position))
}
diff --git a/app/src/main/java/com/certified/notes/adapters/NoteRecyclerAdapter.kt b/app/src/main/java/com/certified/notes/adapters/NoteRecyclerAdapter.kt
index b8b9c0c..d63f563 100644
--- a/app/src/main/java/com/certified/notes/adapters/NoteRecyclerAdapter.kt
+++ b/app/src/main/java/com/certified/notes/adapters/NoteRecyclerAdapter.kt
@@ -77,7 +77,7 @@ class NoteRecyclerAdapter(context: Context) :
}
interface OnNoteClickedListener {
- fun onNoteClick(note: Note?)
+ fun onNoteClick(note: Note)
}
inner class ViewHolder(itemView: View) :
diff --git a/app/src/main/java/com/certified/notes/adapters/ResultRecyclerAdapter.kt b/app/src/main/java/com/certified/notes/adapters/ResultRecyclerAdapter.kt
index 76f29df..b60f341 100644
--- a/app/src/main/java/com/certified/notes/adapters/ResultRecyclerAdapter.kt
+++ b/app/src/main/java/com/certified/notes/adapters/ResultRecyclerAdapter.kt
@@ -16,11 +16,11 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.certified.notes.R
import com.certified.notes.model.Course
-import com.certified.notes.room.NotesViewModel
+import com.certified.notes.view.Main.MainActivityViewModel
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-class ResultRecyclerAdapter(val context: Context, private val viewModel: NotesViewModel) :
+class ResultRecyclerAdapter(val context: Context, private val viewModel: MainActivityViewModel) :
ListAdapter(DIFF_CALLBACK) {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
diff --git a/app/src/main/java/com/certified/notes/adapters/TodoRecyclerAdapter.kt b/app/src/main/java/com/certified/notes/adapters/TodoRecyclerAdapter.kt
index 0db8663..ab1d215 100644
--- a/app/src/main/java/com/certified/notes/adapters/TodoRecyclerAdapter.kt
+++ b/app/src/main/java/com/certified/notes/adapters/TodoRecyclerAdapter.kt
@@ -14,11 +14,11 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.certified.notes.R
import com.certified.notes.model.Todo
-import com.certified.notes.room.NotesViewModel
+import com.certified.notes.view.Home.HomeViewModel
import com.google.android.material.checkbox.MaterialCheckBox
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-class TodoRecyclerAdapter(val context: Context, private val viewModel: NotesViewModel) :
+class TodoRecyclerAdapter(val context: Context, private val viewModel: HomeViewModel) :
ListAdapter(DIFF_CALLBACK) {
private lateinit var listener: OnTodoClickedListener
@@ -98,7 +98,7 @@ class TodoRecyclerAdapter(val context: Context, private val viewModel: NotesView
}
builder.setNegativeButton(context.getString(R.string.no)) { dialog, _ ->
val todo1 = Todo(todoContent, true)
- todo1.id = getItem(position).id
+ todo1.id = todo.id
viewModel.updateTodo(todo1)
dialog.cancel()
}
diff --git a/app/src/main/java/com/certified/notes/model/BookMark.kt b/app/src/main/java/com/certified/notes/model/BookMark.kt
index e4766a5..b108523 100644
--- a/app/src/main/java/com/certified/notes/model/BookMark.kt
+++ b/app/src/main/java/com/certified/notes/model/BookMark.kt
@@ -5,12 +5,16 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "bookmark_table")
-class BookMark(
- @field:ColumnInfo(name = "note_id") val noteId: Int,
- @field:ColumnInfo(name = "course_code") val courseCode: String,
- @field:ColumnInfo(name = "note_title") val noteTitle: String,
- @field:ColumnInfo(name = "note_content") val noteContent: String
+data class BookMark(
+ @ColumnInfo(name = "note_id")
+ val noteId: Int,
+ @ColumnInfo(name = "course_code")
+ val courseCode: String,
+ @ColumnInfo(name = "note_title")
+ val noteTitle: String,
+ @ColumnInfo(name = "note_content")
+ val noteContent: String
) {
@PrimaryKey(autoGenerate = true)
- var id = 0
+ var id: Int = 0;
}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/model/Course.kt b/app/src/main/java/com/certified/notes/model/Course.kt
index 56cf6d6..fcf38ae 100644
--- a/app/src/main/java/com/certified/notes/model/Course.kt
+++ b/app/src/main/java/com/certified/notes/model/Course.kt
@@ -5,15 +5,22 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "course_table")
-class Course(
- @field:ColumnInfo(name = "course_code") val courseCode: String,
- @field:ColumnInfo(name = "course_title") val courseTitle: String,
- @field:ColumnInfo(name = "course_unit") val courseUnit: Int,
- @field:ColumnInfo(name = "course_mark") val courseMark: Int,
- @field:ColumnInfo(name = "course_grade") val courseGrade: String,
- @field:ColumnInfo(name = "course_grade_point") val courseGradePoint: Int
+data class Course(
+ @ColumnInfo(name = "course_code")
+ val courseCode: String,
+ @ColumnInfo(name = "course_title")
+ val courseTitle: String,
+ @ColumnInfo(name = "course_unit")
+ val courseUnit: Int,
+ @ColumnInfo(name = "course_mark")
+ val courseMark: Int,
+ @ColumnInfo(name = "course_grade")
+ val courseGrade: String,
+ @ColumnInfo(name = "course_grade_point")
+ val courseGradePoint: Int,
+ @ColumnInfo(name = "course_credit_point")
+ val courseCreditPoint: Int = courseGradePoint * courseUnit
) {
@PrimaryKey(autoGenerate = true)
- var id = 0
- @field:ColumnInfo(name = "course_credit_point") var courseCreditPoint: Int = courseGradePoint * courseUnit
+ var id: Int = 0
}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/model/Note.kt b/app/src/main/java/com/certified/notes/model/Note.kt
index 0e717ff..d32d260 100644
--- a/app/src/main/java/com/certified/notes/model/Note.kt
+++ b/app/src/main/java/com/certified/notes/model/Note.kt
@@ -5,11 +5,14 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "note_table")
-class Note(
- @field:ColumnInfo(name = "course_code") val courseCode: String?,
- @field:ColumnInfo(name = "note_title") val title: String,
- @field:ColumnInfo(name = "note_content") val content: String?
+data class Note(
+ @ColumnInfo(name = "course_code")
+ val courseCode: String,
+ @ColumnInfo(name = "note_title")
+ val title: String,
+ @ColumnInfo(name = "note_content")
+ val content: String?
) {
@PrimaryKey(autoGenerate = true)
- var id = 0
+ var id: Int = 0
}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/model/Result.kt b/app/src/main/java/com/certified/notes/model/Result.kt
index 6bc736f..d6bed84 100644
--- a/app/src/main/java/com/certified/notes/model/Result.kt
+++ b/app/src/main/java/com/certified/notes/model/Result.kt
@@ -4,11 +4,11 @@ import androidx.room.ColumnInfo
import androidx.room.PrimaryKey
//@Entity(tableName = "result_table")
-class Result(
- @field:ColumnInfo(name = "course_code") val courseCode: String,
- @field:ColumnInfo(name = "course_unit") val courseUnit: String,
- @field:ColumnInfo(name = "course_mark") val courseMark: String
+data class Result(
+ @ColumnInfo(name = "course_code") val courseCode: String,
+ @ColumnInfo(name = "course_unit") val courseUnit: String,
+ @ColumnInfo(name = "course_mark") val courseMark: String
) {
@PrimaryKey(autoGenerate = true)
- var id = 0
+ var id: Int = 0
}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/model/SliderItem.kt b/app/src/main/java/com/certified/notes/model/SliderItem.kt
index 789eb01..2ad9777 100644
--- a/app/src/main/java/com/certified/notes/model/SliderItem.kt
+++ b/app/src/main/java/com/certified/notes/model/SliderItem.kt
@@ -1,3 +1,3 @@
package com.certified.notes.model
-class SliderItem (val animation: Int, val title: String, val description: String)
\ No newline at end of file
+data class SliderItem (val animation: Int, val title: String, val description: String)
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/model/Todo.kt b/app/src/main/java/com/certified/notes/model/Todo.kt
index d3b26bf..29e1c50 100644
--- a/app/src/main/java/com/certified/notes/model/Todo.kt
+++ b/app/src/main/java/com/certified/notes/model/Todo.kt
@@ -4,7 +4,10 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "todo_table")
-class Todo(val todo: String, val isDone: Boolean) {
+data class Todo(
+ val todo: String,
+ val isDone: Boolean
+) {
@PrimaryKey(autoGenerate = true)
- var id = 0
+ var id: Int = 0
}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/model/User.kt b/app/src/main/java/com/certified/notes/model/User.kt
index e87049b..8df874a 100644
--- a/app/src/main/java/com/certified/notes/model/User.kt
+++ b/app/src/main/java/com/certified/notes/model/User.kt
@@ -6,13 +6,13 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "user_table")
-class User(
+data class User(
val name: String,
val school: String,
val department: String,
val level: String,
- @field:ColumnInfo(name = "profile_image") val profileImage: Bitmap?
+ @ColumnInfo(name = "profile_image") val profileImage: Bitmap?
) {
@PrimaryKey
- var id = 0
+ var id: Int = 0
}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/room/NotesDao.kt b/app/src/main/java/com/certified/notes/room/NotesDao.kt
index 296f286..0b31d29 100644
--- a/app/src/main/java/com/certified/notes/room/NotesDao.kt
+++ b/app/src/main/java/com/certified/notes/room/NotesDao.kt
@@ -7,47 +7,47 @@ import com.certified.notes.model.*
@Dao
interface NotesDao {
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insertNote(note: Note)
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun insertNote(note: Note)
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insertCourse(course: Course)
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun insertCourse(course: Course)
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insertTodo(todo: Todo)
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun insertTodo(todo: Todo)
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insertBookMark(bookMark: BookMark)
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun insertBookMark(bookMark: BookMark)
@Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insertUser(user: User)
+ suspend fun insertUser(user: User)
- @Update
- fun updateNote(note: Note)
+ @Update(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun updateNote(note: Note)
- @Update
- fun updateCourse(course: Course)
+ @Update(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun updateCourse(course: Course)
- @Update
- fun updateTodo(todo: Todo)
+ @Update(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun updateTodo(todo: Todo)
- @Update
- fun updateBookMark(bookMark: BookMark)
+ @Update(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun updateBookMark(bookMark: BookMark)
- @Update
- fun updateUser(user: User)
+ @Update(onConflict = OnConflictStrategy.IGNORE)
+ suspend fun updateUser(user: User)
@Delete
- fun deleteNote(note: Note)
+ suspend fun deleteNote(note: Note)
@Delete
- fun deleteCourse(course: Course)
+ suspend fun deleteCourse(course: Course)
@Delete
- fun deleteTodo(todo: Todo)
+ suspend fun deleteTodo(todo: Todo)
@Delete
- fun deleteBookMark(bookMark: BookMark)
+ suspend fun deleteBookMark(bookMark: BookMark)
@Query("DELETE FROM note_table ")
fun deleteAllNotes()
@@ -95,10 +95,10 @@ interface NotesDao {
fun getNotesAt(course_code: String): LiveData>
@Query("SELECT course_code FROM course_table WHERE course_title = :courseTitle")
- fun getCourseCode(courseTitle: String): String?
+ fun getCourseCode(courseTitle: String): String
@Query("SELECT course_title FROM course_table WHERE course_code = :courseCode")
- fun getCourseTitle(courseCode: String): String?
+ fun getCourseTitle(courseCode: String): String
@Query("SELECT note_id FROM bookmark_table")
fun getNoteIds(): LiveData>
@@ -116,7 +116,7 @@ interface NotesDao {
fun getDeletableBookmarks(noCourse: String): LiveData>
@Query("SELECT * FROM note_table WHERE note_title LIKE :searchQuery OR note_content LIKE :searchQuery OR course_code LIKE :searchQuery ORDER BY note_title ASC")
- fun searchNotes(searchQuery: String): LiveData?>?
+ fun searchNotes(searchQuery: String?): LiveData?>?
@Query("SELECT * FROM course_table WHERE course_code LIKE :searchQuery OR course_title LIKE :searchQuery ORDER BY course_code ASC")
fun searchCourses(searchQuery: String?): LiveData?>?
diff --git a/app/src/main/java/com/certified/notes/room/NotesDatabase.kt b/app/src/main/java/com/certified/notes/room/NotesDatabase.kt
index 77104ad..a027729 100644
--- a/app/src/main/java/com/certified/notes/room/NotesDatabase.kt
+++ b/app/src/main/java/com/certified/notes/room/NotesDatabase.kt
@@ -1,31 +1,30 @@
package com.certified.notes.room
import android.content.Context
+import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.sqlite.db.SupportSQLiteDatabase
-import com.certified.notes.model.Course
-import com.certified.notes.model.Note
-import com.certified.notes.model.Todo
-import com.certified.notes.model.User
+import com.certified.notes.model.*
import com.certified.notes.util.Converters
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Executors
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
-//@Database(
-// entities = [Note::class, Course::class, Todo::class, BookMark::class, User::class],
-// version = 1,
-// exportSchema = false
-//)
+@Database(
+ entities = [Note::class, Course::class, Todo::class, BookMark::class, User::class],
+ version = 1,
+ exportSchema = false
+)
@TypeConverters(Converters::class)
abstract class NotesDatabase : RoomDatabase() {
abstract fun noteDao(): NotesDao
companion object {
- private const val NUMBER_OF_THREADS = 4
- val databaseWriteExecutor: ExecutorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS)
- private lateinit var instance: NotesDatabase
+ @Volatile
+ private var INSTANCE: NotesDatabase? = null
+
private val roomCallback: Callback = object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
@@ -72,104 +71,128 @@ abstract class NotesDatabase : RoomDatabase() {
"Foreground Services can be tied to a notification icon"
)
- val course1 = Course("AGE 301", "Engineering Statistics", 2, 0, "F", 0)
- val course2 = Course("CPE 301", "Digital System Design with VHDL", 3, 0, "F", 0)
- val course3 = Course("EEE 301", "Measurement and Instrumentation", 2, 0, "F", 0)
- val course4 = Course("EEE 303", "Electronics Engineering I", 3, 0, "F", 0)
- val course5 = Course("EEE 305", "Electromagnetic Field Theory", 2, 0, "F", 0)
- val course6 = Course("EEE 307", "Electric Machines I", 3, 0, "F", 0)
- val course7 = Course("EEE 311", "Electric Circuit Theory I", 3, 0, "F", 0)
- val course8 = Course("EEE 313", "Electrical/Electronic Laboratory I", 1, 0, "F", 0)
- val course9 = Course("MTS 315", "Engineering Mathematics I", 3, 0, "F", 0)
- val course10 = Course("PMT 301", "Introduction to Entrepreneurship", 2, 0, "F", 0)
+ val course1 = Course(
+ "AGE 301", "Engineering Statistics", 2, 0, "F", 0
+ )
+ val course2 = Course(
+ "CPE 301", "Digital System Design with VHDL", 3, 0, "F", 0
+ )
+ val course3 = Course(
+ "EEE 301", "Measurement and Instrumentation", 2, 0, "F", 0
+ )
+ val course4 = Course(
+ "EEE 303", "Electronics Engineering I", 3, 0, "F", 0
+ )
+ val course5 = Course(
+ "EEE 305", "Electromagnetic Field Theory", 2, 0, "F", 0
+ )
+ val course6 = Course(
+ "EEE 307", "Electric Machines I", 3, 0, "F", 0
+ )
+ val course7 = Course(
+ "EEE 311", "Electric Circuit Theory I", 3, 0, "F", 0
+ )
+ val course8 = Course(
+ "EEE 313", "Electrical/Electronic Laboratory I", 1, 0, "F", 0
+ )
+ val course9 = Course(
+ "MTS 315", "Engineering Mathematics I", 3, 0, "F", 0
+ )
+ val course10 = Course(
+ "PMT 301", "Introduction to Entrepreneurship", 2, 0, "F", 0
+ )
val todo1 = Todo(
- "Make sure to complete the To-dos below",
- false
+ "Make sure to complete the To-dos below", false
)
val todo2 = Todo(
"Learn LiveData, Room, ViewModel, WorkManager, Notification, Paging library",
false
)
val todo3 = Todo(
- "The above should be learnt completely in order to pass the AAD exam",
- false
+ "The abdove should be learnt completely in order to pass the AAD exam", false
)
val todo4 = Todo(
- "Stop all projects that aren't related to the AAD exam",
- false
+ "Stop all projects that aren't related to the AAD exam", false
)
val todo5 = Todo(
- "Visit the code labs and study guide for the AAD exam frequently",
- false
+ "Visit the code labs and study guide for the AAD exam frequently", false
)
val todo6 = Todo(
"Practice, Practice and keep practicing. Obtaining the AAD certificate should be the only priority for now",
false
)
val todo7 = Todo(
- "Make sure you pass the exam at the first try!!!",
- false
+ "Make sure you pass the exam at the first try!!!", false
)
val todo8 = Todo(
- "Make sure to complete the To-dos above",
- false
+ "Make sure to complete the To-dos above", false
)
val user =
- User("Enter name", "Enter school", "Enter department", "Select level", null)
+ User(
+ name = "Enter name",
+ school = "Enter school",
+ department = "Enter department",
+ level = "Select level",
+ profileImage = null
+ )
- databaseWriteExecutor.execute {
- val notesDao = instance.noteDao()
+ CoroutineScope(Dispatchers.IO).launch {
+ val notesDao = INSTANCE?.noteDao()
+ if (notesDao != null) {
// notesDao.deleteAllNotes()
- notesDao.insertNote(note1)
- notesDao.insertNote(note2)
- notesDao.insertNote(note3)
- notesDao.insertNote(note4)
- notesDao.insertNote(note5)
- notesDao.insertNote(note6)
- notesDao.insertNote(note7)
- notesDao.insertNote(note8)
+ notesDao.insertNote(note1)
+ notesDao.insertNote(note2)
+ notesDao.insertNote(note3)
+ notesDao.insertNote(note4)
+ notesDao.insertNote(note5)
+ notesDao.insertNote(note6)
+ notesDao.insertNote(note7)
+ notesDao.insertNote(note8)
// notesDao.deleteAllCourses()
- notesDao.insertCourse(course1)
- notesDao.insertCourse(course2)
- notesDao.insertCourse(course3)
- notesDao.insertCourse(course4)
- notesDao.insertCourse(course5)
- notesDao.insertCourse(course6)
- notesDao.insertCourse(course7)
- notesDao.insertCourse(course8)
- notesDao.insertCourse(course9)
- notesDao.insertCourse(course10)
+ notesDao.insertCourse(course1)
+ notesDao.insertCourse(course2)
+ notesDao.insertCourse(course3)
+ notesDao.insertCourse(course4)
+ notesDao.insertCourse(course5)
+ notesDao.insertCourse(course6)
+ notesDao.insertCourse(course7)
+ notesDao.insertCourse(course8)
+ notesDao.insertCourse(course9)
+ notesDao.insertCourse(course10)
// notesDao.deleteAllTodos()
- notesDao.insertTodo(todo1)
- notesDao.insertTodo(todo2)
- notesDao.insertTodo(todo3)
- notesDao.insertTodo(todo4)
- notesDao.insertTodo(todo5)
- notesDao.insertTodo(todo6)
- notesDao.insertTodo(todo7)
- notesDao.insertTodo(todo8)
+ notesDao.insertTodo(todo1)
+ notesDao.insertTodo(todo2)
+ notesDao.insertTodo(todo3)
+ notesDao.insertTodo(todo4)
+ notesDao.insertTodo(todo5)
+ notesDao.insertTodo(todo6)
+ notesDao.insertTodo(todo7)
+ notesDao.insertTodo(todo8)
- notesDao.insertUser(user)
+ notesDao.insertUser(user)
+ }
}
}
}
@Synchronized
fun getInstance(context: Context): NotesDatabase {
+ var instance = INSTANCE
+
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
NotesDatabase::class.java,
"notes_database"
- )
- .fallbackToDestructiveMigration()
+ ).fallbackToDestructiveMigration()
.addCallback(roomCallback)
.build()
+ INSTANCE = instance
}
return instance
}
diff --git a/app/src/main/java/com/certified/notes/room/NotesDatabasekt.java b/app/src/main/java/com/certified/notes/room/NotesDatabasekt.java
index c1f3b2d..c423a0c 100644
--- a/app/src/main/java/com/certified/notes/room/NotesDatabasekt.java
+++ b/app/src/main/java/com/certified/notes/room/NotesDatabasekt.java
@@ -1,117 +1,117 @@
-package com.certified.notes.room;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.room.Database;
-import androidx.room.Room;
-import androidx.room.RoomDatabase;
-import androidx.room.TypeConverters;
-import androidx.sqlite.db.SupportSQLiteDatabase;
-
-import com.certified.notes.model.BookMark;
-import com.certified.notes.model.Course;
-import com.certified.notes.model.Note;
-import com.certified.notes.model.Todo;
-import com.certified.notes.model.User;
-import com.certified.notes.util.Converters;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-@Database(entities = {Note.class, Course.class, Todo.class, BookMark.class, User.class}, version = 1, exportSchema = false)
-@TypeConverters(Converters.class)
-public abstract class NotesDatabasekt extends RoomDatabase {
-
- private static final int NUMBER_OF_THREADS = 4;
- public static final ExecutorService databaseWriteExecutor = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
- private static NotesDatabasekt instance;
- private static final RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
- @Override
- public void onCreate(@NonNull SupportSQLiteDatabase db) {
- super.onCreate(db);
-
- Note note1 = new Note("MTS 315", "Dynamic intent resolution", "Wow, intents allow components to be resolved at runtime");
- Note note2 = new Note("CPE 301", "Parameters", "Leverage variable-length parameter lists?");
- Note note3 = new Note("EEE 301", "Delegating intents", "PendingIntents are powerful; they delegate much more than just a component invocation");
- Note note4 = new Note("AGE 301", "Compiler options", "The -jar option isn't compatible with with the -cp option");
- Note note5 = new Note("EEE 305", "Serialization", "Remember to include SerialVersionUID to assure version compatibility");
- Note note6 = new Note("PMT 301", "Service default threads", "Did you know that by default an Android Service will tie up the UI thread?");
- Note note7 = new Note("EEE 311", "Anonymous classes", "Anonymous classes simplify implementing one-use types");
- Note note8 = new Note("EEE 307", "Long running operations", "Foreground Services can be tied to a notification icon");
-
- Course course1 = new Course("AGE 301", "Engineering Statistics", 2, 0, "F", 0);
- Course course2 = new Course("CPE 301", "Digital System Design with VHDL", 3, 0, "F", 0);
- Course course3 = new Course("EEE 301", "Measurement and Instrumentation", 2, 0, "F", 0);
- Course course4 = new Course("EEE 303", "Electronics Engineering I", 3, 0, "F", 0);
- Course course5 = new Course("EEE 305", "Electromagnetic Field Theory", 2, 0, "F", 0);
- Course course6 = new Course("EEE 307", "Electric Machines I", 3, 0, "F", 0);
- Course course7 = new Course("EEE 311", "Electric Circuit Theory I", 3, 0, "F", 0);
- Course course8 = new Course("EEE 313", "Electrical/Electronic Laboratory I", 1, 0, "F", 0);
- Course course9 = new Course("MTS 315", "Engineering Mathematics I", 3, 0, "F", 0);
- Course course10 = new Course("PMT 301", "Introduction to Entrepreneurship", 2, 0, "F", 0);
-
- Todo todo1 = new Todo("Make sure to complete the To-dos below", false);
- Todo todo2 = new Todo("Learn LiveData, Room, ViewModel, WorkManager, Notification, Paging library", false);
- Todo todo3 = new Todo("The above should be learnt completely in order to pass the AAD exam", false);
- Todo todo4 = new Todo("Stop all projects that aren't related to the AAD exam", false);
- Todo todo5 = new Todo("Visit the code labs and study guide for the AAD exam frequently", false);
- Todo todo6 = new Todo("Practice, Practice and keep practicing. Obtaining the AAD certificate should be the only priority for now", false);
- Todo todo7 = new Todo("Make sure you pass the exam at the first try!!!", false);
- Todo todo8 = new Todo("Make sure to complete the To-dos above", false);
-
- User user = new User("Enter name", "Enter school", "Enter department", "Select level", null);
-
- databaseWriteExecutor.execute(() -> {
- NotesDao notesDao = instance.mNotesDao();
-
-// notesDao.deleteAllNotes();
- notesDao.insertNote(note1);
- notesDao.insertNote(note2);
- notesDao.insertNote(note3);
- notesDao.insertNote(note4);
- notesDao.insertNote(note5);
- notesDao.insertNote(note6);
- notesDao.insertNote(note7);
- notesDao.insertNote(note8);
-
-// notesDao.deleteAllCourses();
- notesDao.insertCourse(course1);
- notesDao.insertCourse(course2);
- notesDao.insertCourse(course3);
- notesDao.insertCourse(course4);
- notesDao.insertCourse(course5);
- notesDao.insertCourse(course6);
- notesDao.insertCourse(course7);
- notesDao.insertCourse(course8);
- notesDao.insertCourse(course9);
- notesDao.insertCourse(course10);
-
-// notesDao.deleteAllTodos();
- notesDao.insertTodo(todo1);
- notesDao.insertTodo(todo2);
- notesDao.insertTodo(todo3);
- notesDao.insertTodo(todo4);
- notesDao.insertTodo(todo5);
- notesDao.insertTodo(todo6);
- notesDao.insertTodo(todo7);
- notesDao.insertTodo(todo8);
-//
- notesDao.insertUser(user);
- });
- }
- };
-
- public static synchronized NotesDatabasekt getInstance(Context context) {
-
- if (instance == null) {
- instance = Room.databaseBuilder(context.getApplicationContext(), NotesDatabasekt.class, "notes_database")
- .fallbackToDestructiveMigration()
- .addCallback(roomCallback)
- .build();
- }
- return instance;
- }
-
- public abstract NotesDao mNotesDao();
-}
\ No newline at end of file
+//package com.certified.notes.room;
+//
+//import android.content.Context;
+//
+//import androidx.annotation.NonNull;
+//import androidx.room.Database;
+//import androidx.room.Room;
+//import androidx.room.RoomDatabase;
+//import androidx.room.TypeConverters;
+//import androidx.sqlite.db.SupportSQLiteDatabase;
+//
+//import com.certified.notes.model.BookMark;
+//import com.certified.notes.model.Course;
+//import com.certified.notes.model.Note;
+//import com.certified.notes.model.Todo;
+//import com.certified.notes.model.User;
+//import com.certified.notes.util.Converters;
+//
+//import java.util.concurrent.ExecutorService;
+//import java.util.concurrent.Executors;
+//
+////@Database(entities = {Note.class, Course.class, Todo.class, BookMark.class, User.class}, version = 1, exportSchema = false)
+////@TypeConverters(Converters.class)
+//public abstract class NotesDatabasekt extends RoomDatabase {
+//
+// private static final int NUMBER_OF_THREADS = 4;
+// public static final ExecutorService databaseWriteExecutor = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
+// private static NotesDatabasekt instance;
+// private static final RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
+// @Override
+// public void onCreate(@NonNull SupportSQLiteDatabase db) {
+// super.onCreate(db);
+//
+// Note note1 = new Note("MTS 315", "Dynamic intent resolution", "Wow, intents allow components to be resolved at runtime");
+// Note note2 = new Note("CPE 301", "Parameters", "Leverage variable-length parameter lists?");
+// Note note3 = new Note("EEE 301", "Delegating intents", "PendingIntents are powerful; they delegate much more than just a component invocation");
+// Note note4 = new Note("AGE 301", "Compiler options", "The -jar option isn't compatible with with the -cp option");
+// Note note5 = new Note("EEE 305", "Serialization", "Remember to include SerialVersionUID to assure version compatibility");
+// Note note6 = new Note("PMT 301", "Service default threads", "Did you know that by default an Android Service will tie up the UI thread?");
+// Note note7 = new Note("EEE 311", "Anonymous classes", "Anonymous classes simplify implementing one-use types");
+// Note note8 = new Note("EEE 307", "Long running operations", "Foreground Services can be tied to a notification icon");
+//
+// Course course1 = new Course("AGE 301", "Engineering Statistics", 2, 0, "F", 0);
+// Course course2 = new Course("CPE 301", "Digital System Design with VHDL", 3, 0, "F", 0);
+// Course course3 = new Course("EEE 301", "Measurement and Instrumentation", 2, 0, "F", 0);
+// Course course4 = new Course("EEE 303", "Electronics Engineering I", 3, 0, "F", 0);
+// Course course5 = new Course("EEE 305", "Electromagnetic Field Theory", 2, 0, "F", 0);
+// Course course6 = new Course("EEE 307", "Electric Machines I", 3, 0, "F", 0);
+// Course course7 = new Course("EEE 311", "Electric Circuit Theory I", 3, 0, "F", 0);
+// Course course8 = new Course("EEE 313", "Electrical/Electronic Laboratory I", 1, 0, "F", 0);
+// Course course9 = new Course("MTS 315", "Engineering Mathematics I", 3, 0, "F", 0);
+// Course course10 = new Course("PMT 301", "Introduction to Entrepreneurship", 2, 0, "F", 0);
+//
+// Todo todo1 = new Todo("Make sure to complete the To-dos below", false);
+// Todo todo2 = new Todo("Learn LiveData, Room, ViewModel, WorkManager, Notification, Paging library", false);
+// Todo todo3 = new Todo("The above should be learnt completely in order to pass the AAD exam", false);
+// Todo todo4 = new Todo("Stop all projects that aren't related to the AAD exam", false);
+// Todo todo5 = new Todo("Visit the code labs and study guide for the AAD exam frequently", false);
+// Todo todo6 = new Todo("Practice, Practice and keep practicing. Obtaining the AAD certificate should be the only priority for now", false);
+// Todo todo7 = new Todo("Make sure you pass the exam at the first try!!!", false);
+// Todo todo8 = new Todo("Make sure to complete the To-dos above", false);
+//
+// User user = new User("Enter name", "Enter school", "Enter department", "Select level", null);
+//
+// databaseWriteExecutor.execute(() -> {
+// NotesDao notesDao = instance.mNotesDao();
+//
+//// notesDao.deleteAllNotes();
+// notesDao.insertNote(note1);
+// notesDao.insertNote(note2);
+// notesDao.insertNote(note3);
+// notesDao.insertNote(note4);
+// notesDao.insertNote(note5);
+// notesDao.insertNote(note6);
+// notesDao.insertNote(note7);
+// notesDao.insertNote(note8);
+//
+//// notesDao.deleteAllCourses();
+// notesDao.insertCourse(course1);
+// notesDao.insertCourse(course2);
+// notesDao.insertCourse(course3);
+// notesDao.insertCourse(course4);
+// notesDao.insertCourse(course5);
+// notesDao.insertCourse(course6);
+// notesDao.insertCourse(course7);
+// notesDao.insertCourse(course8);
+// notesDao.insertCourse(course9);
+// notesDao.insertCourse(course10);
+//
+//// notesDao.deleteAllTodos();
+// notesDao.insertTodo(todo1);
+// notesDao.insertTodo(todo2);
+// notesDao.insertTodo(todo3);
+// notesDao.insertTodo(todo4);
+// notesDao.insertTodo(todo5);
+// notesDao.insertTodo(todo6);
+// notesDao.insertTodo(todo7);
+// notesDao.insertTodo(todo8);
+////
+// notesDao.insertUser(user);
+// });
+// }
+// };
+//
+// public static synchronized NotesDatabasekt getInstance(Context context) {
+//
+// if (instance == null) {
+// instance = Room.databaseBuilder(context.getApplicationContext(), NotesDatabasekt.class, "notes_database")
+// .fallbackToDestructiveMigration()
+// .addCallback(roomCallback)
+// .build();
+// }
+// return instance;
+// }
+//
+// public abstract NotesDao mNotesDao();
+//}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/room/NotesViewModel.kt b/app/src/main/java/com/certified/notes/room/NotesViewModel.kt
deleted file mode 100644
index cbdb830..0000000
--- a/app/src/main/java/com/certified/notes/room/NotesViewModel.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.certified.notes.room
-
-import android.app.Application
-import androidx.lifecycle.AndroidViewModel
-import androidx.lifecycle.LiveData
-import com.certified.notes.model.*
-import com.certified.notes.util.Repository
-
-class NotesViewModel(application: Application) : AndroidViewModel(application) {
-
- private val repository = Repository(application)
-
- val allNotes: LiveData> = repository.allNotes
- val randomNotes: LiveData> = repository.randomNotes
- val allCourses: LiveData> = repository.allCourses
- val randomCourses: LiveData> = repository.randomCourses
- val allTodos: LiveData> = repository.allTodos
- val allBookMarks: LiveData> = repository.allBookMarks
- val allNoteIds: LiveData> = repository.allNoteIds
- val allCourseUnits: LiveData> = repository.allCourseUnits
- val allCourseCreditPoints: LiveData> = repository.allCourseCreditPoints
- val user: LiveData = repository.user
-
- fun insertNote(note: Note) {
- repository.insertNote(note)
- }
-
- fun insertCourse(course: Course) {
- repository.insertCourse(course)
- }
-
- fun insertTodo(todo: Todo) {
- repository.insertTodo(todo)
- }
-
- fun insertBookMark(bookMark: BookMark) {
- repository.insertBookMark(bookMark)
- }
-
- fun updateNote(note: Note) {
- repository.updateNote(note)
- }
-
- fun updateCourse(course: Course) {
- repository.updateCourse(course)
- }
-
- fun updateTodo(todo: Todo) {
- repository.updateTodo(todo)
- }
-
- fun updateBookMark(bookMark: BookMark) {
- repository.updateBookMark(bookMark)
- }
-
- fun updateUser(user: User) {
- repository.updateUser(user)
- }
-
- fun deleteNote(note: Note) {
- repository.deleteNote(note)
- }
-
- fun deleteCourse(course: Course) {
- repository.deleteCourse(course)
- }
-
- fun deleteTodo(todo: Todo) {
- repository.deleteTodo(todo)
- }
-
- fun deleteBookMark(bookMark: BookMark) {
- repository.deleteBookMark(bookMark)
- }
-
- fun deleteAllNotes() {
- repository.deleteAllNotes()
- }
-
- fun deleteAllCourses() {
- repository.deleteAllCourses()
- }
-
- fun deleteAllTodos() {
- repository.deleteAllTodos()
- }
-
- fun deleteAllBookMarks() {
- repository.deleteAllBookMarks()
- }
-
- fun deleteCompletedTodos() {
- repository.deleteCompletedTodos()
- }
-
- fun getCourseCode(courseTitle: String): String {
- return repository.getCourseCode(courseTitle)
- }
-
- fun getCourseTitle(courseCode: String): String {
- return repository.getCourseTitle(courseCode)
- }
-
- fun deleteBookMarkedNote(noteId: Int) {
- repository.deleteBookMarkedNote(noteId)
- }
-
- fun getBookMarkAt(noteId: Int): LiveData>? {
- return repository.getBookMarkAt(noteId)
- }
-
- fun getNotesAt(courseCode: String): LiveData>? {
- return repository.getNotesAt(courseCode)
- }
-
- fun getDeletableNotes(noCourse: String): LiveData>? {
- return repository.getDeletableNotes(noCourse)
- }
-
- fun getDeletableBookmarks(noCourse: String): LiveData>? {
- return repository.getDeletableBookmarks(noCourse)
- }
-
-
- fun searchNotes(searchQuery: String?): LiveData?>? {
- return repository.searchNotes(searchQuery)
- }
-
- fun searchCourses(searchQuery: String?): LiveData?>? {
- return repository.searchCourses(searchQuery)
- }
-
- fun searchBookmarks(searchQuery: String?): LiveData?>? {
- return repository.searchBookmarks(searchQuery)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/NotesFragment.java b/app/src/main/java/com/certified/notes/ui/NotesFragment.java
deleted file mode 100644
index 2bee812..0000000
--- a/app/src/main/java/com/certified/notes/ui/NotesFragment.java
+++ /dev/null
@@ -1,336 +0,0 @@
-package com.certified.notes.ui;
-
-import android.content.SharedPreferences;
-import android.os.Build;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.PopupMenu;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.widget.SearchView;
-import androidx.fragment.app.Fragment;
-import androidx.navigation.NavController;
-import androidx.preference.PreferenceManager;
-import androidx.recyclerview.widget.ItemTouchHelper;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.certified.notes.R;
-import com.certified.notes.adapters.NoteRecyclerAdapter;
-import com.certified.notes.model.BookMark;
-import com.certified.notes.model.Course;
-import com.certified.notes.model.Note;
-import com.certified.notes.room.NotesViewModel;
-import com.certified.notes.util.PreferenceKeys;
-import com.google.android.material.bottomsheet.BottomSheetDialog;
-import com.google.android.material.button.MaterialButton;
-import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-
-import io.sulek.ssml.SSMLLinearLayoutManager;
-
-import static android.graphics.Color.RED;
-import static android.text.TextUtils.isEmpty;
-
-public class NotesFragment extends Fragment implements PopupMenu.OnMenuItemClickListener {
-
- private RecyclerView recyclerNotes;
- private NavController mNavController;
- private NotesViewModel mViewModel;
- private ImageView ivNotePopupMenu;
- private SharedPreferences mPreferences;
- private SharedPreferences.Editor mEditor;
- private Set mDefValues;
- private Set mNoteIds;
- private SearchView svSearchNotes;
-
- public NotesFragment() {
- // Required empty public constructor
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // Inflate the layout for this fragment
- View view = inflater.inflate(R.layout.fragment_notes, container, false);
-
- recyclerNotes = view.findViewById(R.id.recycler_view_notes);
- ivNotePopupMenu = view.findViewById(R.id.iv_note_popup_menu);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- svSearchNotes = view.findViewById(R.id.sv_search_database);
- }
-
- return view;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- mViewModel = new NotesViewModel(requireActivity().getApplication());
- mPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext().getApplicationContext());
- ivNotePopupMenu.setOnClickListener(this::showPopupMenu);
-
- mDefValues = new HashSet<>();
- mDefValues.add("-1");
-
- mNoteIds = new HashSet<>(mPreferences.getStringSet(PreferenceKeys.NOTE_IDS, mDefValues));
-
- init();
- }
-
- private void showPopupMenu(View view) {
- PopupMenu menu = new PopupMenu(getContext(), view);
- menu.setOnMenuItemClickListener(this);
- menu.inflate(R.menu.note_menu);
- menu.show();
- }
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- int id = item.getItemId();
- if (id == R.id.delete_all_notes) {
- launchDeleteDialog();
- }
- return true;
- }
-
- private void init() {
- LinearLayoutManager noteLayoutManager = new LinearLayoutManager(getContext());
-
- NoteRecyclerAdapter noteRecyclerAdapter = new NoteRecyclerAdapter(getContext());
- mViewModel.getAllNotes().observe(getViewLifecycleOwner(), noteRecyclerAdapter::submitList);
- recyclerNotes.setAdapter(noteRecyclerAdapter);
- recyclerNotes.setLayoutManager(new SSMLLinearLayoutManager(requireContext()));
-
- ArrayList courseList = new ArrayList<>();
- ArrayAdapter adapterCourses = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, courseList);
-
- courseList.add(getString(R.string.select_a_course));
- courseList.add(getString(R.string.no_course));
- mViewModel.getAllCourses().observe(getViewLifecycleOwner(), courses -> {
- for (Course course : courses) {
- courseList.add(course.getCourseTitle());
- }
- adapterCourses.notifyDataSetChanged();
- });
-
- noteRecyclerAdapter.setOnNoteClickedListener(note -> {
- LayoutInflater inflater = this.getLayoutInflater();
- View view = inflater.inflate(R.layout.dialog_new_note, null);
- BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme);
-
- Spinner spinnerCourses = view.findViewById(R.id.spinner_courses);
- EditText etNoteTitle = view.findViewById(R.id.et_note_title);
- EditText etNoteContent = view.findViewById(R.id.et_note_content);
- MaterialButton btnSave = view.findViewById(R.id.btn_save);
- MaterialButton btnCancel = view.findViewById(R.id.btn_cancel);
- TextView tvNoteDialogTitle = view.findViewById(R.id.tv_note_dialog_title);
-
- adapterCourses.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- spinnerCourses.setAdapter(adapterCourses);
-
- tvNoteDialogTitle.setText(getString(R.string.edit_note));
- etNoteTitle.setText(note.getTitle());
- etNoteContent.setText(note.getContent());
- int coursePosition;
- if (!note.getCourseCode().equals("NIL")) {
- coursePosition = adapterCourses.getPosition(mViewModel.getCourseTitle(note.getCourseCode()));
- } else {
- coursePosition = 1;
- }
-
- spinnerCourses.setSelection(coursePosition);
-
- btnCancel.setOnClickListener(v -> bottomSheetDialog.dismiss());
- btnSave.setText(R.string.update);
- btnSave.setOnClickListener(v -> {
- String courseTitle = spinnerCourses.getSelectedItem().toString();
- String courseCode;
- if (courseTitle.equals(getString(R.string.no_course)))
- courseCode = "NIL";
- else
- courseCode = mViewModel.getCourseCode(courseTitle);
- String noteTitle = etNoteTitle.getText().toString().trim();
- String noteContent = etNoteContent.getText().toString().trim();
- if (!isEmpty(noteTitle) && !isEmpty(noteContent)) {
- if (!courseTitle.equals("Select a course")) {
- if (!courseTitle.equals("No course")) {
- if (!courseCode.equals(note.getCourseCode()) || !noteTitle.equals(note.getTitle()) || !noteContent.equals(note.getContent())) {
- Note note1 = new Note(courseCode, noteTitle, noteContent);
- note1.setId(note.getId());
- mViewModel.updateNote(note1);
- mViewModel.getBookMarkAt(note.getId()).observe(getViewLifecycleOwner(), bookMarks -> {
- if (bookMarks != null) {
- int noteId = note1.getId();
- for (BookMark bookMark : bookMarks) {
- BookMark bookMark1 = new BookMark(noteId, courseCode, noteTitle, noteContent);
- bookMark1.setId(bookMark.getId());
- mViewModel.updateBookMark(bookMark1);
- }
- }
- });
- noteRecyclerAdapter.notifyDataSetChanged();
- bottomSheetDialog.dismiss();
- } else
- Toast.makeText(getContext(), "Note not changed", Toast.LENGTH_SHORT).show();
- } else {
- if (!note.getCourseCode().equals("NIL") || !noteTitle.equals(note.getTitle()) || !noteContent.equals(note.getContent())) {
- Note note1 = new Note("NIL", noteTitle, noteContent);
- note1.setId(note.getId());
- mViewModel.updateNote(note1);
- mViewModel.getBookMarkAt(note.getId()).observe(getViewLifecycleOwner(), bookMarks -> {
- if (bookMarks != null) {
- int noteId = note1.getId();
- for (BookMark bookMark : bookMarks) {
- BookMark bookMark1 = new BookMark(noteId, "NIL", noteTitle, noteContent);
- bookMark1.setId(bookMark.getId());
- mViewModel.updateBookMark(bookMark1);
- }
- }
- });
- bottomSheetDialog.dismiss();
- } else
- Toast.makeText(getContext(), "Note not changed", Toast.LENGTH_SHORT).show();
- }
- } else
- Toast.makeText(getContext(), "Select a course", Toast.LENGTH_SHORT).show();
- } else
- Toast.makeText(getContext(), "All fields are required", Toast.LENGTH_SHORT).show();
- });
- bottomSheetDialog.setContentView(view);
- bottomSheetDialog.show();
- });
-
- new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
- @Override
- public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
- return false;
- }
-
- @Override
- public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
- switch (direction) {
- case ItemTouchHelper.LEFT:
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
- builder.setTitle("Delete");
- builder.setMessage(R.string.note_delete_dialog_message);
- builder.setPositiveButton(getString(R.string.delete), (dialog1, which) -> {
-
- int noteId = noteRecyclerAdapter.getNoteAt(viewHolder.getAdapterPosition()).getId();
-
- mViewModel.deleteNote(noteRecyclerAdapter.getNoteAt(viewHolder.getAdapterPosition()));
- mViewModel.deleteBookMarkedNote(noteId);
- mNoteIds.remove(String.valueOf(noteId));
-
- mEditor = mPreferences.edit();
- mEditor.putStringSet(PreferenceKeys.NOTE_IDS, mNoteIds);
- mEditor.apply();
-
- dialog1.dismiss();
- });
- builder.setNegativeButton(getString(R.string.cancel), (dialog1, which) -> {
- noteRecyclerAdapter.notifyDataSetChanged();
- dialog1.dismiss();
- });
- AlertDialog alertDialog = builder.create();
- alertDialog.setOnShowListener(dialog1 -> {
- alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(RED);
- alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(RED);
- });
- alertDialog.show();
- break;
- case ItemTouchHelper.RIGHT:
- Note note = noteRecyclerAdapter.getNoteAt(viewHolder.getAdapterPosition());
- int noteId = note.getId();
- String courseCode = note.getCourseCode();
- String noteTitle = note.getTitle();
- String noteContent = note.getContent();
- BookMark bookMark = new BookMark(noteId, courseCode, noteTitle, noteContent);
-
- mViewModel.getBookMarkAt(noteId).observe(getViewLifecycleOwner(), bookMarks -> {
- if (bookMarks == null) {
-// for(BookMark bookMark1 : bookMarks) {
-// }
-// else {
-// mViewModel.getAllBookMarks().observe(getViewLifecycleOwner(), bookMarks1 -> {
-// if (!bookMarks.contains(bookMark)) {
-// bookMark.setId(bookMark1.getId());
- mViewModel.insertBookMark(bookMark);
-
- mNoteIds.add(String.valueOf(noteId));
-
- mEditor = mPreferences.edit();
- mEditor.putStringSet(PreferenceKeys.NOTE_IDS, mNoteIds);
- mEditor.apply();
-// }
-// });
- }
- });
- noteRecyclerAdapter.notifyDataSetChanged();
- break;
- }
- }
- }).attachToRecyclerView(recyclerNotes);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- svSearchNotes.isSubmitButtonEnabled();
- svSearchNotes.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String query) {
- if (query != null) {
- searchNotes(query, noteRecyclerAdapter);
- }
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String query) {
- if (query != null) {
- searchNotes(query, noteRecyclerAdapter);
- }
- return true;
- }
- });
- }
- }
-
- private void searchNotes(String query, NoteRecyclerAdapter noteRecyclerAdapter) {
- String searchQuery = "%" + query + "%";
- mViewModel.searchNotes(searchQuery).observe(getViewLifecycleOwner(), noteRecyclerAdapter::submitList);
- }
-
- private void launchDeleteDialog() {
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
- builder.setTitle(R.string.delete);
- builder.setMessage(R.string.all_note_delete_dialog_message);
- builder.setIcon(R.drawable.ic_baseline_delete_24);
- builder.setPositiveButton(getString(R.string.yes), (dialog1, which) -> {
- mViewModel.deleteAllNotes();
- mViewModel.deleteAllBookMarks();
- dialog1.dismiss();
- });
- builder.setNegativeButton(getString(R.string.no), (dialog1, which) -> dialog1.dismiss());
- AlertDialog alertDialog = builder.create();
- alertDialog.setOnShowListener(dialog1 -> {
- alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(RED);
- alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(RED);
- });
- alertDialog.show();
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/ProfileFragment.java b/app/src/main/java/com/certified/notes/ui/ProfileFragment.java
deleted file mode 100644
index f32ae24..0000000
--- a/app/src/main/java/com/certified/notes/ui/ProfileFragment.java
+++ /dev/null
@@ -1,436 +0,0 @@
-package com.certified.notes.ui;
-
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.provider.MediaStore;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AppCompatDelegate;
-import androidx.constraintlayout.widget.Group;
-import androidx.fragment.app.Fragment;
-import androidx.navigation.NavController;
-import androidx.navigation.Navigation;
-import androidx.preference.PreferenceManager;
-
-import com.bumptech.glide.Glide;
-import com.certified.notes.R;
-import com.certified.notes.model.User;
-import com.certified.notes.room.NotesViewModel;
-import com.certified.notes.util.PreferenceKeys;
-import com.google.android.material.bottomsheet.BottomSheetDialog;
-import com.google.android.material.button.MaterialButton;
-import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-import com.google.android.material.switchmaterial.SwitchMaterial;
-import com.google.android.material.textfield.TextInputEditText;
-import com.google.android.material.textfield.TextInputLayout;
-import com.google.android.material.textview.MaterialTextView;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.Objects;
-
-import de.hdodenhof.circleimageview.CircleImageView;
-
-import static android.app.Activity.RESULT_OK;
-import static android.text.TextUtils.isEmpty;
-
-public class ProfileFragment extends Fragment implements View.OnClickListener {
-
- private static final int USER_ID = 0;
- private static final int REQUEST_IMAGE_CAPTURE = 101;
- private static final int PICK_IMAGE_CODE = 102;
- String userName, userSchool, userDepartment, userLevel;
- Bitmap profileImageBitmap;
- private NotesViewModel mViewModel;
- private NavController mNavController;
- private Group groupName, groupSchool, groupDepartment, groupLevel;
- private TextView tvName, tvSchool, tvDepartment, tvLevel;
- private CircleImageView profileImage;
- private FloatingActionButton fabChangeProfilePicture, fabSettings;
- private SwitchMaterial switchDarkMode;
-// private static final String currentPhotoPath;
-
- public ProfileFragment() {
- // Required empty public constructor
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // Inflate the layout for this fragment
- View view = inflater.inflate(R.layout.fragment_profile, container, false);
-
- groupName = view.findViewById(R.id.group_edit_name);
- groupSchool = view.findViewById(R.id.group_edit_school);
- groupDepartment = view.findViewById(R.id.group_edit_department);
- groupLevel = view.findViewById(R.id.group_edit_level);
-
- tvName = view.findViewById(R.id.tv_name);
- tvSchool = view.findViewById(R.id.tv_school);
- tvDepartment = view.findViewById(R.id.tv_department);
- tvLevel = view.findViewById(R.id.tv_level);
-
- profileImage = view.findViewById(R.id.profile_image);
- fabChangeProfilePicture = view.findViewById(R.id.fab_change_profile_picture);
- fabSettings = view.findViewById(R.id.fab_settings);
-
- switchDarkMode = view.findViewById(R.id.switch_dark_mode);
-
- return view;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- mViewModel = new NotesViewModel(requireActivity().getApplication());
- mNavController = Navigation.findNavController(view);
-
- groupName.setOnClickListener(this);
- groupSchool.setOnClickListener(this);
- groupDepartment.setOnClickListener(this);
- groupLevel.setOnClickListener(this);
-
- profileImage.setOnClickListener(this);
- fabChangeProfilePicture.setOnClickListener(this);
- fabSettings.setOnClickListener(this);
-
- mViewModel.getUser().observe(getViewLifecycleOwner(), user -> {
- if (user != null) {
- userName = user.getName();
- userSchool = user.getSchool();
- userDepartment = user.getDepartment();
- userLevel = user.getLevel();
- profileImageBitmap = user.getProfileImage();
-
- tvName.setText(userName);
- tvSchool.setText(userSchool);
- tvDepartment.setText(userDepartment);
- tvLevel.setText(userLevel);
- if (profileImageBitmap != null) {
- Glide.with(requireContext())
- .load(profileImageBitmap)
- .into(profileImage);
- } else {
- Glide.with(requireContext())
- .load(R.drawable.ic_logo)
- .into(profileImage);
- }
- }
- });
-
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(requireContext());
- boolean nightMode = preferences.getBoolean(PreferenceKeys.DARK_MODE, false);
- switchDarkMode.setChecked(nightMode);
- switchDarkMode.setOnClickListener(v -> {
- if (switchDarkMode.isChecked()) {
- SharedPreferences.Editor editor = preferences.edit();
- editor.putBoolean(PreferenceKeys.DARK_MODE, true);
- editor.apply();
-
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
- } else {
- SharedPreferences.Editor editor = preferences.edit();
- editor.putBoolean(PreferenceKeys.DARK_MODE, false);
- editor.apply();
-
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
- }
- });
- }
-
- @Override
- public void onClick(View v) {
- int id = v.getId();
- if (id == R.id.group_edit_name) {
- launchNameDialog();
- } else if (id == R.id.group_edit_school) {
- launchSchoolDialog();
- } else if (id == R.id.group_edit_department) {
- launchDepartmentDialog();
- } else if (id == R.id.group_edit_level) {
- launchLevelDialog();
- } else if (id == R.id.fab_settings) {
-// mNavController.navigate(R.id.settingsFragment);
- } else if (id == R.id.profile_image || id == R.id.fab_change_profile_picture) {
- launchProfileImageDialog();
- }
- }
-
- private void launchProfileImageDialog() {
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
- CharSequence[] selection = new CharSequence[]{
-// "View profile picture",
- "Take picture",
- "Choose from gallery",
- "Delete profile picture"
- };
- builder.setTitle("Options");
- builder.setSingleChoiceItems(selection, -1, (dialog, which) -> {
- switch (which) {
- case 0:
- launchCamera();
- dialog.dismiss();
- break;
- case 1:
- chooseFromGallery();
- dialog.dismiss();
- break;
- case 2:
- deleteProfileImage();
- dialog.dismiss();
- break;
- }
- });
- builder.show();
- }
-
- private void deleteProfileImage() {
- User user = new User(userName, userSchool, userDepartment, userLevel, null);
- user.setId(USER_ID);
- mViewModel.updateUser(user);
- }
-
- private void launchCamera() {
- Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- try {
- startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(getContext(), "An error occurred", Toast.LENGTH_LONG).show();
- }
- }
-
- public void chooseFromGallery() {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.setType("image/*");
-// intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
- try {
- startActivityForResult(Intent.createChooser(intent, "Select image"), PICK_IMAGE_CODE);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(getContext(), "An error occurred", Toast.LENGTH_LONG).show();
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
- assert data != null;
- Bundle extras = data.getExtras();
-
- Bitmap profileImageBitmap = (Bitmap) extras.get("data");
- String name = tvName.getText().toString();
- String school = tvSchool.getText().toString();
- String department = tvDepartment.getText().toString();
- String level = tvLevel.getText().toString();
-
- User user = new User(name, school, department, level, profileImageBitmap);
- user.setId(USER_ID);
- mViewModel.updateUser(user);
-
- Glide.with(requireContext())
- .load(profileImageBitmap)
- .into(profileImage);
- } else if (requestCode == PICK_IMAGE_CODE && resultCode == RESULT_OK) {
- assert data != null;
- Uri uri = data.getData();
- try {
- InputStream stream = getContext().getContentResolver().openInputStream(uri);
- Bitmap bitmap = BitmapFactory.decodeStream(stream);
- User user = new User(userName, userSchool, userDepartment, userLevel, bitmap);
- user.setId(USER_ID);
- mViewModel.updateUser(user);
-
- Glide.with(requireContext())
- .load(bitmap)
- .into(profileImage);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
-
- private void launchNameDialog() {
- LayoutInflater inflater = this.getLayoutInflater();
- View view = inflater.inflate(R.layout.dialog_edit_profile, null);
- BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme);
-
- MaterialTextView tvEditProfileDialogTitle = view.findViewById(R.id.tv_edit_profile_dialog_title);
- TextInputLayout inputLayout = view.findViewById(R.id.et_edit_profile_layout);
- TextInputEditText inputEditText = view.findViewById(R.id.et_edit_profile);
- MaterialButton btnCancel = view.findViewById(R.id.btn_cancel);
- MaterialButton btnSave = view.findViewById(R.id.btn_save);
-
- tvEditProfileDialogTitle.setText(R.string.edit_name);
- inputLayout.setHint(getString(R.string.name));
- inputEditText.setText(userName);
-
- btnCancel.setOnClickListener(v -> bottomSheetDialog.dismiss());
- btnSave.setOnClickListener(v -> {
- String name = Objects.requireNonNull(inputEditText.getText()).toString().trim();
- String school = tvSchool.getText().toString().trim();
- String department = tvDepartment.getText().toString().trim();
- String level = tvLevel.getText().toString().trim();
-
- if (!isEmpty(name)) {
- if (!name.equals(userName)) {
-
- User user = new User(name, school, department, level, profileImageBitmap);
- user.setId(USER_ID);
- mViewModel.updateUser(user);
- tvName.setText(name);
-
- bottomSheetDialog.dismiss();
- } else
- Toast.makeText(getContext(), "Name not changed", Toast.LENGTH_SHORT).show();
- } else
- Toast.makeText(getContext(), "Please Enter a name", Toast.LENGTH_SHORT).show();
- });
- bottomSheetDialog.setContentView(view);
- bottomSheetDialog.show();
- }
-
- private void launchSchoolDialog() {
- LayoutInflater inflater = this.getLayoutInflater();
- View view = inflater.inflate(R.layout.dialog_edit_profile, null);
- BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme);
-
- MaterialTextView tvEditProfileDialogTitle = view.findViewById(R.id.tv_edit_profile_dialog_title);
- TextInputLayout inputLayout = view.findViewById(R.id.et_edit_profile_layout);
- TextInputEditText inputEditText = view.findViewById(R.id.et_edit_profile);
- MaterialButton btnCancel = view.findViewById(R.id.btn_cancel);
- MaterialButton btnSave = view.findViewById(R.id.btn_save);
-
- tvEditProfileDialogTitle.setText(R.string.edit_school);
- inputLayout.setHint(getString(R.string.school));
- inputEditText.setText(userSchool);
-
- btnCancel.setOnClickListener(v -> bottomSheetDialog.dismiss());
- btnSave.setOnClickListener(v -> {
- String name = tvName.getText().toString().trim();
- String school = inputEditText.getText().toString().trim();
- String department = tvDepartment.getText().toString().trim();
- String level = tvLevel.getText().toString().trim();
-
- if (!isEmpty(school)) {
- if (!school.equals(userSchool)) {
- User user = new User(name, school, department, level, profileImageBitmap);
- user.setId(USER_ID);
-
- mViewModel.updateUser(user);
- tvSchool.setText(school);
-
- bottomSheetDialog.dismiss();
- } else
- Toast.makeText(getContext(), "School not changed", Toast.LENGTH_SHORT).show();
- } else
- Toast.makeText(getContext(), "Please Enter a school", Toast.LENGTH_SHORT).show();
- });
- bottomSheetDialog.setContentView(view);
- bottomSheetDialog.show();
- }
-
- private void launchDepartmentDialog() {
- LayoutInflater inflater = this.getLayoutInflater();
- View view = inflater.inflate(R.layout.dialog_edit_profile, null);
- BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme);
-
- MaterialTextView tvEditProfileDialogTitle = view.findViewById(R.id.tv_edit_profile_dialog_title);
- TextInputLayout inputLayout = view.findViewById(R.id.et_edit_profile_layout);
- TextInputEditText inputEditText = view.findViewById(R.id.et_edit_profile);
- MaterialButton btnCancel = view.findViewById(R.id.btn_cancel);
- MaterialButton btnSave = view.findViewById(R.id.btn_save);
-
- tvEditProfileDialogTitle.setText(R.string.edit_department);
- inputLayout.setHint(getString(R.string.department));
- inputEditText.setText(userDepartment);
-
- btnCancel.setOnClickListener(v -> bottomSheetDialog.dismiss());
- btnSave.setOnClickListener(v -> {
- String name = tvName.getText().toString().trim();
- String school = tvSchool.getText().toString().trim();
- String department = inputEditText.getText().toString().trim();
- String level = tvLevel.getText().toString().trim();
-
- if (!isEmpty(department)) {
- if (!department.equals(userDepartment)) {
- User user = new User(name, school, department, level, profileImageBitmap);
- user.setId(USER_ID);
-
- mViewModel.updateUser(user);
- tvDepartment.setText(department);
- bottomSheetDialog.dismiss();
- } else
- Toast.makeText(getContext(), "Department not changed", Toast.LENGTH_SHORT).show();
- } else
- Toast.makeText(getContext(), "Please Enter a department", Toast.LENGTH_SHORT).show();
- });
- bottomSheetDialog.setContentView(view);
- bottomSheetDialog.show();
- }
-
- private void launchLevelDialog() {
- LayoutInflater inflater = this.getLayoutInflater();
- View view = inflater.inflate(R.layout.dialog_edit_level, null);
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- builder.setBackground(getContext().getDrawable(R.drawable.alert_dialog_bg));
- }
- builder.setTitle(getString(R.string.select_level));
- AlertDialog alertDialog = builder.create();
- alertDialog.setView(view);
-
- Spinner spinnerLevel = view.findViewById(R.id.spinner_level);
- MaterialButton btnCancel = view.findViewById(R.id.btn_cancel);
- MaterialButton btnSave = view.findViewById(R.id.btn_save);
-
- String[] levels = {getString(R.string.select_level), "100L", "200L", "300L", "400L", "500L"};
- ArrayAdapter adapterLevels = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, levels);
-
- adapterLevels.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- spinnerLevel.setAdapter(adapterLevels);
-
- int selection = adapterLevels.getPosition(userLevel);
- spinnerLevel.setSelection(selection);
-
- btnCancel.setOnClickListener(v -> alertDialog.dismiss());
- btnSave.setOnClickListener(v -> {
- String name = tvName.getText().toString().trim();
- String school = tvSchool.getText().toString().trim();
- String department = tvDepartment.getText().toString().trim();
- String level = spinnerLevel.getSelectedItem().toString();
-
- if (!level.equals(getString(R.string.select_level))) {
- if (!level.equals(userLevel)) {
- User user = new User(name, school, department, level, profileImageBitmap);
- user.setId(USER_ID);
-
- mViewModel.updateUser(user);
- tvLevel.setText(level);
-
- alertDialog.dismiss();
- } else
- Toast.makeText(getContext(), "Level not changed", Toast.LENGTH_SHORT).show();
- } else
- Toast.makeText(getContext(), "Please select a level", Toast.LENGTH_SHORT).show();
- });
- alertDialog.show();
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/util/Repository.kt b/app/src/main/java/com/certified/notes/util/Repository.kt
index 7158e30..69e1510 100644
--- a/app/src/main/java/com/certified/notes/util/Repository.kt
+++ b/app/src/main/java/com/certified/notes/util/Repository.kt
@@ -6,12 +6,8 @@ import androidx.lifecycle.Transformations
import com.certified.notes.model.*
import com.certified.notes.room.NotesDao
import com.certified.notes.room.NotesDatabase
-import com.certified.notes.room.NotesDatabasekt
import java.util.*
-import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Executors
import kotlin.random.Random
class Repository(application: Application) {
@@ -28,13 +24,9 @@ class Repository(application: Application) {
val allCourseCreditPoints: LiveData>
val user: LiveData
- companion object {
- val executor: ExecutorService = Executors.newSingleThreadExecutor()
- }
-
init {
- val database = NotesDatabasekt.getInstance(application)
- noteDao = database!!.mNotesDao()
+ val database = NotesDatabase.getInstance(application)
+ noteDao = database.noteDao()
allNotes = noteDao.getAllNotes()
allCourses = noteDao.getAllCourses()
allTodos = noteDao.getAllTodos()
@@ -72,81 +64,81 @@ class Repository(application: Application) {
}
}
- fun insertNote(note: Note) {
- executor.execute { noteDao.insertNote(note) }
+ suspend fun insertNote(note: Note) {
+ noteDao.insertNote(note)
}
- fun insertCourse(course: Course) {
- executor.execute { noteDao.insertCourse(course) }
+ suspend fun insertCourse(course: Course) {
+ noteDao.insertCourse(course)
}
- fun insertTodo(todo: Todo) {
- executor.execute { noteDao.insertTodo(todo) }
+ suspend fun insertTodo(todo: Todo) {
+ noteDao.insertTodo(todo)
}
- fun insertBookMark(bookMark: BookMark) {
- executor.execute { noteDao.insertBookMark(bookMark) }
+ suspend fun insertBookMark(bookMark: BookMark) {
+ noteDao.insertBookMark(bookMark)
}
- fun updateNote(note: Note) {
- executor.execute { noteDao.updateNote(note) }
+ suspend fun updateNote(note: Note) {
+ noteDao.updateNote(note)
}
- fun updateCourse(course: Course) {
- executor.execute { noteDao.updateCourse(course) }
+ suspend fun updateCourse(course: Course) {
+ noteDao.updateCourse(course)
}
- fun updateTodo(todo: Todo) {
- executor.execute { noteDao.updateTodo(todo) }
+ suspend fun updateTodo(todo: Todo) {
+ noteDao.updateTodo(todo)
}
- fun updateBookMark(bookMark: BookMark) {
- executor.execute { noteDao.updateBookMark(bookMark) }
+ suspend fun updateBookMark(bookMark: BookMark) {
+ noteDao.updateBookMark(bookMark)
}
- fun updateUser(user: User) {
- executor.execute { noteDao.updateUser(user) }
+ suspend fun updateUser(user: User) {
+ noteDao.updateUser(user)
}
- fun deleteNote(note: Note) {
- executor.execute { noteDao.deleteNote(note) }
+ suspend fun deleteNote(note: Note) {
+ noteDao.deleteNote(note)
}
- fun deleteCourse(course: Course) {
- executor.execute { noteDao.deleteCourse(course) }
+ suspend fun deleteCourse(course: Course) {
+ noteDao.deleteCourse(course)
}
- fun deleteTodo(todo: Todo) {
- executor.execute { noteDao.deleteTodo(todo) }
+ suspend fun deleteTodo(todo: Todo) {
+ noteDao.deleteTodo(todo)
}
- fun deleteBookMark(bookMark: BookMark) {
- executor.execute { noteDao.deleteBookMark(bookMark) }
+ suspend fun deleteBookMark(bookMark: BookMark) {
+ noteDao.deleteBookMark(bookMark)
}
fun deleteAllNotes() {
- NotesDatabase.databaseWriteExecutor.execute { noteDao.deleteAllNotes() }
+ noteDao.deleteAllNotes()
}
fun deleteAllCourses() {
- NotesDatabase.databaseWriteExecutor.execute { noteDao.deleteAllCourses() }
+ noteDao.deleteAllCourses()
}
fun deleteAllTodos() {
- NotesDatabase.databaseWriteExecutor.execute { noteDao.deleteAllTodos() }
+ noteDao.deleteAllTodos()
}
fun deleteAllBookMarks() {
- NotesDatabase.databaseWriteExecutor.execute { noteDao.deleteAllBookMarks() }
+ noteDao.deleteAllBookMarks()
}
fun deleteCompletedTodos() {
- executor.execute { noteDao.deleteCompletedTodos() }
+ noteDao.deleteCompletedTodos()
}
fun getCourseCode(courseTitle: String): String {
return try {
- executor.submit { noteDao.getCourseCode(courseTitle) }.get()
+ noteDao.getCourseCode(courseTitle)
} catch (e: ExecutionException) {
e.printStackTrace()
""
@@ -158,7 +150,7 @@ class Repository(application: Application) {
fun getCourseTitle(courseCode: String): String {
return try {
- executor.submit { noteDao.getCourseTitle(courseCode) }.get()
+ noteDao.getCourseTitle(courseCode)
} catch (e: ExecutionException) {
e.printStackTrace()
""
@@ -170,7 +162,7 @@ class Repository(application: Application) {
fun deleteBookMarkedNote(noteId: Int) {
try {
- executor.submit { noteDao.deleteBookMarkedNote(noteId) }.get()
+ noteDao.deleteBookMarkedNote(noteId)
} catch (e: ExecutionException) {
e.printStackTrace()
} catch (e: InterruptedException) {
@@ -180,7 +172,7 @@ class Repository(application: Application) {
fun getBookMarkAt(noteId: Int): LiveData>? {
return try {
- executor.submit(Callable { noteDao.getBookMarkAt(noteId) }).get()
+ noteDao.getBookMarkAt(noteId)
} catch (e: ExecutionException) {
e.printStackTrace()
null
@@ -192,7 +184,7 @@ class Repository(application: Application) {
fun getNotesAt(courseCode: String): LiveData>? {
return try {
- executor.submit(Callable { noteDao.getNotesAt(courseCode) }).get()
+ noteDao.getNotesAt(courseCode)
} catch (e: ExecutionException) {
e.printStackTrace()
null
@@ -204,7 +196,7 @@ class Repository(application: Application) {
fun getDeletableNotes(noCourse: String): LiveData>? {
return try {
- executor.submit(Callable { noteDao.getDeletableNotes(noCourse) }).get()
+ noteDao.getDeletableNotes(noCourse)
} catch (e: ExecutionException) {
e.printStackTrace()
null
@@ -216,7 +208,7 @@ class Repository(application: Application) {
fun getDeletableBookmarks(noCourse: String): LiveData>? {
return try {
- executor.submit(Callable { noteDao.getDeletableBookmarks(noCourse) }).get()
+ noteDao.getDeletableBookmarks(noCourse)
} catch (e: ExecutionException) {
e.printStackTrace()
null
@@ -228,11 +220,7 @@ class Repository(application: Application) {
fun searchNotes(searchQuery: String?): LiveData?>? {
return try {
- executor.submit(Callable {
- noteDao.searchNotes(
- searchQuery!!
- )
- }).get()
+ noteDao.searchNotes(searchQuery)
} catch (e: ExecutionException) {
e.printStackTrace()
null
@@ -244,11 +232,7 @@ class Repository(application: Application) {
fun searchCourses(searchQuery: String?): LiveData?>? {
return try {
- executor.submit(Callable {
- noteDao.searchCourses(
- searchQuery
- )
- }).get()
+ noteDao.searchCourses(searchQuery)
} catch (e: ExecutionException) {
e.printStackTrace()
null
@@ -260,11 +244,7 @@ class Repository(application: Application) {
fun searchBookmarks(searchQuery: String?): LiveData?>? {
return try {
- executor.submit(Callable {
- noteDao.searchBookmarks(
- searchQuery
- )
- }).get()
+ noteDao.searchBookmarks(searchQuery)
} catch (e: ExecutionException) {
e.printStackTrace()
null
diff --git a/app/src/main/java/com/certified/notes/util/TestingPractice.kt b/app/src/main/java/com/certified/notes/util/TestingPractice.kt
new file mode 100644
index 0000000..57a375b
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/util/TestingPractice.kt
@@ -0,0 +1,11 @@
+package com.certified.notes.util
+
+import androidx.room.ColumnInfo
+import androidx.room.PrimaryKey
+
+class TestingPractice {
+
+ fun insertNote(courseCode: String, title: String,content: String) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/BookMarksFragment.kt b/app/src/main/java/com/certified/notes/view/BookMarks/BookMarksFragment.kt
similarity index 91%
rename from app/src/main/java/com/certified/notes/ui/BookMarksFragment.kt
rename to app/src/main/java/com/certified/notes/view/BookMarks/BookMarksFragment.kt
index 91addd2..2bb026e 100644
--- a/app/src/main/java/com/certified/notes/ui/BookMarksFragment.kt
+++ b/app/src/main/java/com/certified/notes/view/BookMarks/BookMarksFragment.kt
@@ -1,8 +1,7 @@
-package com.certified.notes.ui
+package com.certified.notes.view.BookMarks
import android.content.DialogInterface
import android.graphics.Canvas
-import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
@@ -15,6 +14,7 @@ import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
@@ -24,7 +24,6 @@ import com.certified.notes.adapters.BookMarkRecyclerAdapter
import com.certified.notes.adapters.BookMarkRecyclerAdapter.OnBookMarkClickedListener
import com.certified.notes.model.BookMark
import com.certified.notes.model.Note
-import com.certified.notes.room.NotesViewModel
import com.certified.notes.util.PreferenceKeys
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
@@ -34,7 +33,7 @@ import it.xabaras.android.recyclerview.swipedecorator.RecyclerViewSwipeDecorator
class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
private lateinit var recyclerBookMarks: RecyclerView
- private lateinit var viewModel: NotesViewModel
+ private lateinit var viewModel: BookMarksViewModel
private lateinit var ivBookMarkPopupMenu: ImageView
private lateinit var svSearchBookMark: SearchView
@@ -48,9 +47,7 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
recyclerBookMarks = view.findViewById(R.id.recycler_view_notes)
ivBookMarkPopupMenu = view.findViewById(R.id.iv_bookmark_popup_menu)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- svSearchBookMark = view.findViewById(R.id.sv_search_database)
- }
+ svSearchBookMark = view.findViewById(R.id.sv_search_database)
return view
}
@@ -58,7 +55,8 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- viewModel = NotesViewModel(requireActivity().application)
+ val viewModelFactory = BookMarksViewModelFactory(requireActivity().application)
+ viewModel = ViewModelProvider(this, viewModelFactory).get(BookMarksViewModel::class.java)
ivBookMarkPopupMenu.setOnClickListener(this::showPopupMenu)
init()
@@ -66,7 +64,7 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
private fun init() {
val bookMarkLayoutManager = LinearLayoutManager(requireContext())
- val bookMarkRecyclerAdapter = BookMarkRecyclerAdapter()
+ val bookMarkRecyclerAdapter by lazy { BookMarkRecyclerAdapter() }
viewModel.allBookMarks.observe(viewLifecycleOwner, bookMarkRecyclerAdapter::submitList)
recyclerBookMarks.adapter = bookMarkRecyclerAdapter
@@ -145,7 +143,7 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
}
}
} else {
- val note = Note("NIL", noteTitle, noteContent)
+ val note = Note( "NIL", noteTitle, noteContent)
note.id = bookmark.noteId
viewModel.updateNote(note)
viewModel.getBookMarkAt(bookmark.noteId)
@@ -153,8 +151,7 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
if (it != null) {
for (bookMark in it) {
val bookMark1 =
- BookMark(
- noteId,
+ BookMark( noteId,
"NIL",
noteTitle,
noteContent
@@ -261,25 +258,23 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
}).attachToRecyclerView(recyclerBookMarks)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- svSearchBookMark.isSubmitButtonEnabled
- svSearchBookMark.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
- override fun onQueryTextSubmit(query: String?): Boolean {
- if (query != null) {
- searchBookmarks(query, bookMarkRecyclerAdapter)
- }
- return true
+ svSearchBookMark.isSubmitButtonEnabled
+ svSearchBookMark.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+ override fun onQueryTextSubmit(query: String?): Boolean {
+ if (query != null) {
+ searchBookmarks(query, bookMarkRecyclerAdapter)
}
+ return true
+ }
- override fun onQueryTextChange(query: String?): Boolean {
- if (query != null) {
- searchBookmarks(query, bookMarkRecyclerAdapter)
- }
- return true
+ override fun onQueryTextChange(query: String?): Boolean {
+ if (query != null) {
+ searchBookmarks(query, bookMarkRecyclerAdapter)
}
+ return true
+ }
- })
- }
+ })
}
private fun searchBookmarks(query: String, bookMarkRecyclerAdapter: BookMarkRecyclerAdapter) {
@@ -308,6 +303,8 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
builder.setTitle(getString(R.string.delete))
builder.setMessage(getString(R.string.all_bookmark_delete_dialog_message))
builder.setIcon(R.drawable.ic_baseline_delete_24)
+ val alertDialog = builder.create()
+
builder.setPositiveButton(getString(R.string.yes)) { dialog: DialogInterface, _: Int ->
viewModel.deleteAllBookMarks()
@@ -329,7 +326,6 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
}
builder.setNegativeButton(getString(R.string.no)) { _, _ ->
- val alertDialog = builder.create()
alertDialog.setOnShowListener {
if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(
@@ -359,7 +355,7 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
)
}
}
- alertDialog.show()
}
+ alertDialog.show()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/view/BookMarks/BookMarksViewModel.kt b/app/src/main/java/com/certified/notes/view/BookMarks/BookMarksViewModel.kt
new file mode 100644
index 0000000..3c46f0e
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/BookMarks/BookMarksViewModel.kt
@@ -0,0 +1,61 @@
+package com.certified.notes.view.BookMarks
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.viewModelScope
+import com.certified.notes.model.BookMark
+import com.certified.notes.model.Course
+import com.certified.notes.model.Note
+import com.certified.notes.util.Repository
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+class BookMarksViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val repository = Repository(application)
+
+ private val _allBookMarks: LiveData> = repository.allBookMarks
+ val allBookMarks: LiveData>
+ get() = _allBookMarks
+
+ val allCourses: LiveData> = repository.allCourses
+
+ fun updateBookMark(bookMark: BookMark) {
+ viewModelScope.launch(Dispatchers.IO) { repository.updateBookMark(bookMark) }
+ }
+
+ fun updateNote(note: Note) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateNote(note)
+ }
+ }
+
+ fun deleteBookMark(bookMark: BookMark) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.deleteBookMark(bookMark)
+ }
+ }
+
+ fun deleteAllBookMarks() {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.deleteAllBookMarks()
+ }
+ }
+
+ fun getBookMarkAt(noteId: Int): LiveData>? {
+ return repository.getBookMarkAt(noteId)
+ }
+
+ fun getCourseCode(courseTitle: String): String {
+ return repository.getCourseCode(courseTitle)
+ }
+
+ fun getCourseTitle(courseCode: String): String {
+ return repository.getCourseTitle(courseCode)
+ }
+
+ fun searchBookmarks(searchQuery: String?): LiveData?>? {
+ return repository.searchBookmarks(searchQuery)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/view/BookMarks/BookMarksViewModelFactory.kt b/app/src/main/java/com/certified/notes/view/BookMarks/BookMarksViewModelFactory.kt
new file mode 100644
index 0000000..2021619
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/BookMarks/BookMarksViewModelFactory.kt
@@ -0,0 +1,13 @@
+package com.certified.notes.view.BookMarks
+
+import android.app.Application
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+
+class BookMarksViewModelFactory(val application: Application): ViewModelProvider.Factory {
+ override fun create(modelClass: Class): T {
+ if (modelClass.isAssignableFrom(BookMarksViewModel::class.java))
+ return BookMarksViewModel(application) as T
+ throw IllegalArgumentException("Unknown ViewModel class")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/CoursesFragmentKt.kt b/app/src/main/java/com/certified/notes/view/Courses/CoursesFragmentKt.kt
similarity index 91%
rename from app/src/main/java/com/certified/notes/ui/CoursesFragmentKt.kt
rename to app/src/main/java/com/certified/notes/view/Courses/CoursesFragmentKt.kt
index 3ba2b50..3b4199a 100644
--- a/app/src/main/java/com/certified/notes/ui/CoursesFragmentKt.kt
+++ b/app/src/main/java/com/certified/notes/view/Courses/CoursesFragmentKt.kt
@@ -1,6 +1,5 @@
-package com.certified.notes.ui
+package com.certified.notes.view.Courses
-import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@@ -12,8 +11,10 @@ import android.widget.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.widget.SearchView
+import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
@@ -23,7 +24,6 @@ import com.certified.notes.adapters.HomeNoteRecyclerAdapter
import com.certified.notes.model.BookMark
import com.certified.notes.model.Course
import com.certified.notes.model.Note
-import com.certified.notes.room.NotesViewModel
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -37,7 +37,7 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
}
private lateinit var recyclerCourses: RecyclerView
- private lateinit var viewModel: NotesViewModel
+ private lateinit var viewModel: CoursesViewModel
private lateinit var ivCoursePopupMenu: ImageView
private lateinit var svSearchCourses: SearchView
@@ -51,9 +51,7 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
recyclerCourses = view.findViewById(R.id.recycler_view_courses)
ivCoursePopupMenu = view.findViewById(R.id.iv_course_popup_menu)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- svSearchCourses = view.findViewById(R.id.sv_search_database)
- }
+ svSearchCourses = view.findViewById(R.id.sv_search_database)
return view
}
@@ -61,7 +59,8 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- viewModel = NotesViewModel(requireActivity().application)
+ val viewModelFactory = CoursesViewModelFactory(requireActivity().application)
+ viewModel = ViewModelProvider(this, viewModelFactory).get(CoursesViewModel::class.java)
ivCoursePopupMenu.setOnClickListener(this::showPopupMenu)
init()
@@ -106,27 +105,27 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
}
})
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- svSearchCourses.isSubmitButtonEnabled
- svSearchCourses.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
- override fun onQueryTextSubmit(query: String?): Boolean {
- if (query != null)
- searchCourses(query, courseRecyclerAdapter)
- return true
- }
-
- override fun onQueryTextChange(query: String?): Boolean {
- if (query != null)
- searchCourses(query, courseRecyclerAdapter)
- return true
- }
+ svSearchCourses.isSubmitButtonEnabled
+ svSearchCourses.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+ override fun onQueryTextSubmit(query: String?): Boolean {
+ if (query != null)
+ searchCourses(query, courseRecyclerAdapter)
+ return true
+ }
- })
- }
+ override fun onQueryTextChange(query: String?): Boolean {
+ if (query != null)
+ searchCourses(query, courseRecyclerAdapter)
+ return true
+ }
+ })
}
private fun launchRelatedNotesDialog(course: Course) {
- val view = layoutInflater.inflate(R.layout.dialog_related_notes, null)
+ val view = layoutInflater.inflate(
+ R.layout.dialog_related_notes,
+ ConstraintLayout(requireContext())
+ )
val bottomSheetDialog = BottomSheetDialog(requireContext())
val recyclerViewRelatedNotes: RecyclerView =
view.findViewById(R.id.recycler_view_related_notes)
@@ -162,7 +161,10 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
override fun onNoteClicked(note: Note) {
bottomSheetDialog.dismiss()
- val view1 = layoutInflater.inflate(R.layout.dialog_new_note, null)
+ val view1 = layoutInflater.inflate(
+ R.layout.dialog_new_note,
+ ConstraintLayout(requireContext())
+ )
val bottomSheetDialog1 = BottomSheetDialog(
requireContext(),
R.style.BottomSheetDialogTheme
@@ -224,7 +226,12 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
val noteId = note1.id
for (bookMark in bookMarks) {
val bookMark1 =
- BookMark(noteId, courseCode, noteTitle, noteContent)
+ BookMark(
+ noteId,
+ courseCode,
+ noteTitle,
+ noteContent
+ )
bookMark1.id = bookMark.id
viewModel.updateBookMark(bookMark1)
}
@@ -258,7 +265,8 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
}
private fun launchEditCourseDialog(course: Course) {
- val view = layoutInflater.inflate(R.layout.dialog_new_course, null)
+ val view =
+ layoutInflater.inflate(R.layout.dialog_new_course, ConstraintLayout(requireContext()))
val bottomSheetDialog = BottomSheetDialog(requireContext())
val tvCourseDialogTitle: MaterialTextView = view.findViewById(R.id.tv_course_dialog_title)
@@ -304,7 +312,7 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
for (note in notes) {
val noteTitle = note.title
val noteContent = note.content
- val note1 = Note(courseCode, noteTitle, noteContent)
+ val note1 = Note( courseCode, noteTitle, noteContent)
note1.id = note.id
viewModel.updateNote(note1)
diff --git a/app/src/main/java/com/certified/notes/view/Courses/CoursesViewModel.kt b/app/src/main/java/com/certified/notes/view/Courses/CoursesViewModel.kt
new file mode 100644
index 0000000..da62b17
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Courses/CoursesViewModel.kt
@@ -0,0 +1,87 @@
+package com.certified.notes.view.Courses
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.viewModelScope
+import com.certified.notes.model.BookMark
+import com.certified.notes.model.Course
+import com.certified.notes.model.Note
+import com.certified.notes.util.Repository
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+class CoursesViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val repository = Repository(application)
+
+ val allCourses: LiveData> = repository.allCourses
+
+ fun updateNote(note: Note) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateNote(note)
+ }
+ }
+
+ fun updateCourse(course: Course) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateCourse(course)
+ }
+ }
+
+ fun updateBookMark(bookMark: BookMark) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateBookMark(bookMark)
+ }
+ }
+
+ fun deleteNote(note: Note) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.deleteNote(note)
+ }
+ }
+
+ fun deleteCourse(course: Course) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.deleteCourse(course)
+ }
+ }
+
+ fun deleteBookMark(bookMark: BookMark) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.deleteBookMark(bookMark)
+ }
+ }
+
+ fun deleteAllCourses() {
+ repository.deleteAllCourses()
+ }
+
+ fun getNotesAt(courseCode: String): LiveData>? {
+ return repository.getNotesAt(courseCode)
+ }
+
+ fun getCourseCode(courseTitle: String): String {
+ return repository.getCourseCode(courseTitle)
+ }
+
+ fun getCourseTitle(courseCode: String): String {
+ return repository.getCourseTitle(courseCode)
+ }
+
+ fun getBookMarkAt(noteId: Int): LiveData>? {
+ return repository.getBookMarkAt(noteId)
+ }
+
+ fun getDeletableNotes(noCourse: String): LiveData>? {
+ return repository.getDeletableNotes(noCourse)
+ }
+
+ fun getDeletableBookmarks(noCourse: String): LiveData>? {
+ return repository.getDeletableBookmarks(noCourse)
+ }
+
+ fun searchCourses(searchQuery: String?): LiveData?>? {
+ return repository.searchCourses(searchQuery)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/view/Courses/CoursesViewModelFactory.kt b/app/src/main/java/com/certified/notes/view/Courses/CoursesViewModelFactory.kt
new file mode 100644
index 0000000..b0edbfb
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Courses/CoursesViewModelFactory.kt
@@ -0,0 +1,13 @@
+package com.certified.notes.view.Courses
+
+import android.app.Application
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+
+class CoursesViewModelFactory(val application: Application): ViewModelProvider.Factory {
+ override fun create(modelClass: Class): T {
+ if (modelClass.isAssignableFrom(CoursesViewModel::class.java))
+ return CoursesViewModel(application) as T
+ throw IllegalArgumentException("Unknown ViewModel class")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/HomeFragment.kt b/app/src/main/java/com/certified/notes/view/Home/HomeFragment.kt
similarity index 90%
rename from app/src/main/java/com/certified/notes/ui/HomeFragment.kt
rename to app/src/main/java/com/certified/notes/view/Home/HomeFragment.kt
index 17e8d34..77f6c96 100644
--- a/app/src/main/java/com/certified/notes/ui/HomeFragment.kt
+++ b/app/src/main/java/com/certified/notes/view/Home/HomeFragment.kt
@@ -1,4 +1,4 @@
-package com.certified.notes.ui
+package com.certified.notes.view.Home
import android.os.Bundle
import android.view.LayoutInflater
@@ -12,6 +12,7 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.preference.PreferenceManager
@@ -23,7 +24,6 @@ import com.certified.notes.adapters.HomeNoteRecyclerAdapter
import com.certified.notes.adapters.TodoRecyclerAdapter
import com.certified.notes.model.Note
import com.certified.notes.model.Todo
-import com.certified.notes.room.NotesViewModel
import com.certified.notes.util.PreferenceKeys
import com.github.captain_miao.optroundcardview.OptRoundCardView
import com.google.android.material.bottomsheet.BottomSheetDialog
@@ -46,7 +46,7 @@ class HomeFragment : Fragment(), View.OnClickListener, PopupMenu.OnMenuItemClick
private lateinit var btnShowAllCourses: MaterialButton
private lateinit var ivTodoPopupMenu: ImageView
private lateinit var navController: NavController
- private lateinit var viewModel: NotesViewModel
+ private lateinit var viewModel: HomeViewModel
private lateinit var cardView: MaterialCardView
private lateinit var todoRecyclerAdapter: TodoRecyclerAdapter
@@ -79,7 +79,9 @@ class HomeFragment : Fragment(), View.OnClickListener, PopupMenu.OnMenuItemClick
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
- viewModel = NotesViewModel(requireActivity().application)
+
+ val viewModelFactory = HomeViewModelFactory(requireActivity().application)
+ viewModel = ViewModelProvider(this, viewModelFactory).get(HomeViewModel::class.java)
activity?.findViewById(R.id.optRoundCardView2)?.visibility = View.VISIBLE
activity?.findViewById(R.id.fab)?.visibility = View.VISIBLE
@@ -259,31 +261,35 @@ class HomeFragment : Fragment(), View.OnClickListener, PopupMenu.OnMenuItemClick
val alertDialog = builder.create()
alertDialog.setOnShowListener {
if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
- alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE).setTextColor(
- ContextCompat.getColor(
- requireContext(),
- R.color.black
+ alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE)
+ .setTextColor(
+ ContextCompat.getColor(
+ requireContext(),
+ R.color.black
+ )
)
- )
- alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEGATIVE).setTextColor(
- ContextCompat.getColor(
- requireContext(),
- R.color.black
+ alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEGATIVE)
+ .setTextColor(
+ ContextCompat.getColor(
+ requireContext(),
+ R.color.black
+ )
)
- )
} else {
- alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE).setTextColor(
- ContextCompat.getColor(
- requireContext(),
- R.color.red
+ alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE)
+ .setTextColor(
+ ContextCompat.getColor(
+ requireContext(),
+ R.color.red
+ )
)
- )
- alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEGATIVE).setTextColor(
- ContextCompat.getColor(
- requireContext(),
- R.color.red
+ alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEGATIVE)
+ .setTextColor(
+ ContextCompat.getColor(
+ requireContext(),
+ R.color.red
+ )
)
- )
}
}
alertDialog.show()
diff --git a/app/src/main/java/com/certified/notes/view/Home/HomeViewModel.kt b/app/src/main/java/com/certified/notes/view/Home/HomeViewModel.kt
new file mode 100644
index 0000000..f3ee188
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Home/HomeViewModel.kt
@@ -0,0 +1,41 @@
+package com.certified.notes.view.Home
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.viewModelScope
+import com.certified.notes.model.Course
+import com.certified.notes.model.Note
+import com.certified.notes.model.Todo
+import com.certified.notes.util.Repository
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+class HomeViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val repository = Repository(application)
+
+ val randomNotes: LiveData> = repository.randomNotes
+ val randomCourses: LiveData> = repository.randomCourses
+ val allTodos: LiveData> = repository.allTodos
+
+ fun updateTodo(todo: Todo) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateTodo(todo)
+ }
+ }
+
+ fun deleteTodo(todo: Todo) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.deleteTodo(todo)
+ }
+ }
+
+ fun deleteAllTodos() {
+ repository.deleteAllTodos()
+ }
+
+ fun deleteCompletedTodos() {
+ repository.deleteCompletedTodos()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/view/Home/HomeViewModelFactory.kt b/app/src/main/java/com/certified/notes/view/Home/HomeViewModelFactory.kt
new file mode 100644
index 0000000..d853aa3
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Home/HomeViewModelFactory.kt
@@ -0,0 +1,14 @@
+package com.certified.notes.view.Home
+
+import android.app.Application
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import java.lang.IllegalArgumentException
+
+class HomeViewModelFactory(val application: Application): ViewModelProvider.Factory {
+ override fun create(modelClass: Class): T {
+ if (modelClass.isAssignableFrom(HomeViewModel::class.java))
+ return HomeViewModel(application) as T
+ throw IllegalArgumentException("Unknown ViewModel class")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/MainActivity.kt b/app/src/main/java/com/certified/notes/view/Main/MainActivity.kt
similarity index 95%
rename from app/src/main/java/com/certified/notes/ui/MainActivity.kt
rename to app/src/main/java/com/certified/notes/view/Main/MainActivity.kt
index 240458b..b0aefbd 100644
--- a/app/src/main/java/com/certified/notes/ui/MainActivity.kt
+++ b/app/src/main/java/com/certified/notes/view/Main/MainActivity.kt
@@ -1,4 +1,4 @@
-package com.certified.notes.ui
+package com.certified.notes.view.Main
import android.os.Bundle
import android.view.LayoutInflater
@@ -6,7 +6,7 @@ import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
-import androidx.lifecycle.Observer
+import androidx.constraintlayout.widget.ConstraintLayout
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.ui.NavigationUI
@@ -15,7 +15,6 @@ import com.certified.notes.R
import com.certified.notes.model.Course
import com.certified.notes.model.Note
import com.certified.notes.model.Todo
-import com.certified.notes.room.NotesViewModel
import com.certified.notes.util.PreferenceKeys
import com.github.captain_miao.optroundcardview.OptRoundCardView
import com.google.android.material.bottomnavigation.BottomNavigationView
@@ -27,7 +26,7 @@ import com.shawnlin.numberpicker.NumberPicker
class MainActivity : AppCompatActivity(), View.OnClickListener {
- private lateinit var notesViewModel: NotesViewModel
+ private lateinit var notesViewModel: MainActivityViewModel
private lateinit var tvFabTodoTitle: TextView
private lateinit var tvFabNoteTitle: TextView
@@ -52,7 +51,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
isDarkModeEnabled()
// createNotificationChannel()
- notesViewModel = NotesViewModel(application)
+ notesViewModel = MainActivityViewModel(application)
navController = Navigation.findNavController(this, R.id.fragment)
bottomNavigationView = findViewById(R.id.smoothBottomBar)
@@ -155,7 +154,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
private fun launchCourseDialog() {
val inflater: LayoutInflater = layoutInflater
- val view = inflater.inflate(R.layout.dialog_new_course, null)
+ val view = inflater.inflate(R.layout.dialog_new_course, ConstraintLayout(this))
val bottomSheetDialog = BottomSheetDialog(this, R.style.BottomSheetDialogTheme)
val tvCourseDialogTitle: MaterialTextView = view.findViewById(R.id.tv_course_dialog_title)
@@ -196,7 +195,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
private fun launchTodoDialog() {
val inflater = layoutInflater
- val view = inflater.inflate(R.layout.dialog_new_todo, null)
+ val view = inflater.inflate(R.layout.dialog_new_todo, ConstraintLayout(this))
val bottomSheetDialog = BottomSheetDialog(this, R.style.BottomSheetDialogTheme)
val tvTodoDialogTitle: MaterialTextView = view.findViewById(R.id.tv_todo_dialog_title)
@@ -221,7 +220,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
private fun launchNoteDialog() {
val inflater = layoutInflater
- val view = inflater.inflate(R.layout.dialog_new_note, null)
+ val view = inflater.inflate(R.layout.dialog_new_note, ConstraintLayout(this))
val bottomSheetDialog = BottomSheetDialog(this, R.style.BottomSheetDialogTheme)
val spinnerCourses: Spinner = view.findViewById(R.id.spinner_courses)
@@ -233,7 +232,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
val courseList = arrayListOf()
val adapterCourses = ArrayAdapter(this, android.R.layout.simple_spinner_item, courseList)
- notesViewModel.allCourses.observe(this, Observer { courses: List ->
+ notesViewModel.allCourses.observe(this, { courses: List ->
courseList.add(getString(R.string.select_a_course))
courseList.add(getString(R.string.no_course))
for (course in courses) {
diff --git a/app/src/main/java/com/certified/notes/view/Main/MainActivityViewModel.kt b/app/src/main/java/com/certified/notes/view/Main/MainActivityViewModel.kt
new file mode 100644
index 0000000..19820e0
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Main/MainActivityViewModel.kt
@@ -0,0 +1,67 @@
+package com.certified.notes.view.Main
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.viewModelScope
+import com.certified.notes.model.*
+import com.certified.notes.util.Repository
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+class MainActivityViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val repository = Repository(application)
+
+ val allCourses: LiveData> = repository.allCourses
+ val allNoteIds: LiveData> = repository.allNoteIds
+ val allCourseUnits: LiveData> = repository.allCourseUnits
+ val allCourseCreditPoints: LiveData> = repository.allCourseCreditPoints
+ val user: LiveData = repository.user
+
+ fun insertNote(note: Note) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.insertNote(note)
+ }
+ }
+
+ fun insertCourse(course: Course) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.insertCourse(course)
+ }
+ }
+
+ fun insertTodo(todo: Todo) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.insertTodo(todo)
+ }
+ }
+
+ fun updateNote(note: Note) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateNote(note)
+ }
+ }
+
+ fun updateCourse(course: Course) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateCourse(course)
+ }
+ }
+
+ fun deleteAllCourses() {
+ repository.deleteAllCourses()
+ }
+
+ fun getCourseCode(courseTitle: String): String {
+ return repository.getCourseCode(courseTitle)
+ }
+
+ fun getCourseTitle(courseCode: String): String {
+ return repository.getCourseTitle(courseCode)
+ }
+
+ fun getBookMarkAt(noteId: Int): LiveData>? {
+ return repository.getBookMarkAt(noteId)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/NotesFragmentKt.kt b/app/src/main/java/com/certified/notes/view/Notes/NotesFragment.kt
similarity index 87%
rename from app/src/main/java/com/certified/notes/ui/NotesFragmentKt.kt
rename to app/src/main/java/com/certified/notes/view/Notes/NotesFragment.kt
index 26d2cd1..30e310e 100644
--- a/app/src/main/java/com/certified/notes/ui/NotesFragmentKt.kt
+++ b/app/src/main/java/com/certified/notes/view/Notes/NotesFragment.kt
@@ -1,7 +1,6 @@
-package com.certified.notes.ui
+package com.certified.notes.view.Notes
import android.content.SharedPreferences
-import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
@@ -15,15 +14,14 @@ import androidx.appcompat.widget.SearchView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.ItemTouchHelper
-import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.certified.notes.R
import com.certified.notes.adapters.NoteRecyclerAdapter
import com.certified.notes.model.BookMark
import com.certified.notes.model.Note
-import com.certified.notes.room.NotesViewModel
import com.certified.notes.util.PreferenceKeys
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
@@ -31,7 +29,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textview.MaterialTextView
import io.sulek.ssml.SSMLLinearLayoutManager
-class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
+class NotesFragment : Fragment(), PopupMenu.OnMenuItemClickListener {
private lateinit var recyclerNotes: RecyclerView
private lateinit var viewModel: NotesViewModel
@@ -52,8 +50,7 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
recyclerNotes = view.findViewById(R.id.recycler_view_notes)
ivNotePopupMenu = view.findViewById(R.id.iv_note_popup_menu)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
- svSearchNotes = view.findViewById(R.id.sv_search_database)
+ svSearchNotes = view.findViewById(R.id.sv_search_database)
return view
}
@@ -61,7 +58,8 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- viewModel = NotesViewModel(requireActivity().application)
+ val viewModelFactory = NotesViewModelFactory(requireActivity().application)
+ viewModel = ViewModelProvider(this, viewModelFactory).get(NotesViewModel::class.java)
preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
ivNotePopupMenu.setOnClickListener(this::showPopupMenu)
@@ -73,8 +71,8 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
}
private fun init() {
- val noteLayoutManager = LinearLayoutManager(requireContext())
- val noteRecyclerAdapter = NoteRecyclerAdapter(requireContext())
+// val noteLayoutManager = LinearLayoutManager(requireContext())
+ val noteRecyclerAdapter by lazy { NoteRecyclerAdapter(requireContext()) }
viewModel.allNotes.observe(viewLifecycleOwner, noteRecyclerAdapter::submitList)
recyclerNotes.adapter = noteRecyclerAdapter
@@ -97,7 +95,7 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
noteRecyclerAdapter.setOnNoteClickedListener(object :
NoteRecyclerAdapter.OnNoteClickedListener {
- override fun onNoteClick(note: Note?) {
+ override fun onNoteClick(note: Note) {
val view = layoutInflater.inflate(
R.layout.dialog_new_note,
ConstraintLayout(requireContext())
@@ -116,10 +114,18 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
spinnerCourses.adapter = adapterCourses
tvNoteDialogTitle.text = getString(R.string.edit_note)
- etNoteTitle.setText(note?.title)
- etNoteContent.setText(note?.content)
- val coursePosition = if (note?.courseCode != getString(R.string.nil))
- adapterCourses.getPosition(note?.courseCode?.let { viewModel.getCourseTitle(it) })
+ etNoteTitle.setText(note.title)
+ etNoteContent.setText(note.content)
+
+// val coursePosition: Int = if (note.courseCode != getString(R.string.nil)) {
+// viewModel.getCourseTitle(note.courseCode.let { it })?.observe(viewLifecycleOwner) {
+// adapterCourses.getPosition(it)
+// }
+// }
+// else 1
+
+ val coursePosition = if (note.courseCode != getString(R.string.nil))
+ adapterCourses.getPosition(note.courseCode.let { viewModel.getCourseTitle(it) })
else 1
spinnerCourses.setSelection(coursePosition)
@@ -137,9 +143,9 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
if (noteTitle.isNotEmpty() && noteContent.isNotEmpty()) {
if (courseTitle != getString(R.string.select_a_course)) {
// if (courseTitle != getString(R.string.no_course)) {
- if (courseCode != note?.courseCode || noteTitle != note.title || noteContent != note.content) {
+ if (courseCode != note.courseCode || noteTitle != note.title || noteContent != note.content) {
val note1 = Note(courseCode, noteTitle, noteContent)
- note1.id = note!!.id
+ note1.id = note.id
viewModel.updateNote(note1)
viewModel.getBookMarkAt(note.id)
?.observe(viewLifecycleOwner) { bookMarks ->
@@ -222,7 +228,8 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
builder.setTitle(getString(R.string.delete))
builder.setMessage(getString(R.string.note_delete_dialog_message))
builder.setPositiveButton(getString(R.string.delete)) { dialog1, _ ->
- val note = noteRecyclerAdapter.getNoteAt(viewHolder.adapterPosition)
+ val note =
+ noteRecyclerAdapter.getNoteAt(viewHolder.absoluteAdapterPosition)
note?.let { viewModel.deleteNote(it) }
note?.id?.let { viewModel.deleteBookMarkedNote(it) }
@@ -272,13 +279,13 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
}
ItemTouchHelper.RIGHT -> {
- val note = noteRecyclerAdapter.getNoteAt(viewHolder.adapterPosition)
+ val note = noteRecyclerAdapter.getNoteAt(viewHolder.absoluteAdapterPosition)
if (note != null) {
val noteId = note.id
val courseCode = note.courseCode
val noteTitle = note.title
val noteContent = note.content
- val bookMark = BookMark(noteId, courseCode!!, noteTitle, noteContent!!)
+ val bookMark = BookMark(noteId, courseCode, noteTitle, noteContent!!)
viewModel.getBookMarkAt(noteId)
?.observe(viewLifecycleOwner) { bookMarks ->
@@ -296,13 +303,23 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
}
}
}).attachToRecyclerView(recyclerNotes)
- }
- private fun showPopupMenu(view: View) {
- val menu = PopupMenu(requireContext(), view)
- menu.inflate(R.menu.note_menu)
- menu.setOnMenuItemClickListener(this)
- menu.show()
+ svSearchNotes.isSubmitButtonEnabled
+ svSearchNotes.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+ override fun onQueryTextSubmit(query: String?): Boolean {
+ if (query != null) {
+ searchNotes(query, noteRecyclerAdapter)
+ }
+ return true
+ }
+
+ override fun onQueryTextChange(query: String?): Boolean {
+ if (query != null) {
+ searchNotes(query, noteRecyclerAdapter)
+ }
+ return true
+ }
+ })
}
private fun searchNotes(query: String, noteRecyclerAdapter: NoteRecyclerAdapter) {
@@ -311,10 +328,17 @@ class NotesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener {
?.observe(viewLifecycleOwner, noteRecyclerAdapter::submitList)
}
+ private fun showPopupMenu(view: View) {
+ val menu = PopupMenu(requireContext(), view)
+ menu.inflate(R.menu.note_menu)
+ menu.setOnMenuItemClickListener(this)
+ menu.show()
+ }
+
private fun launchDeleteDialog() {
val builder = MaterialAlertDialogBuilder(requireContext())
builder.setTitle(getString(R.string.delete))
- builder.setMessage(getString(R.string.note_delete_dialog_message))
+ builder.setMessage(getString(R.string.all_note_delete_dialog_message))
builder.setIcon(R.drawable.ic_baseline_delete_24)
builder.setPositiveButton(getString(R.string.yes)) { dialog, _ ->
viewModel.deleteAllNotes()
diff --git a/app/src/main/java/com/certified/notes/view/Notes/NotesViewModel.kt b/app/src/main/java/com/certified/notes/view/Notes/NotesViewModel.kt
new file mode 100644
index 0000000..36ee9b7
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Notes/NotesViewModel.kt
@@ -0,0 +1,71 @@
+package com.certified.notes.view.Notes
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.viewModelScope
+import com.certified.notes.model.BookMark
+import com.certified.notes.model.Course
+import com.certified.notes.model.Note
+import com.certified.notes.util.Repository
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+class NotesViewModel(application: Application) : AndroidViewModel(application) {
+ private val repository = Repository(application)
+
+ val allNotes: LiveData> = repository.allNotes
+ val allCourses: LiveData> = repository.allCourses
+
+ fun insertBookMark(bookMark: BookMark) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.insertBookMark(bookMark)
+ }
+ }
+
+ fun updateNote(note: Note) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateNote(note)
+ }
+ }
+
+ fun updateBookMark(bookMark: BookMark) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateBookMark(bookMark)
+ }
+ }
+
+ fun deleteNote(note: Note) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.deleteNote(note)
+ }
+ }
+
+ fun deleteAllNotes() {
+ repository.deleteAllNotes()
+ }
+
+ fun deleteAllBookMarks() {
+ repository.deleteAllBookMarks()
+ }
+
+ fun deleteBookMarkedNote(noteId: Int) {
+ repository.deleteBookMarkedNote(noteId)
+ }
+
+ fun getCourseCode(courseTitle: String): String {
+ return repository.getCourseCode(courseTitle)
+ }
+
+ fun getCourseTitle(courseCode: String): String {
+ return repository.getCourseTitle(courseCode)
+ }
+
+ fun getBookMarkAt(noteId: Int): LiveData>? {
+ return repository.getBookMarkAt(noteId)
+ }
+
+ fun searchNotes(searchQuery: String?): LiveData?>? {
+ return repository.searchNotes(searchQuery)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/view/Notes/NotesViewModelFactory.kt b/app/src/main/java/com/certified/notes/view/Notes/NotesViewModelFactory.kt
new file mode 100644
index 0000000..6516b02
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Notes/NotesViewModelFactory.kt
@@ -0,0 +1,14 @@
+package com.certified.notes.view.Notes
+
+import android.app.Application
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import java.lang.IllegalArgumentException
+
+class NotesViewModelFactory(val application: Application): ViewModelProvider.Factory {
+ override fun create(modelClass: Class): T {
+ if (modelClass.isAssignableFrom(NotesViewModel::class.java))
+ return NotesViewModel(application) as T
+ throw IllegalArgumentException("Unknown ViewModel class")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/OnboardingFragment.kt b/app/src/main/java/com/certified/notes/view/OnboardingFragment.kt
similarity index 95%
rename from app/src/main/java/com/certified/notes/ui/OnboardingFragment.kt
rename to app/src/main/java/com/certified/notes/view/OnboardingFragment.kt
index dd37648..9d92e40 100644
--- a/app/src/main/java/com/certified/notes/ui/OnboardingFragment.kt
+++ b/app/src/main/java/com/certified/notes/view/OnboardingFragment.kt
@@ -1,4 +1,4 @@
-package com.certified.notes.ui
+package com.certified.notes.view
import android.content.SharedPreferences
import android.os.Bundle
@@ -15,9 +15,7 @@ import com.certified.notes.R
import com.certified.notes.adapters.ViewPagerAdapter
import com.certified.notes.model.SliderItem
import com.certified.notes.util.PreferenceKeys
-import com.github.captain_miao.optroundcardview.OptRoundCardView
import com.google.android.material.button.MaterialButton
-import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.rd.PageIndicatorView
class OnboardingFragment : Fragment() {
diff --git a/app/src/main/java/com/certified/notes/view/Profile/ProfileFragment.kt b/app/src/main/java/com/certified/notes/view/Profile/ProfileFragment.kt
new file mode 100644
index 0000000..d88eb5e
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Profile/ProfileFragment.kt
@@ -0,0 +1,425 @@
+package com.certified.notes.view.Profile
+
+import android.app.Activity
+import android.content.ActivityNotFoundException
+import android.content.DialogInterface
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.os.Bundle
+import android.provider.MediaStore
+import android.text.TextUtils.isEmpty
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ArrayAdapter
+import android.widget.Spinner
+import android.widget.TextView
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatDelegate
+import androidx.appcompat.content.res.AppCompatResources
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.Group
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import androidx.navigation.NavController
+import androidx.navigation.Navigation
+import androidx.preference.PreferenceManager
+import com.bumptech.glide.Glide
+import com.certified.notes.R
+import com.certified.notes.model.User
+import com.certified.notes.util.PreferenceKeys
+import com.github.captain_miao.optroundcardview.OptRoundCardView
+import com.google.android.material.bottomsheet.BottomSheetDialog
+import com.google.android.material.button.MaterialButton
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.google.android.material.floatingactionbutton.FloatingActionButton
+import com.google.android.material.switchmaterial.SwitchMaterial
+import com.google.android.material.textfield.TextInputEditText
+import com.google.android.material.textfield.TextInputLayout
+import com.google.android.material.textview.MaterialTextView
+import de.hdodenhof.circleimageview.CircleImageView
+import java.io.FileNotFoundException
+
+class ProfileFragment : Fragment(), View.OnClickListener {
+
+ private lateinit var viewModel: ProfileViewModel
+ private lateinit var mNavController: NavController
+
+ private lateinit var groupName: Group
+ private lateinit var groupSchool: Group
+ private lateinit var groupDepartment: Group
+ private lateinit var groupLevel: Group
+
+ private lateinit var tvName: TextView
+ private lateinit var tvSchool: TextView
+ private lateinit var tvDepartment: TextView
+ private lateinit var tvLevel: TextView
+
+ private lateinit var profileImage: CircleImageView
+ private lateinit var switchDarkMode: SwitchMaterial
+
+ private lateinit var fabChangeProfilePicture: FloatingActionButton
+ private lateinit var fabSettings: FloatingActionButton
+
+ private lateinit var userName: String
+ private lateinit var userSchool: String
+ private lateinit var userDepartment: String
+ private lateinit var userLevel: String
+ private var profileImageBitmap: Bitmap? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ val view = inflater.inflate(R.layout.fragment_profile, container, false)
+
+ groupName = view.findViewById(R.id.group_edit_name)
+ groupSchool = view.findViewById(R.id.group_edit_school)
+ groupDepartment = view.findViewById(R.id.group_edit_department)
+ groupLevel = view.findViewById(R.id.group_edit_level)
+
+ tvName = view.findViewById(R.id.tv_name)
+ tvSchool = view.findViewById(R.id.tv_school)
+ tvDepartment = view.findViewById(R.id.tv_department)
+ tvLevel = view.findViewById(R.id.tv_level)
+
+ profileImage = view.findViewById(R.id.profile_image)
+
+ fabChangeProfilePicture = view.findViewById(R.id.fab_change_profile_picture)
+ fabSettings = view.findViewById(R.id.fab_settings)
+
+ switchDarkMode = view.findViewById(R.id.switch_dark_mode)
+
+ return view
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ val viewModelFactory = ProfileViewModelFactory(requireActivity().application)
+ viewModel = ViewModelProvider(this, viewModelFactory).get(ProfileViewModel::class.java)
+ mNavController = Navigation.findNavController(view)
+
+ groupName.setOnClickListener(this)
+ groupSchool.setOnClickListener(this)
+ groupDepartment.setOnClickListener(this)
+ groupLevel.setOnClickListener(this)
+
+ profileImage.setOnClickListener(this)
+
+ fabChangeProfilePicture.setOnClickListener(this)
+ fabSettings.setOnClickListener(this)
+
+ viewModel.user.observe(viewLifecycleOwner) { user ->
+ if (user != null) {
+ userName = user.name
+ userSchool = user.school
+ userDepartment = user.department
+ userLevel = user.level
+ profileImageBitmap = user.profileImage
+
+ tvName.text = userName
+ tvSchool.text = userSchool
+ tvDepartment.text = userDepartment
+ tvLevel.text = userLevel
+
+ if (profileImageBitmap != null) {
+ Glide.with(requireContext())
+ .load(profileImageBitmap)
+ .into(profileImage)
+ } else {
+ Glide.with(requireContext())
+ .load(R.drawable.ic_logo)
+ .into(profileImage)
+ }
+ }
+ }
+
+ val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
+ val nightMode = preferences.getBoolean(PreferenceKeys.DARK_MODE, false)
+ val editor = preferences.edit()
+
+ switchDarkMode.isChecked = nightMode
+ switchDarkMode.setOnClickListener {
+ if (switchDarkMode.isChecked) {
+ editor.putBoolean(PreferenceKeys.DARK_MODE, true)
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
+ } else {
+ editor.putBoolean(PreferenceKeys.DARK_MODE, false)
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
+ }
+ editor.apply()
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+
+ activity?.findViewById(R.id.optRoundCardView2)?.visibility = View.VISIBLE
+ activity?.findViewById(R.id.fab)?.visibility = View.VISIBLE
+ }
+
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.group_edit_name -> launchNameDialog()
+ R.id.group_edit_school -> launchSchoolDialog()
+ R.id.group_edit_department -> launchDepartmentDialog()
+ R.id.group_edit_level -> launchLevelDialog()
+// R.id.fab_settings -> mNavController.navigate(R.id.settingsFragment)
+ R.id.profile_image -> launchProfileImageDialog()
+ R.id.fab_change_profile_picture -> launchProfileImageDialog()
+ }
+ }
+
+ private fun launchProfileImageDialog() {
+ val builder = MaterialAlertDialogBuilder(requireContext())
+ val selection = arrayOf(
+// "View profile picture",
+ "Take picture",
+ "Choose from gallery",
+ "Delete profile picture",
+ )
+ builder.setTitle("Options")
+ builder.setSingleChoiceItems(selection, -1) { dialog: DialogInterface, which: Int ->
+ when (which) {
+ 0 -> launchCamera()
+ 1 -> chooseFromGallery()
+ 2 -> deleteProfilePicture()
+ }
+ dialog.dismiss()
+ }
+ builder.show()
+ }
+
+ private fun deleteProfilePicture() {
+ val user = User(userName, userSchool, userDepartment, userLevel, null)
+ user.id = USER_ID
+ viewModel.updateUser(user)
+ }
+
+ private fun launchCamera() {
+ val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+ try {
+ startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
+ } catch (e: ActivityNotFoundException) {
+ Toast.makeText(context, "An error occurred: ${e.message}", Toast.LENGTH_LONG).show()
+ }
+ }
+
+ private fun chooseFromGallery() {
+ val intent = Intent(Intent.ACTION_GET_CONTENT)
+ intent.type = "image/*"
+ // intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+ try {
+ startActivityForResult(Intent.createChooser(intent, "Select image"), PICK_IMAGE_CODE)
+ } catch (e: ActivityNotFoundException) {
+ Toast.makeText(context, "An error occurred: ${e.message}", Toast.LENGTH_LONG).show()
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
+ assert(data != null)
+ val extras = data?.extras
+ val profileImageBitmap = extras!!["data"] as Bitmap?
+ val name = tvName.text.toString()
+ val school = tvSchool.text.toString()
+ val department = tvDepartment.text.toString()
+ val level = tvLevel.text.toString()
+
+ val user = User(name, school, department, level, profileImageBitmap)
+ user.id = USER_ID
+ viewModel.updateUser(user)
+
+ Glide.with(requireContext())
+ .load(profileImageBitmap)
+ .into(profileImage)
+ } else if (requestCode == PICK_IMAGE_CODE && resultCode == Activity.RESULT_OK) {
+ assert(data != null)
+ val uri = data?.data
+ try {
+ val stream = uri?.let { requireContext().contentResolver.openInputStream(it) }
+ val bitmap = BitmapFactory.decodeStream(stream)
+ val user = User(userName, userSchool, userDepartment, userLevel, bitmap)
+ user.id = USER_ID
+ viewModel.updateUser(user)
+ Glide.with(requireContext())
+ .load(bitmap)
+ .into(profileImage)
+ } catch (e: FileNotFoundException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ private fun launchNameDialog() {
+ val inflater = this.layoutInflater
+ val view =
+ inflater.inflate(R.layout.dialog_edit_profile, ConstraintLayout(requireContext()))
+
+ val bottomSheetDialog = BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme)
+ val tvEditProfileDialogTitle: MaterialTextView =
+ view.findViewById(R.id.tv_edit_profile_dialog_title)
+
+ val inputLayout: TextInputLayout = view.findViewById(R.id.et_edit_profile_layout)
+ val inputEditText: TextInputEditText = view.findViewById(R.id.et_edit_profile)
+
+ val btnCancel: MaterialButton = view.findViewById(R.id.btn_cancel)
+ val btnSave: MaterialButton = view.findViewById(R.id.btn_save)
+
+ tvEditProfileDialogTitle.setText(R.string.edit_name)
+ inputLayout.hint = getString(R.string.name)
+ inputEditText.setText(userName)
+
+ btnCancel.setOnClickListener { bottomSheetDialog.dismiss() }
+ btnSave.setOnClickListener {
+ val name = tvName.toString().trim()
+ val school = tvSchool.text.toString().trim()
+ val department = tvDepartment.text.toString().trim()
+ val level = tvLevel.text.toString().trim()
+ if (!isEmpty(name)) {
+ if (name != userName) {
+ val user = User(name, school, department, level, profileImageBitmap)
+ user.id = USER_ID
+ viewModel.updateUser(user)
+ tvName.text = name
+ } else Toast.makeText(context, "Name not changed", Toast.LENGTH_SHORT).show()
+ bottomSheetDialog.dismiss()
+ } else Toast.makeText(context, "Please Enter a name", Toast.LENGTH_SHORT).show()
+ }
+
+ bottomSheetDialog.setContentView(view)
+ bottomSheetDialog.show()
+ }
+
+ private fun launchSchoolDialog() {
+ val inflater = this.layoutInflater
+ val view =
+ inflater.inflate(R.layout.dialog_edit_profile, ConstraintLayout(requireContext()))
+
+ val bottomSheetDialog = BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme)
+ val tvEditProfileDialogTitle: MaterialTextView =
+ view.findViewById(R.id.tv_edit_profile_dialog_title)
+
+ val inputLayout: TextInputLayout = view.findViewById(R.id.et_edit_profile_layout)
+ val inputEditText: TextInputEditText = view.findViewById(R.id.et_edit_profile)
+
+ val btnCancel: MaterialButton = view.findViewById(R.id.btn_cancel)
+ val btnSave: MaterialButton = view.findViewById(R.id.btn_save)
+
+ tvEditProfileDialogTitle.setText(R.string.edit_school)
+ inputLayout.hint = getString(R.string.school)
+ inputEditText.setText(userSchool)
+
+ btnCancel.setOnClickListener { bottomSheetDialog.dismiss() }
+ btnSave.setOnClickListener {
+ val name = tvName.text.toString().trim()
+ val school = inputEditText.text.toString().trim()
+ val department = tvDepartment.text.toString().trim()
+ val level = tvLevel.text.toString().trim()
+ if (!isEmpty(school)) {
+ if (school != userSchool) {
+ val user = User(name, school, department, level, profileImageBitmap)
+ user.id = USER_ID
+ viewModel.updateUser(user)
+ tvSchool.text = school
+ } else Toast.makeText(context, "School not changed", Toast.LENGTH_SHORT).show()
+ bottomSheetDialog.dismiss()
+ } else Toast.makeText(context, "Please Enter a school", Toast.LENGTH_SHORT).show()
+ }
+ bottomSheetDialog.setContentView(view)
+ bottomSheetDialog.show()
+ }
+
+ private fun launchDepartmentDialog() {
+ val inflater = this.layoutInflater
+ val view =
+ inflater.inflate(R.layout.dialog_edit_profile, ConstraintLayout(requireContext()))
+
+ val bottomSheetDialog = BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme)
+ val tvEditProfileDialogTitle: MaterialTextView =
+ view.findViewById(R.id.tv_edit_profile_dialog_title)
+
+ val inputLayout: TextInputLayout = view.findViewById(R.id.et_edit_profile_layout)
+ val inputEditText: TextInputEditText = view.findViewById(R.id.et_edit_profile)
+
+ val btnCancel: MaterialButton = view.findViewById(R.id.btn_cancel)
+ val btnSave: MaterialButton = view.findViewById(R.id.btn_save)
+
+ tvEditProfileDialogTitle.setText(R.string.edit_department)
+ inputLayout.hint = getString(R.string.department)
+ inputEditText.setText(userDepartment)
+
+ btnCancel.setOnClickListener { bottomSheetDialog.dismiss() }
+ btnSave.setOnClickListener {
+ val name = tvName.text.toString().trim()
+ val school = tvSchool.text.toString().trim()
+ val department = inputEditText.text.toString().trim()
+ val level = tvLevel.text.toString().trim()
+ if (!isEmpty(department)) {
+ if (department != userDepartment) {
+ val user = User(name, school, department, level, profileImageBitmap)
+ user.id = USER_ID
+ viewModel.updateUser(user)
+ tvDepartment.text = department
+ } else Toast.makeText(context, "Department not changed", Toast.LENGTH_SHORT).show()
+ bottomSheetDialog.dismiss()
+ } else Toast.makeText(context, "Please Enter a department", Toast.LENGTH_SHORT).show()
+ }
+ bottomSheetDialog.setContentView(view)
+ bottomSheetDialog.show()
+ }
+
+ private fun launchLevelDialog() {
+ val inflater = this.layoutInflater
+ val view = inflater.inflate(R.layout.dialog_edit_level, null)
+ val builder = MaterialAlertDialogBuilder(requireContext())
+
+ builder.background =
+ AppCompatResources.getDrawable(requireContext(), R.drawable.alert_dialog_bg)
+ builder.setTitle(getString(R.string.select_level))
+
+ val alertDialog = builder.create()
+ alertDialog.setView(view)
+
+ val spinnerLevel = view.findViewById(R.id.spinner_level)
+ val btnCancel: MaterialButton = view.findViewById(R.id.btn_cancel)
+ val btnSave: MaterialButton = view.findViewById(R.id.btn_save)
+
+ val levels =
+ arrayOf(getString(R.string.select_level), "100L", "200L", "300L", "400L", "500L")
+ val adapterLevels =
+ ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, levels)
+
+ adapterLevels.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
+ spinnerLevel.adapter = adapterLevels
+
+ val selection = adapterLevels.getPosition(userLevel)
+ spinnerLevel.setSelection(selection)
+ btnCancel.setOnClickListener { alertDialog.dismiss() }
+ btnSave.setOnClickListener {
+ val name = tvName.text.toString().trim()
+ val school = tvSchool.text.toString().trim()
+ val department = tvDepartment.text.toString().trim()
+ val level = spinnerLevel.selectedItem.toString()
+ if (level != getString(R.string.select_level)) {
+ if (level != userLevel) {
+ val user = User(name, school, department, level, profileImageBitmap)
+ user.id = USER_ID
+ viewModel.updateUser(user)
+ tvLevel.text = level
+ } else Toast.makeText(context, "Level not changed", Toast.LENGTH_SHORT).show()
+ alertDialog.dismiss()
+ } else Toast.makeText(context, "Please select a level", Toast.LENGTH_SHORT).show()
+ }
+ alertDialog.show()
+ }
+
+ companion object {
+ private const val USER_ID = 0
+ private const val REQUEST_IMAGE_CAPTURE = 101
+ private const val PICK_IMAGE_CODE = 102
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/view/Profile/ProfileViewModel.kt b/app/src/main/java/com/certified/notes/view/Profile/ProfileViewModel.kt
new file mode 100644
index 0000000..0314533
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Profile/ProfileViewModel.kt
@@ -0,0 +1,23 @@
+package com.certified.notes.view.Profile
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.viewModelScope
+import com.certified.notes.model.User
+import com.certified.notes.util.Repository
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+class ProfileViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val repository = Repository(application)
+
+ val user: LiveData = repository.user
+
+ fun updateUser(user: User) {
+ viewModelScope.launch(Dispatchers.IO) {
+ repository.updateUser(user)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/view/Profile/ProfileViewModelFactory.kt b/app/src/main/java/com/certified/notes/view/Profile/ProfileViewModelFactory.kt
new file mode 100644
index 0000000..6788930
--- /dev/null
+++ b/app/src/main/java/com/certified/notes/view/Profile/ProfileViewModelFactory.kt
@@ -0,0 +1,14 @@
+package com.certified.notes.view.Profile
+
+import android.app.Application
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import java.lang.IllegalArgumentException
+
+class ProfileViewModelFactory(val application: Application): ViewModelProvider.Factory {
+ override fun create(modelClass: Class): T {
+ if (modelClass.isAssignableFrom(ProfileViewModel::class.java))
+ return ProfileViewModel(application) as T
+ throw IllegalArgumentException("Unknown ViewModel class")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/certified/notes/ui/ResultFragment.java b/app/src/main/java/com/certified/notes/view/ResultFragment.java
similarity index 93%
rename from app/src/main/java/com/certified/notes/ui/ResultFragment.java
rename to app/src/main/java/com/certified/notes/view/ResultFragment.java
index b076911..3cda40f 100644
--- a/app/src/main/java/com/certified/notes/ui/ResultFragment.java
+++ b/app/src/main/java/com/certified/notes/view/ResultFragment.java
@@ -1,4 +1,4 @@
-package com.certified.notes.ui;
+package com.certified.notes.view;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -14,7 +14,7 @@
import com.certified.notes.R;
import com.certified.notes.adapters.ResultRecyclerAdapter;
-import com.certified.notes.room.NotesViewModel;
+import com.certified.notes.view.Main.MainActivityViewModel;
import com.google.android.material.button.MaterialButton;
public class ResultFragment extends Fragment {
@@ -22,7 +22,7 @@ public class ResultFragment extends Fragment {
private RecyclerView recyclerResults;
private MaterialButton btnCheckGpa;
private TextView tvTotalLoadUnit, tvGradePointAverage;
- private NotesViewModel mViewModel;
+ private MainActivityViewModel mViewModel;
private ResultRecyclerAdapter mResultRecyclerAdapter;
public ResultFragment() {
@@ -63,7 +63,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
}
private void init() {
- mViewModel = new NotesViewModel(getActivity().getApplication());
+ mViewModel = new MainActivityViewModel(getActivity().getApplication());
LinearLayoutManager resultLayoutManager = new LinearLayoutManager(getContext());
mResultRecyclerAdapter = new ResultRecyclerAdapter(requireContext(), mViewModel);
diff --git a/app/src/main/java/com/certified/notes/ui/SplashFragment.kt b/app/src/main/java/com/certified/notes/view/SplashFragment.kt
similarity index 98%
rename from app/src/main/java/com/certified/notes/ui/SplashFragment.kt
rename to app/src/main/java/com/certified/notes/view/SplashFragment.kt
index b741201..06e06ed 100644
--- a/app/src/main/java/com/certified/notes/ui/SplashFragment.kt
+++ b/app/src/main/java/com/certified/notes/view/SplashFragment.kt
@@ -1,4 +1,4 @@
-package com.certified.notes.ui
+package com.certified.notes.view
import android.app.Notification
import android.app.NotificationChannel
@@ -22,6 +22,7 @@ import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.preference.PreferenceManager
import com.certified.notes.R
+import com.certified.notes.view.Main.MainActivity
import com.certified.notes.util.PreferenceKeys
class SplashFragment : Fragment() {
diff --git a/app/src/main/res/layout-land/fragment_home.xml b/app/src/main/res/layout-land/fragment_home.xml
index 06fda26..4097c60 100644
--- a/app/src/main/res/layout-land/fragment_home.xml
+++ b/app/src/main/res/layout-land/fragment_home.xml
@@ -6,7 +6,7 @@
android:layout_height="match_parent"
android:layout_marginBottom="16dp"
android:background="?attr/backgroundColor"
- tools:context=".ui.HomeFragment">
+ tools:context=".view.Home.HomeFragment">
+ tools:context=".view.OnboardingFragment">
+ tools:context=".view.Profile.ProfileFragment">
+ tools:context=".view.ResultFragment">
+ tools:context=".view.Home.HomeFragment">
+ tools:context=".view.OnboardingFragment">
+ tools:context=".view.Main.MainActivity">
+ tools:context=".view.Main.MainActivity">
+ tools:context=".view.BookMarks.BookMarksFragment">
+ tools:context=".view.Courses.CoursesFragmentKt">
+ tools:context=".view.Home.HomeFragment">
+ tools:context=".view.Notes.NotesFragment">
+ tools:context=".view.OnboardingFragment">
+ tools:context=".view.Profile.ProfileFragment">
+ tools:context=".view.ResultFragment">
+ tools:context=".view.Main.MainActivity">
+ tools:context=".view.BookMarks.BookMarksFragment">
+ tools:context=".view.Courses.CoursesFragmentKt">
+ tools:context=".view.Notes.NotesFragment">
+ tools:context=".view.Main.MainActivity">
+ tools:context=".view.BookMarks.BookMarksFragment">
+ tools:context=".view.Courses.CoursesFragmentKt">
+ tools:context=".view.Home.HomeFragment">
+ tools:context=".view.Notes.NotesFragment">
+ tools:context=".view.OnboardingFragment">
+ tools:context=".view.Profile.ProfileFragment">
+ tools:context=".view.ResultFragment">
+ tools:context=".view.SplashFragment">
\ No newline at end of file
diff --git a/app/src/test/java/com/certified/notes/util/RepositoryTest.kt b/app/src/test/java/com/certified/notes/util/RepositoryTest.kt
new file mode 100644
index 0000000..4ecc94d
--- /dev/null
+++ b/app/src/test/java/com/certified/notes/util/RepositoryTest.kt
@@ -0,0 +1,21 @@
+package com.certified.notes.util
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class RepositoryTest {
+
+ @Test
+ fun insertNote() {
+ val test = TestingPractice()
+ val courseCode = "EEE 415"
+ val title = "Engineering Maths 3"
+ val content = "A very useless course tbh"
+ val result = test.insertNote(courseCode, title, content)
+
+ assertThat(result).isEqualTo(true)
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 9369ee8..31b581c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,6 +14,13 @@ buildscript {
}
}
+//gradleEnterprise {
+// buildScan {
+// termsOfServiceUrl = "https://gradle.com/terms-of-service"
+// termsOfServiceAgree = "yes"
+// }
+//}
+
allprojects {
repositories {
google()