From 59642a8283b4685c2551eee2b1a7051e98b2a521 Mon Sep 17 00:00:00 2001 From: Samson Achiaga Date: Sun, 5 Sep 2021 13:09:25 +0100 Subject: [PATCH 1/4] Refactored project to implement MVVM --- .idea/misc.xml | 6 + app/src/main/AndroidManifest.xml | 2 +- .../notes/adapters/ResultRecyclerAdapter.kt | 4 +- .../notes/adapters/TodoRecyclerAdapter.kt | 4 +- .../certified/notes/room/NotesViewModel.kt | 136 ------- .../ui/{ => BookMarks}/BookMarksFragment.kt | 13 +- .../notes/ui/BookMarks/BookMarksViewModel.kt | 53 +++ .../ui/BookMarks/BookMarksViewModelFactory.kt | 13 + .../ui/{ => Courses}/CoursesFragmentKt.kt | 9 +- .../notes/ui/Courses/CoursesViewModel.kt | 70 ++++ .../ui/Courses/CoursesViewModelFactory.kt | 13 + .../notes/ui/{ => Home}/HomeFragment.kt | 54 +-- .../certified/notes/ui/Home/HomeViewModel.kt | 34 ++ .../notes/ui/Home/HomeViewModelFactory.kt | 14 + .../notes/ui/{ => Main}/MainActivity.kt | 7 +- .../notes/ui/Main/MainActivityViewModel.kt | 59 +++ .../NotesFragment.kt} | 9 +- .../notes/ui/Notes/NotesViewModel.kt | 61 ++++ .../notes/ui/Notes/NotesViewModelFactory.kt | 14 + .../com/certified/notes/ui/NotesFragment.java | 336 ------------------ .../certified/notes/ui/ProfileFragment.java | 6 +- .../certified/notes/ui/ResultFragment.java | 6 +- .../com/certified/notes/ui/SplashFragment.kt | 1 + .../main/res/layout-land/fragment_home.xml | 2 +- .../res/layout-sw600dp-land/fragment_home.xml | 2 +- .../res/layout-sw600dp-v21/activity_main.xml | 2 +- .../main/res/layout-sw600dp/activity_main.xml | 2 +- .../layout-sw600dp/fragment_book_marks.xml | 2 +- .../res/layout-sw600dp/fragment_courses.xml | 2 +- .../main/res/layout-sw600dp/fragment_home.xml | 2 +- .../res/layout-sw600dp/fragment_notes.xml | 2 +- app/src/main/res/layout-v21/activity_main.xml | 2 +- .../res/layout-v21/fragment_book_marks.xml | 2 +- .../main/res/layout-v21/fragment_courses.xml | 2 +- .../main/res/layout-v21/fragment_notes.xml | 2 +- app/src/main/res/layout/activity_main.xml | 2 +- .../main/res/layout/fragment_book_marks.xml | 2 +- app/src/main/res/layout/fragment_courses.xml | 2 +- app/src/main/res/layout/fragment_home.xml | 2 +- app/src/main/res/layout/fragment_notes.xml | 2 +- app/src/main/res/navigation/nav_graph.xml | 8 +- 41 files changed, 419 insertions(+), 547 deletions(-) delete mode 100644 app/src/main/java/com/certified/notes/room/NotesViewModel.kt rename app/src/main/java/com/certified/notes/ui/{ => BookMarks}/BookMarksFragment.kt (97%) create mode 100644 app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModel.kt create mode 100644 app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModelFactory.kt rename app/src/main/java/com/certified/notes/ui/{ => Courses}/CoursesFragmentKt.kt (98%) create mode 100644 app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModel.kt create mode 100644 app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModelFactory.kt rename app/src/main/java/com/certified/notes/ui/{ => Home}/HomeFragment.kt (90%) create mode 100644 app/src/main/java/com/certified/notes/ui/Home/HomeViewModel.kt create mode 100644 app/src/main/java/com/certified/notes/ui/Home/HomeViewModelFactory.kt rename app/src/main/java/com/certified/notes/ui/{ => Main}/MainActivity.kt (98%) create mode 100644 app/src/main/java/com/certified/notes/ui/Main/MainActivityViewModel.kt rename app/src/main/java/com/certified/notes/ui/{NotesFragmentKt.kt => Notes/NotesFragment.kt} (98%) create mode 100644 app/src/main/java/com/certified/notes/ui/Notes/NotesViewModel.kt create mode 100644 app/src/main/java/com/certified/notes/ui/Notes/NotesViewModelFactory.kt delete mode 100644 app/src/main/java/com/certified/notes/ui/NotesFragment.java diff --git a/.idea/misc.xml b/.idea/misc.xml index 8a758c4..caefaa2 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,7 +3,13 @@ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6cfdc4a..eb6eb99 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/ResultRecyclerAdapter.kt b/app/src/main/java/com/certified/notes/adapters/ResultRecyclerAdapter.kt index 76f29df..87fb202 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.ui.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..ccf83f2 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.ui.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 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/BookMarksFragment.kt b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksFragment.kt similarity index 97% rename from app/src/main/java/com/certified/notes/ui/BookMarksFragment.kt rename to app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksFragment.kt index 91addd2..0aad09d 100644 --- a/app/src/main/java/com/certified/notes/ui/BookMarksFragment.kt +++ b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksFragment.kt @@ -1,4 +1,4 @@ -package com.certified.notes.ui +package com.certified.notes.ui.BookMarks import android.content.DialogInterface import android.graphics.Canvas @@ -15,6 +15,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 +25,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 +34,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 +48,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 +56,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() diff --git a/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModel.kt b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModel.kt new file mode 100644 index 0000000..b3c4546 --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModel.kt @@ -0,0 +1,53 @@ +package com.certified.notes.ui.BookMarks + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import com.certified.notes.model.BookMark +import com.certified.notes.model.Course +import com.certified.notes.model.Note +import com.certified.notes.model.User +import com.certified.notes.util.Repository + +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) { + repository.updateBookMark(bookMark) + } + + fun updateNote(note: Note) { + repository.updateNote(note) + } + + fun deleteBookMark(bookMark: BookMark) { + repository.deleteBookMark(bookMark) + } + + fun deleteAllBookMarks() { + 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/ui/BookMarks/BookMarksViewModelFactory.kt b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModelFactory.kt new file mode 100644 index 0000000..4a74d7a --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModelFactory.kt @@ -0,0 +1,13 @@ +package com.certified.notes.ui.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/ui/Courses/CoursesFragmentKt.kt similarity index 98% rename from app/src/main/java/com/certified/notes/ui/CoursesFragmentKt.kt rename to app/src/main/java/com/certified/notes/ui/Courses/CoursesFragmentKt.kt index 3ba2b50..3941cb5 100644 --- a/app/src/main/java/com/certified/notes/ui/CoursesFragmentKt.kt +++ b/app/src/main/java/com/certified/notes/ui/Courses/CoursesFragmentKt.kt @@ -1,4 +1,4 @@ -package com.certified.notes.ui +package com.certified.notes.ui.Courses import android.os.Build import android.os.Bundle @@ -14,6 +14,7 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.widget.SearchView 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 @@ -61,7 +61,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() diff --git a/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModel.kt b/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModel.kt new file mode 100644 index 0000000..5781535 --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModel.kt @@ -0,0 +1,70 @@ +package com.certified.notes.ui.Courses + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import com.certified.notes.model.* +import com.certified.notes.util.Repository + +class CoursesViewModel(application: Application): AndroidViewModel(application) { + + private val repository = Repository(application) + + val allCourses: LiveData> = repository.allCourses + + fun updateNote(note: Note) { + repository.updateNote(note) + } + + fun updateCourse(course: Course) { + repository.updateCourse(course) + } + + fun updateBookMark(bookMark: BookMark) { + repository.updateBookMark(bookMark) + } + + fun deleteNote(note: Note) { + repository.deleteNote(note) + } + + fun deleteCourse(course: Course) { + repository.deleteCourse(course) + } + + fun deleteBookMark(bookMark: BookMark) { + 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/ui/Courses/CoursesViewModelFactory.kt b/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModelFactory.kt new file mode 100644 index 0000000..30c331f --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModelFactory.kt @@ -0,0 +1,13 @@ +package com.certified.notes.ui.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/ui/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/ui/Home/HomeFragment.kt index 17e8d34..913bb9d 100644 --- a/app/src/main/java/com/certified/notes/ui/HomeFragment.kt +++ b/app/src/main/java/com/certified/notes/ui/Home/HomeFragment.kt @@ -1,4 +1,4 @@ -package com.certified.notes.ui +package com.certified.notes.ui.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/ui/Home/HomeViewModel.kt b/app/src/main/java/com/certified/notes/ui/Home/HomeViewModel.kt new file mode 100644 index 0000000..2292857 --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/Home/HomeViewModel.kt @@ -0,0 +1,34 @@ +package com.certified.notes.ui.Home + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import com.certified.notes.model.Course +import com.certified.notes.model.Note +import com.certified.notes.model.Todo +import com.certified.notes.util.Repository + +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) { + repository.updateTodo(todo) + } + + fun deleteTodo(todo: Todo) { + 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/ui/Home/HomeViewModelFactory.kt b/app/src/main/java/com/certified/notes/ui/Home/HomeViewModelFactory.kt new file mode 100644 index 0000000..e1165c9 --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/Home/HomeViewModelFactory.kt @@ -0,0 +1,14 @@ +package com.certified.notes.ui.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/ui/Main/MainActivity.kt similarity index 98% rename from app/src/main/java/com/certified/notes/ui/MainActivity.kt rename to app/src/main/java/com/certified/notes/ui/Main/MainActivity.kt index 240458b..3f623d1 100644 --- a/app/src/main/java/com/certified/notes/ui/MainActivity.kt +++ b/app/src/main/java/com/certified/notes/ui/Main/MainActivity.kt @@ -1,4 +1,4 @@ -package com.certified.notes.ui +package com.certified.notes.ui.Main import android.os.Bundle import android.view.LayoutInflater @@ -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) diff --git a/app/src/main/java/com/certified/notes/ui/Main/MainActivityViewModel.kt b/app/src/main/java/com/certified/notes/ui/Main/MainActivityViewModel.kt new file mode 100644 index 0000000..cdd03e7 --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/Main/MainActivityViewModel.kt @@ -0,0 +1,59 @@ +package com.certified.notes.ui.Main + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import com.certified.notes.model.* +import com.certified.notes.util.Repository + +class MainActivityViewModel(application: Application) : AndroidViewModel(application) { + + private val repository = Repository(application) + + val allNotes: LiveData> = repository.allNotes + 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) { + repository.insertNote(note) + } + + fun insertCourse(course: Course) { + repository.insertCourse(course) + } + + fun insertTodo(todo: Todo) { + repository.insertTodo(todo) + } + + fun updateNote(note: Note) { + repository.updateNote(note) + } + + fun updateCourse(course: Course) { + repository.updateCourse(course) + } + + fun updateUser(user: User) { + repository.updateUser(user) + } + + 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/ui/Notes/NotesFragment.kt similarity index 98% rename from app/src/main/java/com/certified/notes/ui/NotesFragmentKt.kt rename to app/src/main/java/com/certified/notes/ui/Notes/NotesFragment.kt index 26d2cd1..f20c20e 100644 --- a/app/src/main/java/com/certified/notes/ui/NotesFragmentKt.kt +++ b/app/src/main/java/com/certified/notes/ui/Notes/NotesFragment.kt @@ -1,4 +1,4 @@ -package com.certified.notes.ui +package com.certified.notes.ui.Notes import android.content.SharedPreferences import android.os.Build @@ -15,6 +15,7 @@ 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 @@ -23,7 +24,6 @@ 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 +31,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 @@ -61,7 +61,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) diff --git a/app/src/main/java/com/certified/notes/ui/Notes/NotesViewModel.kt b/app/src/main/java/com/certified/notes/ui/Notes/NotesViewModel.kt new file mode 100644 index 0000000..bbfca45 --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/Notes/NotesViewModel.kt @@ -0,0 +1,61 @@ +package com.certified.notes.ui.Notes + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +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.util.Repository + +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) { + repository.insertBookMark(bookMark) + } + + fun updateNote(note: Note) { + repository.updateNote(note) + } + + fun updateBookMark(bookMark: BookMark) { + repository.updateBookMark(bookMark) + } + + fun deleteNote(note: Note) { + 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/ui/Notes/NotesViewModelFactory.kt b/app/src/main/java/com/certified/notes/ui/Notes/NotesViewModelFactory.kt new file mode 100644 index 0000000..8cb070a --- /dev/null +++ b/app/src/main/java/com/certified/notes/ui/Notes/NotesViewModelFactory.kt @@ -0,0 +1,14 @@ +package com.certified.notes.ui.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/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 index f32ae24..5a37932 100644 --- a/app/src/main/java/com/certified/notes/ui/ProfileFragment.java +++ b/app/src/main/java/com/certified/notes/ui/ProfileFragment.java @@ -30,7 +30,7 @@ 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.ui.Main.MainActivityViewModel; import com.certified.notes.util.PreferenceKeys; import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.button.MaterialButton; @@ -57,7 +57,7 @@ public class ProfileFragment extends Fragment implements View.OnClickListener { private static final int PICK_IMAGE_CODE = 102; String userName, userSchool, userDepartment, userLevel; Bitmap profileImageBitmap; - private NotesViewModel mViewModel; + private MainActivityViewModel mViewModel; private NavController mNavController; private Group groupName, groupSchool, groupDepartment, groupLevel; private TextView tvName, tvSchool, tvDepartment, tvLevel; @@ -99,7 +99,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - mViewModel = new NotesViewModel(requireActivity().getApplication()); + mViewModel = new MainActivityViewModel(requireActivity().getApplication()); mNavController = Navigation.findNavController(view); groupName.setOnClickListener(this); diff --git a/app/src/main/java/com/certified/notes/ui/ResultFragment.java b/app/src/main/java/com/certified/notes/ui/ResultFragment.java index b076911..c5b596f 100644 --- a/app/src/main/java/com/certified/notes/ui/ResultFragment.java +++ b/app/src/main/java/com/certified/notes/ui/ResultFragment.java @@ -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.ui.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/ui/SplashFragment.kt index b741201..c52ec75 100644 --- a/app/src/main/java/com/certified/notes/ui/SplashFragment.kt +++ b/app/src/main/java/com/certified/notes/ui/SplashFragment.kt @@ -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.ui.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..4443b58 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=".ui.Home.HomeFragment"> + tools:context=".ui.Home.HomeFragment"> + tools:context=".ui.Main.MainActivity"> + tools:context=".ui.Main.MainActivity"> + tools:context=".ui.BookMarks.BookMarksFragment"> + tools:context=".ui.Courses.CoursesFragmentKt"> + tools:context=".ui.Home.HomeFragment"> + tools:context=".ui.Notes.NotesFragment"> + tools:context=".ui.Main.MainActivity"> + tools:context=".ui.BookMarks.BookMarksFragment"> + tools:context=".ui.Courses.CoursesFragmentKt"> + tools:context=".ui.Notes.NotesFragment"> + tools:context=".ui.Main.MainActivity"> + tools:context=".ui.BookMarks.BookMarksFragment"> + tools:context=".ui.Courses.CoursesFragmentKt"> + tools:context=".ui.Home.HomeFragment"> + tools:context=".ui.Notes.NotesFragment"> Date: Mon, 6 Sep 2021 05:26:11 +0100 Subject: [PATCH 2/4] Refactored code, changed ProfileFragment.java to Kotlin code --- .idea/misc.xml | 4 + .../notes/ui/Main/MainActivityViewModel.kt | 5 - .../certified/notes/ui/Notes/NotesFragment.kt | 3 +- .../notes/ui/Profile/ProfileFragment.kt | 417 +++++++++++++++++ .../notes/ui/Profile/ProfileViewModel.kt | 18 + .../ui/Profile/ProfileViewModelFactory.kt | 14 + .../certified/notes/ui/ProfileFragment.java | 436 ------------------ .../main/res/layout-land/fragment_profile.xml | 2 +- .../res/layout-sw600dp/fragment_profile.xml | 2 +- app/src/main/res/layout/fragment_profile.xml | 2 +- app/src/main/res/navigation/nav_graph.xml | 2 +- 11 files changed, 458 insertions(+), 447 deletions(-) create mode 100644 app/src/main/java/com/certified/notes/ui/Profile/ProfileFragment.kt create mode 100644 app/src/main/java/com/certified/notes/ui/Profile/ProfileViewModel.kt create mode 100644 app/src/main/java/com/certified/notes/ui/Profile/ProfileViewModelFactory.kt delete mode 100644 app/src/main/java/com/certified/notes/ui/ProfileFragment.java diff --git a/.idea/misc.xml b/.idea/misc.xml index caefaa2..2d40f19 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,6 +3,7 @@ + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index d93f103..b381a3c 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 { @@ -58,7 +61,7 @@ dependencies { 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 @@ -71,7 +74,7 @@ dependencies { implementation 'com.github.captain-miao:optroundcardview:1.0.0' // lottie - implementation "com.airbnb.android:lottie:3.4.0" + implementation "com.airbnb.android:lottie:3.6.0" // page indicator implementation "com.romandanylyk:pageindicatorview:1.0.3@aar" 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 87fb202..a3ab833 100644 --- a/app/src/main/java/com/certified/notes/adapters/ResultRecyclerAdapter.kt +++ b/app/src/main/java/com/certified/notes/adapters/ResultRecyclerAdapter.kt @@ -120,6 +120,7 @@ class ResultRecyclerAdapter(val context: Context, private val viewModel: MainAct if (courseMark in validMark) { if (courseMark != course.courseMark) { val course1 = Course( + course.id, courseCode, courseTitle, courseUnit, @@ -127,7 +128,6 @@ class ResultRecyclerAdapter(val context: Context, private val viewModel: MainAct courseGrade, courseGradePoint ) - course1.id = course.id viewModel.updateCourse(course1) holder.courseGrade.text = courseGrade 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 ccf83f2..5a2c9a7 100644 --- a/app/src/main/java/com/certified/notes/adapters/TodoRecyclerAdapter.kt +++ b/app/src/main/java/com/certified/notes/adapters/TodoRecyclerAdapter.kt @@ -97,8 +97,7 @@ class TodoRecyclerAdapter(val context: Context, private val viewModel: HomeViewM dialog.cancel() } builder.setNegativeButton(context.getString(R.string.no)) { dialog, _ -> - val todo1 = Todo(todoContent, true) - todo1.id = getItem(position).id + val todo1 = Todo(getItem(position).id, todoContent, true) 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..743d3cf 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,15 @@ 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( @PrimaryKey(autoGenerate = true) - var id = 0 -} \ No newline at end of file + var id: Int, + @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 +) \ 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..75b3833 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,21 @@ 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( @PrimaryKey(autoGenerate = true) - var id = 0 - @field:ColumnInfo(name = "course_credit_point") var courseCreditPoint: Int = courseGradePoint * courseUnit -} \ No newline at end of file + val id: Int, + @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 +) \ 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..c399b52 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,13 @@ 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( @PrimaryKey(autoGenerate = true) - var id = 0 -} \ No newline at end of file + var id: Int, + @ColumnInfo(name = "course_code") + val courseCode: String, + @ColumnInfo(name = "note_title") + val title: String, + @ColumnInfo(name = "note_content") + val content: String? +) \ 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..fd07a6b 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,10 @@ 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( @PrimaryKey(autoGenerate = true) - var id = 0 -} \ No newline at end of file + val id: Int, + @ColumnInfo(name = "course_code") val courseCode: String, + @ColumnInfo(name = "course_unit") val courseUnit: String, + @ColumnInfo(name = "course_mark") val courseMark: String +) \ 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..cd41310 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,9 @@ import androidx.room.Entity import androidx.room.PrimaryKey @Entity(tableName = "todo_table") -class Todo(val todo: String, val isDone: Boolean) { +data class Todo( @PrimaryKey(autoGenerate = true) - var id = 0 -} \ No newline at end of file + val id: Int, + val todo: String, + val isDone: Boolean +) \ 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..2597a12 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,12 @@ import androidx.room.Entity import androidx.room.PrimaryKey @Entity(tableName = "user_table") -class User( +data class User( + @PrimaryKey + val id: Int = 0, val name: String, val school: String, val department: String, val level: String, - @field:ColumnInfo(name = "profile_image") val profileImage: Bitmap? -) { - @PrimaryKey - var id = 0 -} \ No newline at end of file + @ColumnInfo(name = "profile_image") val profileImage: Bitmap? +) \ 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..63ce6eb 100644 --- a/app/src/main/java/com/certified/notes/room/NotesDatabase.kt +++ b/app/src/main/java/com/certified/notes/room/NotesDatabase.kt @@ -1,175 +1,202 @@ 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) val note1 = Note( - "MTS 315", + 0, "MTS 315", "Dynamic intent resolution", "Wow, intents allow components to be resolved at runtime" ) val note2 = Note( + 0, "CPE 301", "Parameters", "Leverage variable-length parameter lists?" ) val note3 = Note( + 0, "EEE 301", "Delegating intents", "PendingIntents are powerful; they delegate much more than just a component invocation" ) val note4 = Note( - "AGE 301", + 0, "AGE 301", "Compiler options", "The -jar option isn't compatible with with the -cp option" ) val note5 = Note( - "EEE 305", + 0, "EEE 305", "Serialization", "Remember to include SerialVersionUID to assure version compatibility" ) val note6 = Note( - "PMT 301", + 0, "PMT 301", "Service default threads", "Did you know that by default an Android Service will tie up the UI thread?" ) val note7 = Note( - "EEE 311", + 0, "EEE 311", "Anonymous classes", "Anonymous classes simplify implementing one-use types" ) val note8 = Note( - "EEE 307", + 0, "EEE 307", "Long running operations", "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( + 0, "AGE 301", "Engineering Statistics", 2, 0, "F", 0 + ) + val course2 = Course( + 0, "CPE 301", "Digital System Design with VHDL", 3, 0, "F", 0 + ) + val course3 = Course( + 0, "EEE 301", "Measurement and Instrumentation", 2, 0, "F", 0 + ) + val course4 = Course( + 0, "EEE 303", "Electronics Engineering I", 3, 0, "F", 0 + ) + val course5 = Course( + 0, "EEE 305", "Electromagnetic Field Theory", 2, 0, "F", 0 + ) + val course6 = Course( + 0, "EEE 307", "Electric Machines I", 3, 0, "F", 0 + ) + val course7 = Course( + 0, "EEE 311", "Electric Circuit Theory I", 3, 0, "F", 0 + ) + val course8 = Course( + 0, "EEE 313", "Electrical/Electronic Laboratory I", 1, 0, "F", 0 + ) + val course9 = Course( + 0, "MTS 315", "Engineering Mathematics I", 3, 0, "F", 0 + ) + val course10 = Course( + 0, "PMT 301", "Introduction to Entrepreneurship", 2, 0, "F", 0 + ) val todo1 = Todo( - "Make sure to complete the To-dos below", - false + 0, "Make sure to complete the To-dos below", false ) val todo2 = Todo( + 0, "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 + 0, "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 + 0, "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 + 0, "Visit the code labs and study guide for the AAD exam frequently", false ) val todo6 = Todo( + 0, "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 + 0, "Make sure you pass the exam at the first try!!!", false ) val todo8 = Todo( - "Make sure to complete the To-dos above", - false + 0, "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/ui/BookMarks/BookMarksFragment.kt b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksFragment.kt index 0aad09d..47b7991 100644 --- a/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksFragment.kt +++ b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksFragment.kt @@ -2,7 +2,6 @@ package com.certified.notes.ui.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 @@ -65,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 @@ -125,7 +124,9 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener { if (courseTitle != getString(R.string.select_a_course)) { if (courseCode != bookmark.courseCode || noteTitle != bookmark.noteTitle || noteContent != bookmark.noteContent) { if (courseTitle != getString(R.string.no_course)) { - val note = Note(courseCode, noteTitle, noteContent) + val note = Note( + 0, courseCode, noteTitle, noteContent + ) note.id = bookmark.noteId viewModel.updateNote(note) viewModel.getBookMarkAt(bookmark.noteId) @@ -133,6 +134,7 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener { if (it != null) { for (bookMark in it) { val bookMark1 = BookMark( + 0, noteId, courseCode, noteTitle, @@ -144,7 +146,7 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener { } } } else { - val note = Note("NIL", noteTitle, noteContent) + val note = Note(0, "NIL", noteTitle, noteContent) note.id = bookmark.noteId viewModel.updateNote(note) viewModel.getBookMarkAt(bookmark.noteId) @@ -153,7 +155,7 @@ class BookMarksFragment : Fragment(), PopupMenu.OnMenuItemClickListener { for (bookMark in it) { val bookMark1 = BookMark( - noteId, + 0, noteId, "NIL", noteTitle, noteContent @@ -260,25 +262,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) { @@ -307,6 +307,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() @@ -328,7 +330,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( @@ -358,7 +359,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/ui/BookMarks/BookMarksViewModel.kt b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModel.kt index b3c4546..8e05305 100644 --- a/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModel.kt +++ b/app/src/main/java/com/certified/notes/ui/BookMarks/BookMarksViewModel.kt @@ -3,11 +3,13 @@ package com.certified.notes.ui.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.model.User import com.certified.notes.util.Repository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch class BookMarksViewModel(application: Application) : AndroidViewModel(application) { @@ -20,19 +22,25 @@ class BookMarksViewModel(application: Application) : AndroidViewModel(applicatio val allCourses: LiveData> = repository.allCourses fun updateBookMark(bookMark: BookMark) { - repository.updateBookMark(bookMark) + viewModelScope.launch(Dispatchers.IO) { repository.updateBookMark(bookMark) } } fun updateNote(note: Note) { - repository.updateNote(note) + viewModelScope.launch(Dispatchers.IO) { + repository.updateNote(note) + } } fun deleteBookMark(bookMark: BookMark) { - repository.deleteBookMark(bookMark) + viewModelScope.launch(Dispatchers.IO) { + repository.deleteBookMark(bookMark) + } } fun deleteAllBookMarks() { - repository.deleteAllBookMarks() + viewModelScope.launch(Dispatchers.IO) { + repository.deleteAllBookMarks() + } } fun getBookMarkAt(noteId: Int): LiveData>? { diff --git a/app/src/main/java/com/certified/notes/ui/Courses/CoursesFragmentKt.kt b/app/src/main/java/com/certified/notes/ui/Courses/CoursesFragmentKt.kt index 3941cb5..c7fcf3c 100644 --- a/app/src/main/java/com/certified/notes/ui/Courses/CoursesFragmentKt.kt +++ b/app/src/main/java/com/certified/notes/ui/Courses/CoursesFragmentKt.kt @@ -1,6 +1,5 @@ package com.certified.notes.ui.Courses -import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper @@ -12,6 +11,7 @@ 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 @@ -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 } @@ -107,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) @@ -163,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 @@ -217,7 +218,7 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener { if (noteTitle.isNotEmpty() && noteContent.isNotEmpty()) { if (courseTitle != getString(R.string.select_a_course)) { if (courseCode != note.courseCode || noteTitle != note.title || noteContent != note.content) { - val note1 = Note(courseCode, noteTitle, noteContent) + val note1 = Note(0, courseCode, noteTitle, noteContent) note1.id = note.id viewModel.updateNote(note1) viewModel.getBookMarkAt(note.id) @@ -225,7 +226,13 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener { val noteId = note1.id for (bookMark in bookMarks) { val bookMark1 = - BookMark(noteId, courseCode, noteTitle, noteContent) + BookMark( + 0, + noteId, + courseCode, + noteTitle, + noteContent + ) bookMark1.id = bookMark.id viewModel.updateBookMark(bookMark1) } @@ -259,7 +266,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) @@ -292,20 +300,20 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener { courseUnit != course.courseUnit ) { val course1 = Course( - courseCode, + course.id, courseCode, courseTitle, courseUnit, courseMark, courseGrade, courseGradePoint ) - course1.id = course.id +// course1.id = course.id viewModel.getNotesAt(course.courseCode)?.observe(viewLifecycleOwner) { notes -> if (notes.isNotEmpty()) { for (note in notes) { val noteTitle = note.title val noteContent = note.content - val note1 = Note(courseCode, noteTitle, noteContent) + val note1 = Note(0, courseCode, noteTitle, noteContent) note1.id = note.id viewModel.updateNote(note1) @@ -314,7 +322,7 @@ class CoursesFragmentKt : Fragment(), PopupMenu.OnMenuItemClickListener { if (bookMarks.isNotEmpty()) { for (bookMark in bookMarks) { val bookMark1 = BookMark( - note.id, + 0, note.id, courseCode, noteTitle, noteContent!! diff --git a/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModel.kt b/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModel.kt index 5781535..48d00cb 100644 --- a/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModel.kt +++ b/app/src/main/java/com/certified/notes/ui/Courses/CoursesViewModel.kt @@ -3,37 +3,54 @@ package com.certified.notes.ui.Courses import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData -import com.certified.notes.model.* +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) { +class CoursesViewModel(application: Application) : AndroidViewModel(application) { private val repository = Repository(application) val allCourses: LiveData> = repository.allCourses fun updateNote(note: Note) { - repository.updateNote(note) + viewModelScope.launch(Dispatchers.IO) { + repository.updateNote(note) + } } fun updateCourse(course: Course) { - repository.updateCourse(course) + viewModelScope.launch(Dispatchers.IO) { + repository.updateCourse(course) + } } fun updateBookMark(bookMark: BookMark) { - repository.updateBookMark(bookMark) + viewModelScope.launch(Dispatchers.IO) { + repository.updateBookMark(bookMark) + } } fun deleteNote(note: Note) { - repository.deleteNote(note) + viewModelScope.launch(Dispatchers.IO) { + repository.deleteNote(note) + } } fun deleteCourse(course: Course) { - repository.deleteCourse(course) + viewModelScope.launch(Dispatchers.IO) { + repository.deleteCourse(course) + } } fun deleteBookMark(bookMark: BookMark) { - repository.deleteBookMark(bookMark) + viewModelScope.launch(Dispatchers.IO) { + repository.deleteBookMark(bookMark) + } } fun deleteAllCourses() { diff --git a/app/src/main/java/com/certified/notes/ui/Home/HomeFragment.kt b/app/src/main/java/com/certified/notes/ui/Home/HomeFragment.kt index 913bb9d..987135a 100644 --- a/app/src/main/java/com/certified/notes/ui/Home/HomeFragment.kt +++ b/app/src/main/java/com/certified/notes/ui/Home/HomeFragment.kt @@ -24,6 +24,7 @@ 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.ui.Main.MainActivity import com.certified.notes.util.PreferenceKeys import com.github.captain_miao.optroundcardview.OptRoundCardView import com.google.android.material.bottomsheet.BottomSheetDialog @@ -171,8 +172,8 @@ class HomeFragment : Fragment(), View.OnClickListener, PopupMenu.OnMenuItemClick val done = todo.isDone if (todoContent.isNotEmpty()) { if (todoContent != todo.todo) { - val todo1 = Todo(todoContent, done) - todo1.id = todo.id + val todo1 = Todo(todo.id, todoContent, done) +// todo1.id = todo.id viewModel.updateTodo(todo1) bottomSheetDialog.dismiss() } else diff --git a/app/src/main/java/com/certified/notes/ui/Home/HomeViewModel.kt b/app/src/main/java/com/certified/notes/ui/Home/HomeViewModel.kt index 2292857..27832ed 100644 --- a/app/src/main/java/com/certified/notes/ui/Home/HomeViewModel.kt +++ b/app/src/main/java/com/certified/notes/ui/Home/HomeViewModel.kt @@ -3,12 +3,15 @@ package com.certified.notes.ui.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) { +class HomeViewModel(application: Application) : AndroidViewModel(application) { private val repository = Repository(application) @@ -17,11 +20,15 @@ class HomeViewModel(application: Application): AndroidViewModel(application) { val allTodos: LiveData> = repository.allTodos fun updateTodo(todo: Todo) { - repository.updateTodo(todo) + viewModelScope.launch(Dispatchers.IO) { + repository.updateTodo(todo) + } } fun deleteTodo(todo: Todo) { - repository.deleteTodo(todo) + viewModelScope.launch(Dispatchers.IO) { + repository.deleteTodo(todo) + } } fun deleteAllTodos() { diff --git a/app/src/main/java/com/certified/notes/ui/Main/MainActivity.kt b/app/src/main/java/com/certified/notes/ui/Main/MainActivity.kt index 3f623d1..05f6fd6 100644 --- a/app/src/main/java/com/certified/notes/ui/Main/MainActivity.kt +++ b/app/src/main/java/com/certified/notes/ui/Main/MainActivity.kt @@ -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 @@ -154,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) @@ -176,7 +176,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener { val GRADE_POINT_NOT_SET = 0 if (courseCode.isNotEmpty() && courseTitle.isNotEmpty()) { val course = Course( - courseCode, + 0, courseCode, courseTitle, courseUnit, MARK_NOT_SET, @@ -195,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) @@ -208,7 +208,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener { btnSave.setOnClickListener { val todoContent: String = etTodo.text.toString() if (todoContent.isNotEmpty()) { - val todo = Todo(todoContent, false) + val todo = Todo(0, todoContent, false) notesViewModel.insertTodo(todo) bottomSheetDialog.dismiss() } else @@ -220,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) @@ -232,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) { @@ -257,7 +257,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener { if (noteTitle.isNotEmpty() && noteContent.isNotEmpty()) { if (courseTitle != getString(R.string.select_a_course)) { - val note = Note(courseCode, noteTitle, noteContent) + val note = Note(0, courseCode, noteTitle, noteContent) notesViewModel.insertNote(note) bottomSheetDialog.dismiss() Toast.makeText(this, getString(R.string.note_saved), Toast.LENGTH_LONG).show() diff --git a/app/src/main/java/com/certified/notes/ui/Main/MainActivityViewModel.kt b/app/src/main/java/com/certified/notes/ui/Main/MainActivityViewModel.kt index fc7e2a2..e614b4b 100644 --- a/app/src/main/java/com/certified/notes/ui/Main/MainActivityViewModel.kt +++ b/app/src/main/java/com/certified/notes/ui/Main/MainActivityViewModel.kt @@ -3,8 +3,11 @@ package com.certified.notes.ui.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) { @@ -17,23 +20,33 @@ class MainActivityViewModel(application: Application) : AndroidViewModel(applica val user: LiveData = repository.user fun insertNote(note: Note) { - repository.insertNote(note) + viewModelScope.launch(Dispatchers.IO) { + repository.insertNote(note) + } } fun insertCourse(course: Course) { - repository.insertCourse(course) + viewModelScope.launch(Dispatchers.IO) { + repository.insertCourse(course) + } } fun insertTodo(todo: Todo) { - repository.insertTodo(todo) + viewModelScope.launch(Dispatchers.IO) { + repository.insertTodo(todo) + } } fun updateNote(note: Note) { - repository.updateNote(note) + viewModelScope.launch(Dispatchers.IO) { + repository.updateNote(note) + } } fun updateCourse(course: Course) { - repository.updateCourse(course) + viewModelScope.launch(Dispatchers.IO) { + repository.updateCourse(course) + } } fun deleteAllCourses() { diff --git a/app/src/main/java/com/certified/notes/ui/Notes/NotesFragment.kt b/app/src/main/java/com/certified/notes/ui/Notes/NotesFragment.kt index aef5bc1..e79ddb2 100644 --- a/app/src/main/java/com/certified/notes/ui/Notes/NotesFragment.kt +++ b/app/src/main/java/com/certified/notes/ui/Notes/NotesFragment.kt @@ -1,7 +1,6 @@ package com.certified.notes.ui.Notes import android.content.SharedPreferences -import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.MenuItem @@ -18,7 +17,6 @@ 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 @@ -73,8 +71,8 @@ class NotesFragment : 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 NotesFragment : 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,10 @@ class NotesFragment : 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 = if (note.courseCode != getString(R.string.nil)) + adapterCourses.getPosition(note.courseCode.let { viewModel.getCourseTitle(it) }) else 1 spinnerCourses.setSelection(coursePosition) @@ -137,9 +135,8 @@ class NotesFragment : 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) { - val note1 = Note(courseCode, noteTitle, noteContent) - note1.id = note!!.id + if (courseCode != note.courseCode || noteTitle != note.title || noteContent != note.content) { + val note1 = Note(note.id, courseCode, noteTitle, noteContent) viewModel.updateNote(note1) viewModel.getBookMarkAt(note.id) ?.observe(viewLifecycleOwner) { bookMarks -> @@ -147,12 +144,12 @@ class NotesFragment : Fragment(), PopupMenu.OnMenuItemClickListener { val noteId = note1.id for (bookMark in bookMarks) { val bookMark1 = BookMark( + bookMark.id, noteId, courseCode, noteTitle, noteContent ) - bookMark1.id = bookMark.id viewModel.updateBookMark(bookMark1) } } @@ -222,7 +219,8 @@ class NotesFragment : 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 +270,13 @@ class NotesFragment : 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(0, noteId, courseCode, noteTitle, noteContent!!) viewModel.getBookMarkAt(noteId) ?.observe(viewLifecycleOwner) { bookMarks -> @@ -296,13 +294,23 @@ class NotesFragment : 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 +319,17 @@ class NotesFragment : 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/ui/Notes/NotesViewModel.kt b/app/src/main/java/com/certified/notes/ui/Notes/NotesViewModel.kt index bbfca45..40b899f 100644 --- a/app/src/main/java/com/certified/notes/ui/Notes/NotesViewModel.kt +++ b/app/src/main/java/com/certified/notes/ui/Notes/NotesViewModel.kt @@ -3,32 +3,42 @@ package com.certified.notes.ui.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.model.Todo import com.certified.notes.util.Repository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch -class NotesViewModel(application: Application): AndroidViewModel(application) { +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) { - repository.insertBookMark(bookMark) + viewModelScope.launch(Dispatchers.IO) { + repository.insertBookMark(bookMark) + } } fun updateNote(note: Note) { - repository.updateNote(note) + viewModelScope.launch(Dispatchers.IO) { + repository.updateNote(note) + } } fun updateBookMark(bookMark: BookMark) { - repository.updateBookMark(bookMark) + viewModelScope.launch(Dispatchers.IO) { + repository.updateBookMark(bookMark) + } } fun deleteNote(note: Note) { - repository.deleteNote(note) + viewModelScope.launch(Dispatchers.IO) { + repository.deleteNote(note) + } } fun deleteAllNotes() { diff --git a/app/src/main/java/com/certified/notes/ui/Profile/ProfileFragment.kt b/app/src/main/java/com/certified/notes/ui/Profile/ProfileFragment.kt index f3bfdf9..24f019e 100644 --- a/app/src/main/java/com/certified/notes/ui/Profile/ProfileFragment.kt +++ b/app/src/main/java/com/certified/notes/ui/Profile/ProfileFragment.kt @@ -29,6 +29,7 @@ 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 @@ -152,6 +153,13 @@ class ProfileFragment : Fragment(), View.OnClickListener { } } + 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() @@ -185,8 +193,7 @@ class ProfileFragment : Fragment(), View.OnClickListener { } private fun deleteProfilePicture() { - val user = User(userName, userSchool, userDepartment, userLevel, null) - user.id = USER_ID + val user = User(USER_ID, userName, userSchool, userDepartment, userLevel, null) viewModel.updateUser(user) } @@ -221,8 +228,7 @@ class ProfileFragment : Fragment(), View.OnClickListener { val department = tvDepartment.text.toString() val level = tvLevel.text.toString() - val user = User(name, school, department, level, profileImageBitmap) - user.id = USER_ID + val user = User(USER_ID, name, school, department, level, profileImageBitmap) viewModel.updateUser(user) Glide.with(requireContext()) @@ -234,8 +240,7 @@ class ProfileFragment : Fragment(), View.OnClickListener { 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 + val user = User(USER_ID, userName, userSchool, userDepartment, userLevel, bitmap) viewModel.updateUser(user) Glide.with(requireContext()) .load(bitmap) @@ -273,8 +278,7 @@ class ProfileFragment : Fragment(), View.OnClickListener { val level = tvLevel.text.toString().trim() if (!isEmpty(name)) { if (name != userName) { - val user = User(name, school, department, level, profileImageBitmap) - user.id = USER_ID + val user = User(USER_ID, name, school, department, level, profileImageBitmap) viewModel.updateUser(user) tvName.text = name } else Toast.makeText(context, "Name not changed", Toast.LENGTH_SHORT).show() @@ -313,8 +317,7 @@ class ProfileFragment : Fragment(), View.OnClickListener { val level = tvLevel.text.toString().trim() if (!isEmpty(school)) { if (school != userSchool) { - val user = User(name, school, department, level, profileImageBitmap) - user.id = USER_ID + val user = User(USER_ID, name, school, department, level, profileImageBitmap) viewModel.updateUser(user) tvSchool.text = school } else Toast.makeText(context, "School not changed", Toast.LENGTH_SHORT).show() @@ -352,8 +355,7 @@ class ProfileFragment : Fragment(), View.OnClickListener { val level = tvLevel.text.toString().trim() if (!isEmpty(department)) { if (department != userDepartment) { - val user = User(name, school, department, level, profileImageBitmap) - user.id = USER_ID + val user = User(USER_ID, name, school, department, level, profileImageBitmap) viewModel.updateUser(user) tvDepartment.text = department } else Toast.makeText(context, "Department not changed", Toast.LENGTH_SHORT).show() @@ -398,8 +400,7 @@ class ProfileFragment : Fragment(), View.OnClickListener { 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 + val user = User(USER_ID, name, school, department, level, profileImageBitmap) viewModel.updateUser(user) tvLevel.text = level } else Toast.makeText(context, "Level not changed", Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/com/certified/notes/ui/Profile/ProfileViewModel.kt b/app/src/main/java/com/certified/notes/ui/Profile/ProfileViewModel.kt index 54bdd04..5c9f110 100644 --- a/app/src/main/java/com/certified/notes/ui/Profile/ProfileViewModel.kt +++ b/app/src/main/java/com/certified/notes/ui/Profile/ProfileViewModel.kt @@ -3,16 +3,21 @@ package com.certified.notes.ui.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) { +class ProfileViewModel(application: Application) : AndroidViewModel(application) { private val repository = Repository(application) val user: LiveData = repository.user fun updateUser(user: User) { - repository.updateUser(user) + viewModelScope.launch(Dispatchers.IO) { + repository.updateUser(user) + } } } \ 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 From c4c7c9852aec7c10e0939a324aa528ddceb4327f Mon Sep 17 00:00:00 2001 From: Sammie_kt Date: Mon, 13 Sep 2021 12:05:45 +0100 Subject: [PATCH 4/4] Refactor code, fixed minor bugs. Issue with using coroutine to be fixed in next commit. --- .idea/gradle.xml | 4 +- app/build.gradle | 14 +++--- app/src/main/AndroidManifest.xml | 2 +- .../notes/adapters/ResultRecyclerAdapter.kt | 4 +- .../notes/adapters/TodoRecyclerAdapter.kt | 5 +- .../com/certified/notes/model/BookMark.kt | 7 +-- .../java/com/certified/notes/model/Course.kt | 7 +-- .../java/com/certified/notes/model/Note.kt | 7 +-- .../java/com/certified/notes/model/Result.kt | 7 +-- .../java/com/certified/notes/model/Todo.kt | 7 +-- .../java/com/certified/notes/model/User.kt | 7 +-- .../com/certified/notes/room/NotesDatabase.kt | 48 +++++++++---------- .../certified/notes/util/TestingPractice.kt | 11 +++++ .../BookMarks/BookMarksFragment.kt | 12 ++--- .../BookMarks/BookMarksViewModel.kt | 2 +- .../BookMarks/BookMarksViewModelFactory.kt | 2 +- .../{ui => view}/Courses/CoursesFragmentKt.kt | 13 +++-- .../{ui => view}/Courses/CoursesViewModel.kt | 2 +- .../Courses/CoursesViewModelFactory.kt | 2 +- .../notes/{ui => view}/Home/HomeFragment.kt | 7 ++- .../notes/{ui => view}/Home/HomeViewModel.kt | 2 +- .../{ui => view}/Home/HomeViewModelFactory.kt | 2 +- .../notes/{ui => view}/Main/MainActivity.kt | 8 ++-- .../Main/MainActivityViewModel.kt | 2 +- .../notes/{ui => view}/Notes/NotesFragment.kt | 17 +++++-- .../{ui => view}/Notes/NotesViewModel.kt | 2 +- .../Notes/NotesViewModelFactory.kt | 2 +- .../notes/{ui => view}/OnboardingFragment.kt | 4 +- .../{ui => view}/Profile/ProfileFragment.kt | 23 +++++---- .../{ui => view}/Profile/ProfileViewModel.kt | 2 +- .../Profile/ProfileViewModelFactory.kt | 2 +- .../notes/{ui => view}/ResultFragment.java | 4 +- .../notes/{ui => view}/SplashFragment.kt | 4 +- .../main/res/layout-land/fragment_home.xml | 2 +- .../res/layout-land/fragment_onboarding.xml | 2 +- .../main/res/layout-land/fragment_profile.xml | 2 +- .../main/res/layout-land/fragment_result.xml | 2 +- .../res/layout-sw600dp-land/fragment_home.xml | 2 +- .../fragment_onboarding.xml | 2 +- .../res/layout-sw600dp-v21/activity_main.xml | 2 +- .../main/res/layout-sw600dp/activity_main.xml | 2 +- .../layout-sw600dp/fragment_book_marks.xml | 2 +- .../res/layout-sw600dp/fragment_courses.xml | 2 +- .../main/res/layout-sw600dp/fragment_home.xml | 2 +- .../res/layout-sw600dp/fragment_notes.xml | 2 +- .../layout-sw600dp/fragment_onboarding.xml | 2 +- .../res/layout-sw600dp/fragment_profile.xml | 2 +- .../res/layout-sw600dp/fragment_result.xml | 2 +- app/src/main/res/layout-v21/activity_main.xml | 2 +- .../res/layout-v21/fragment_book_marks.xml | 2 +- .../main/res/layout-v21/fragment_courses.xml | 2 +- .../main/res/layout-v21/fragment_notes.xml | 2 +- app/src/main/res/layout/activity_main.xml | 2 +- .../main/res/layout/fragment_book_marks.xml | 2 +- app/src/main/res/layout/fragment_courses.xml | 2 +- app/src/main/res/layout/fragment_home.xml | 2 +- app/src/main/res/layout/fragment_notes.xml | 2 +- .../main/res/layout/fragment_onboarding.xml | 2 +- app/src/main/res/layout/fragment_profile.xml | 2 +- app/src/main/res/layout/fragment_result.xml | 2 +- app/src/main/res/layout/fragment_splash.xml | 2 +- app/src/main/res/navigation/nav_graph.xml | 16 +++---- .../certified/notes/util/RepositoryTest.kt | 21 ++++++++ build.gradle | 7 +++ 64 files changed, 198 insertions(+), 146 deletions(-) create mode 100644 app/src/main/java/com/certified/notes/util/TestingPractice.kt rename app/src/main/java/com/certified/notes/{ui => view}/BookMarks/BookMarksFragment.kt (97%) rename app/src/main/java/com/certified/notes/{ui => view}/BookMarks/BookMarksViewModel.kt (97%) rename app/src/main/java/com/certified/notes/{ui => view}/BookMarks/BookMarksViewModelFactory.kt (91%) rename app/src/main/java/com/certified/notes/{ui => view}/Courses/CoursesFragmentKt.kt (98%) rename app/src/main/java/com/certified/notes/{ui => view}/Courses/CoursesViewModel.kt (98%) rename app/src/main/java/com/certified/notes/{ui => view}/Courses/CoursesViewModelFactory.kt (91%) rename app/src/main/java/com/certified/notes/{ui => view}/Home/HomeFragment.kt (98%) rename app/src/main/java/com/certified/notes/{ui => view}/Home/HomeViewModel.kt (96%) rename app/src/main/java/com/certified/notes/{ui => view}/Home/HomeViewModelFactory.kt (92%) rename app/src/main/java/com/certified/notes/{ui => view}/Main/MainActivity.kt (98%) rename app/src/main/java/com/certified/notes/{ui => view}/Main/MainActivityViewModel.kt (98%) rename app/src/main/java/com/certified/notes/{ui => view}/Notes/NotesFragment.kt (96%) rename app/src/main/java/com/certified/notes/{ui => view}/Notes/NotesViewModel.kt (98%) rename app/src/main/java/com/certified/notes/{ui => view}/Notes/NotesViewModelFactory.kt (92%) rename app/src/main/java/com/certified/notes/{ui => view}/OnboardingFragment.kt (95%) rename app/src/main/java/com/certified/notes/{ui => view}/Profile/ProfileFragment.kt (95%) rename app/src/main/java/com/certified/notes/{ui => view}/Profile/ProfileViewModel.kt (93%) rename app/src/main/java/com/certified/notes/{ui => view}/Profile/ProfileViewModelFactory.kt (92%) rename app/src/main/java/com/certified/notes/{ui => view}/ResultFragment.java (97%) rename app/src/main/java/com/certified/notes/{ui => view}/SplashFragment.kt (98%) create mode 100644 app/src/test/java/com/certified/notes/util/RepositoryTest.kt diff --git a/.idea/gradle.xml b/.idea/gradle.xml index f6f861c..0818cfa 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -7,8 +7,8 @@