Skip to content

Commit ad0c690

Browse files
Implemented Notes CRUD operations
1 parent 431cae4 commit ad0c690

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+622
-268
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
android:theme="@style/Theme.Mvvm_notes_app"
1717
tools:targetApi="31">
1818
<activity
19-
android:name=".MainActivity"
19+
android:name=".views.MainActivity"
2020
android:exported="true">
2121
<intent-filter>
2222
<action android:name="android.intent.action.MAIN" />
13.2 KB
Loading

app/src/main/java/com/tharunbalaji/mvvm_notes_app/MainFragment.kt

Lines changed: 0 additions & 18 deletions
This file was deleted.

app/src/main/java/com/tharunbalaji/mvvm_notes_app/NoteFragment.kt

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.tharunbalaji.mvvm_notes_app.adapters
2+
3+
4+
import android.view.LayoutInflater
5+
import android.view.ViewGroup
6+
import androidx.recyclerview.widget.DiffUtil
7+
import androidx.recyclerview.widget.RecyclerView
8+
import com.tharunbalaji.mvvm_notes_app.databinding.NoteItemBinding
9+
import com.tharunbalaji.mvvm_notes_app.models.NoteResponse
10+
import androidx.recyclerview.widget.ListAdapter
11+
12+
class NoteAdapter(private val onNoteClicked: (NoteResponse) -> Unit) : ListAdapter<NoteResponse, NoteAdapter.NoteViewHolder>(ComparatorDiffUtil()) {
13+
14+
inner class NoteViewHolder(private val binding: NoteItemBinding): RecyclerView.ViewHolder(binding.root) {
15+
fun bind(note: NoteResponse) {
16+
binding.title.text = note.title
17+
binding.desc.text = note.description
18+
binding.root.setOnClickListener {
19+
onNoteClicked(note)
20+
}
21+
}
22+
}
23+
24+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder {
25+
val view = NoteItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
26+
return NoteViewHolder(view)
27+
}
28+
29+
override fun onBindViewHolder(holder: NoteViewHolder, position: Int) {
30+
val note = getItem(position)
31+
holder.bind(note)
32+
}
33+
34+
class ComparatorDiffUtil: DiffUtil.ItemCallback<NoteResponse>() {
35+
override fun areItemsTheSame(oldItem: NoteResponse, newItem: NoteResponse): Boolean {
36+
return oldItem._id == newItem._id
37+
}
38+
39+
override fun areContentsTheSame(oldItem: NoteResponse, newItem: NoteResponse): Boolean {
40+
return oldItem == newItem
41+
}
42+
}
43+
44+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.tharunbalaji.mvvm_notes_app.api
2+
3+
import com.tharunbalaji.mvvm_notes_app.utils.TokenManager
4+
import okhttp3.Interceptor
5+
import okhttp3.Response
6+
import javax.inject.Inject
7+
8+
class AuthInterceptor @Inject constructor(): Interceptor {
9+
@Inject
10+
lateinit var tokenManager: TokenManager
11+
12+
override fun intercept(chain: Interceptor.Chain): Response {
13+
val request = chain.request().newBuilder()
14+
val token = tokenManager.getToken()
15+
16+
request.addHeader("Authorization","Bearer $token")
17+
18+
return chain.proceed(request.build())
19+
}
20+
}
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package com.tharunbalaji.mvvm_notes_app.di
22

3+
import com.tharunbalaji.mvvm_notes_app.api.AuthInterceptor
4+
import com.tharunbalaji.mvvm_notes_app.api.NotesAPI
35
import com.tharunbalaji.mvvm_notes_app.api.UserAPI
46
import com.tharunbalaji.mvvm_notes_app.utils.Constants.BASE_URL
57
import dagger.Module
68
import dagger.Provides
79
import dagger.hilt.InstallIn
810
import dagger.hilt.components.SingletonComponent
11+
import okhttp3.OkHttpClient
912
import retrofit2.Retrofit
1013
import retrofit2.converter.gson.GsonConverterFactory
1114
import javax.inject.Singleton
@@ -16,16 +19,28 @@ class NetworkModule {
1619

1720
@Singleton
1821
@Provides
19-
fun providesRetrofit(): Retrofit {
22+
fun providesRetrofitBuilder(): Retrofit.Builder {
2023
return Retrofit.Builder()
2124
.baseUrl(BASE_URL)
2225
.addConverterFactory(GsonConverterFactory.create())
23-
.build()
2426
}
2527

2628
@Singleton
2729
@Provides
28-
fun providesUserAPI(retrofit: Retrofit): UserAPI {
29-
return retrofit.create(UserAPI::class.java)
30+
fun providesUserAPI(retrofitBuilder: Retrofit.Builder): UserAPI {
31+
return retrofitBuilder.build().create(UserAPI::class.java)
32+
}
33+
34+
@Singleton
35+
@Provides
36+
fun providesNotesAPI(retrofitBuilder: Retrofit.Builder, okHttpClient: OkHttpClient): NotesAPI {
37+
return retrofitBuilder.client(okHttpClient)
38+
.build().create(NotesAPI::class.java)
39+
}
40+
41+
@Singleton
42+
@Provides
43+
fun providesOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient {
44+
return OkHttpClient.Builder().addInterceptor(authInterceptor).build()
3045
}
3146
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.tharunbalaji.mvvm_notes_app.repository
2+
3+
import androidx.lifecycle.LiveData
4+
import androidx.lifecycle.MutableLiveData
5+
import com.tharunbalaji.mvvm_notes_app.api.NotesAPI
6+
import com.tharunbalaji.mvvm_notes_app.models.NoteRequest
7+
import com.tharunbalaji.mvvm_notes_app.models.NoteResponse
8+
import com.tharunbalaji.mvvm_notes_app.models.UserResponse
9+
import com.tharunbalaji.mvvm_notes_app.utils.NetworkResult
10+
import org.json.JSONObject
11+
import retrofit2.Response
12+
import javax.inject.Inject
13+
14+
class NoteRepository @Inject constructor(private val notesAPI: NotesAPI) {
15+
16+
private val _notesLiveData = MutableLiveData<NetworkResult<List<NoteResponse>>>()
17+
val notesLiveData: LiveData<NetworkResult<List<NoteResponse>>> = _notesLiveData
18+
19+
private val _statusLiveData = MutableLiveData<NetworkResult<String>>()
20+
val statusLiveData: LiveData<NetworkResult<String>> = _statusLiveData
21+
22+
suspend fun getNotes() {
23+
_notesLiveData.postValue(NetworkResult.Loading())
24+
val response = notesAPI.getNotes()
25+
if (response.isSuccessful && response.body() != null) { // Success
26+
_notesLiveData.postValue(NetworkResult.Success(response.body()!!))
27+
} else if (response.errorBody() != null) { // Error occurred
28+
val errorObj = JSONObject(response.errorBody()!!.charStream().readText())
29+
_notesLiveData.postValue(NetworkResult.Error(errorObj.getString("message")))
30+
} else {
31+
_notesLiveData.postValue(NetworkResult.Error("Something went wrong"))
32+
}
33+
}
34+
35+
suspend fun createNote(noteRequest: NoteRequest) {
36+
_statusLiveData.postValue(NetworkResult.Loading())
37+
val response = notesAPI.createNotes(noteRequest)
38+
handleResponse(response, "Note Created")
39+
}
40+
41+
suspend fun deleteNote(noteId: String) {
42+
_statusLiveData.postValue(NetworkResult.Loading())
43+
val response = notesAPI.deleteNote(noteId)
44+
handleResponse(response, "Note Deleted")
45+
}
46+
47+
suspend fun updateNote(noteId: String,noteRequest: NoteRequest) {
48+
_statusLiveData.postValue(NetworkResult.Loading())
49+
val response = notesAPI.updateNote(noteId, noteRequest)
50+
handleResponse(response, "Note Updated")
51+
}
52+
53+
private fun handleResponse(response: Response<NoteResponse>, successMsg: String) {
54+
if (response.isSuccessful && response.body() != null) {
55+
_statusLiveData.postValue(NetworkResult.Success(successMsg))
56+
} else {
57+
_statusLiveData.postValue(NetworkResult.Error("Something went wrong"))
58+
}
59+
}
60+
61+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.tharunbalaji.mvvm_notes_app.viewmodels
2+
3+
import androidx.lifecycle.ViewModel
4+
import androidx.lifecycle.viewModelScope
5+
import com.tharunbalaji.mvvm_notes_app.models.NoteRequest
6+
import com.tharunbalaji.mvvm_notes_app.repository.NoteRepository
7+
import dagger.hilt.android.lifecycle.HiltViewModel
8+
import kotlinx.coroutines.launch
9+
import javax.inject.Inject
10+
11+
@HiltViewModel
12+
class NoteViewModel @Inject constructor(private val noteRepository: NoteRepository): ViewModel() {
13+
14+
val notesLiveData = noteRepository.notesLiveData
15+
val statusLiveData = noteRepository.statusLiveData
16+
17+
fun getNotes(){
18+
viewModelScope.launch {
19+
noteRepository.getNotes()
20+
}
21+
}
22+
23+
fun createNote(noteRequest: NoteRequest) {
24+
viewModelScope.launch {
25+
noteRepository.createNote(noteRequest)
26+
}
27+
}
28+
29+
fun updateNote(noteId: String, noteRequest: NoteRequest) {
30+
viewModelScope.launch {
31+
noteRepository.updateNote(noteId, noteRequest)
32+
}
33+
}
34+
35+
fun deleteNote(noteId: String) {
36+
viewModelScope.launch {
37+
noteRepository.deleteNote(noteId)
38+
}
39+
}
40+
}

app/src/main/java/com/tharunbalaji/mvvm_notes_app/LoginFragment.kt renamed to app/src/main/java/com/tharunbalaji/mvvm_notes_app/views/LoginFragment.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.tharunbalaji.mvvm_notes_app
1+
package com.tharunbalaji.mvvm_notes_app.views
22

33
import android.os.Bundle
44
import androidx.fragment.app.Fragment
@@ -8,6 +8,7 @@ import android.view.ViewGroup
88
import androidx.core.view.isVisible
99
import androidx.fragment.app.viewModels
1010
import androidx.navigation.fragment.findNavController
11+
import com.tharunbalaji.mvvm_notes_app.R
1112
import com.tharunbalaji.mvvm_notes_app.databinding.FragmentLoginBinding
1213
import com.tharunbalaji.mvvm_notes_app.models.UserRequest
1314
import com.tharunbalaji.mvvm_notes_app.utils.NetworkResult

0 commit comments

Comments
 (0)