diff --git a/.github/workflows/android_build.yml b/.github/workflows/android_build.yml new file mode 100644 index 0000000..161a071 --- /dev/null +++ b/.github/workflows/android_build.yml @@ -0,0 +1,24 @@ + name: Android Build + + on: commits + + jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + + - name: Set up jdk + uses: actions/setup-java@v1 + + with: + java-version: 1.8 + + - name: Run Tests + run: ./gradlew test + + + - name: Build Project + run: ./ gradlew assemble diff --git a/app/build.gradle b/app/build.gradle index a0366b4..393cf68 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'com.google.gms.google-services' - + id 'kotlin-kapt' } android { @@ -41,6 +41,11 @@ android { dependencies { + //room + implementation "androidx.room:room-runtime:2.4.0" + kapt "androidx.room:room-compiler:2.4.0" + + // retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' @@ -49,6 +54,7 @@ dependencies { implementation 'com.facebook.shimmer:shimmer:0.5.0' + // firebase implementation platform('com.google.firebase:firebase-bom:31.1.0') implementation 'com.google.firebase:firebase-analytics-ktx' implementation 'com.google.firebase:firebase-auth-ktx' diff --git a/app/src/main/java/com/example/dm/data/database/dao/UserDao.kt b/app/src/main/java/com/example/dm/data/database/dao/UserDao.kt new file mode 100644 index 0000000..02705e3 --- /dev/null +++ b/app/src/main/java/com/example/dm/data/database/dao/UserDao.kt @@ -0,0 +1,7 @@ +package com.example.dm.data.database.dao + +import androidx.room.Database +import com.example.dm.data.model.UserInfo + +class UserDao { +} \ No newline at end of file diff --git a/app/src/main/java/com/example/dm/data/database/repository/UserRepository.kt b/app/src/main/java/com/example/dm/data/database/repository/UserRepository.kt new file mode 100644 index 0000000..26c4ee6 --- /dev/null +++ b/app/src/main/java/com/example/dm/data/database/repository/UserRepository.kt @@ -0,0 +1,4 @@ +package com.example.dm.data.database.repository + +class UserRepository { +} \ No newline at end of file diff --git a/app/src/main/java/com/example/dm/data/database/viewmodel/UserViewModel.kt b/app/src/main/java/com/example/dm/data/database/viewmodel/UserViewModel.kt new file mode 100644 index 0000000..76a003f --- /dev/null +++ b/app/src/main/java/com/example/dm/data/database/viewmodel/UserViewModel.kt @@ -0,0 +1,4 @@ +package com.example.dm.data.database.viewmodel + +class UserViewModel { +} \ No newline at end of file diff --git a/app/src/main/java/com/example/dm/data/repository/Repository.kt b/app/src/main/java/com/example/dm/data/repository/Repository.kt index 98231c4..65b5730 100644 --- a/app/src/main/java/com/example/dm/data/repository/Repository.kt +++ b/app/src/main/java/com/example/dm/data/repository/Repository.kt @@ -1,27 +1,53 @@ package com.example.dm.data.repository +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.widget.Toast import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat.startActivity import com.example.dm.R import com.example.dm.data.model.Message import com.example.dm.data.model.UserInfo import com.example.dm.notification.NotificationModel import com.example.dm.notification.PushNotification import com.example.dm.notification.api.ApiUtlis +import com.example.dm.presentation.activity.MainActivity import com.example.dm.utils.ConstUtils.channelId import com.example.dm.utils.ConstUtils.message import com.example.dm.utils.FirebaseUtils import com.example.dm.utils.FirebaseUtils.chatRef import com.example.dm.utils.FirebaseUtils.firebaseAuth import com.example.dm.utils.FirebaseUtils.firebaseDatabase +import com.example.dm.utils.FirebaseUtils.storageRef import com.example.dm.utils.FirebaseUtils.userRef import com.google.firebase.database.DataSnapshot import com.google.firebase.database.DatabaseError import com.google.firebase.database.ValueEventListener import retrofit2.Call import retrofit2.Response +import java.util.* class Repository { + /* + create user + */ + fun createUser(name: String, phoneNumber: String, imgUri: String, fcmToken: String, uid: String) { + + val user = UserInfo( + uid = uid, + name = name, + phonenumber = phoneNumber, + imgUri = imgUri, + activeStatus = "online", + about = "", + fcm_token = fcmToken + ) + + userRef.child(uid).setValue(user) + } + // fun to check user is created or not fun getUserList(callback: (List) -> Unit) { val userList = mutableListOf() @@ -158,5 +184,21 @@ class Repository { .setValue(user) } + /* + upload data + */ + fun uploadFileToStorage(uri: Uri, callback: (String?) -> Unit) { + val reference = storageRef.child(Date().time.toString()) + reference.putFile(uri).addOnCompleteListener { task -> + if (task.isSuccessful) { + reference.downloadUrl.addOnSuccessListener { uri -> + callback(uri.toString()) + } + } else { + callback(null) + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/dm/data/viewmodel/ViewModel.kt b/app/src/main/java/com/example/dm/data/viewmodel/ViewModel.kt index d271c24..e939fca 100644 --- a/app/src/main/java/com/example/dm/data/viewmodel/ViewModel.kt +++ b/app/src/main/java/com/example/dm/data/viewmodel/ViewModel.kt @@ -1,12 +1,17 @@ package com.example.dm.data.viewmodel +import android.net.Uri +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import com.example.dm.data.model.Message import com.example.dm.data.model.UserInfo import com.example.dm.data.repository.Repository -import com.example.dm.utils.FirebaseUtils class ViewModel(private val repository: Repository = Repository()): androidx.lifecycle.ViewModel() { + private val _createUserSuccess = MutableLiveData() + val createUserSuccess: LiveData = _createUserSuccess + /* function to get User List */ @@ -55,4 +60,20 @@ class ViewModel(private val repository: Repository = Repository()): androidx.lif repository.addContact(user) } + /* + create user + */ + fun createUser(name: String, phoneNumber: String, imgUri: String, fcmToken: String, uid: String) { + repository.createUser(name, phoneNumber, imgUri, fcmToken, uid) + _createUserSuccess.value = true + } + + /* + upload data + */ + fun uploadFileToStorage(uri: Uri, callback: (String?) -> Unit) { + repository.uploadFileToStorage(uri) { url -> + callback(url) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/dm/presentation/account/Number.kt b/app/src/main/java/com/example/dm/presentation/account/Number.kt index 1ae6cde..ee6fa65 100644 --- a/app/src/main/java/com/example/dm/presentation/account/Number.kt +++ b/app/src/main/java/com/example/dm/presentation/account/Number.kt @@ -36,17 +36,21 @@ class Number : AppCompatActivity() { // go to otp activity binding.getOtp.setOnClickListener { number = binding.numberEt.editText!!.text.toString() - if (checkEditText()) { - val intent = Intent(this, OTP::class.java) - intent.putExtra("number", number) - startActivity(intent) - finish() + if (checkEditText(number)) { + goToOTPActivity() } else { Toast.makeText(this, "enter correct number", Toast.LENGTH_SHORT).show() } } } + private fun goToOTPActivity() { + val intent = Intent(this, OTP::class.java) + intent.putExtra("number", number) + startActivity(intent) + finish() + } + fun goToSignup() { if(firebaseUser != null) { startActivity(Intent(this, MainActivity::class.java)) @@ -55,7 +59,7 @@ class Number : AppCompatActivity() { } // function to check edittext is empty or not - fun checkEditText(): Boolean { + fun checkEditText(number: String): Boolean { if (number.isNotEmpty() && number.length == 10) { return true diff --git a/app/src/main/java/com/example/dm/presentation/account/OTP.kt b/app/src/main/java/com/example/dm/presentation/account/OTP.kt index 73d2fef..489f9f2 100644 --- a/app/src/main/java/com/example/dm/presentation/account/OTP.kt +++ b/app/src/main/java/com/example/dm/presentation/account/OTP.kt @@ -2,18 +2,14 @@ package com.example.dm.presentation.account import android.content.Intent import android.os.Bundle -import android.util.Log import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider -import com.example.dm.presentation.activity.MainActivity -import com.example.dm.databinding.ActivityOtpBinding -import com.example.dm.data.model.UserInfo import com.example.dm.data.viewmodel.ViewModel +import com.example.dm.databinding.ActivityOtpBinding import com.example.dm.presentation.temp import com.example.dm.utils.DialogUtils.buildLoadingDialog -import com.example.dm.utils.FirebaseUtils import com.example.dm.utils.FirebaseUtils.firebaseAuth import com.example.dm.utils.FirebaseUtils.firebaseUser import com.example.dm.utils.FirebaseUtils.userRef @@ -22,9 +18,6 @@ import com.google.firebase.FirebaseException import com.google.firebase.auth.PhoneAuthCredential import com.google.firebase.auth.PhoneAuthOptions import com.google.firebase.auth.PhoneAuthProvider -import com.google.firebase.database.DataSnapshot -import com.google.firebase.database.DatabaseError -import com.google.firebase.database.ValueEventListener import com.google.firebase.messaging.FirebaseMessaging import java.util.concurrent.TimeUnit diff --git a/app/src/main/java/com/example/dm/presentation/account/Profile.kt b/app/src/main/java/com/example/dm/presentation/account/Profile.kt index 38ec0db..33aec69 100644 --- a/app/src/main/java/com/example/dm/presentation/account/Profile.kt +++ b/app/src/main/java/com/example/dm/presentation/account/Profile.kt @@ -8,15 +8,13 @@ import android.net.Uri import android.os.Bundle import android.provider.MediaStore import android.provider.Settings -import android.util.Log import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider -import com.example.dm.presentation.activity.MainActivity -import com.example.dm.databinding.ActivityProfileBinding -import com.example.dm.data.model.UserInfo import com.example.dm.data.viewmodel.ViewModel +import com.example.dm.databinding.ActivityProfileBinding +import com.example.dm.presentation.activity.MainActivity import com.example.dm.utils.DialogUtils import com.example.dm.utils.FirebaseUtils import com.google.android.gms.tasks.OnCompleteListener @@ -40,6 +38,7 @@ class Profile : AppCompatActivity() { private lateinit var database: FirebaseDatabase private lateinit var auth: FirebaseAuth private lateinit var binding: ActivityProfileBinding + private lateinit var viewModel: ViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -51,7 +50,7 @@ class Profile : AppCompatActivity() { private fun variableInit() { - + viewModel = ViewModelProvider(this)[ViewModel::class.java] dialog = DialogUtils.buildLoadingDialog(this@Profile) storage = FirebaseUtils.firebaseStorage database = FirebaseUtils.firebaseDatabase @@ -66,27 +65,18 @@ class Profile : AppCompatActivity() { // finish button binding.finishBtn.setOnClickListener { - val name = binding.nameEdtxt.text.toString() + val name = binding.nameEdtxt.editText?.text.toString() if (name.isNotEmpty() && check == 1) { dialog.show() - uploadData() + viewModel.uploadFileToStorage(contentUri) { url -> + uploadDataInfo(url!!) + } } else { Toast.makeText(this@Profile, "Enter your name", Toast.LENGTH_SHORT).show() } } } - // function to upload data of newly created user - private fun uploadData() { - val reference = storage.reference.child("Profile").child(Date().time.toString()) - reference.putFile(contentUri).addOnCompleteListener { task -> - if (task.isSuccessful) { - reference.downloadUrl.addOnSuccessListener { uri -> - uploadDataInfo(uri.toString()) - } - } - } - } // function to create user private fun uploadDataInfo(imgUri: String) { @@ -99,29 +89,30 @@ class Profile : AppCompatActivity() { // Get new FCM registration token val token = task.result - - println("fcm token $token") - val user = UserInfo( - uid = auth.uid.toString(), - name = binding.nameEdtxt.text.toString(), - phonenumber = auth.currentUser?.phoneNumber.toString(), + val uid = auth.uid.toString() + val name = binding.nameEdtxt.editText?.text.toString() + val phoneNumber = auth.currentUser?.phoneNumber.toString() + + viewModel.createUser( + uid = uid, + name = name, + phoneNumber = phoneNumber, imgUri = imgUri, - activeStatus = "online", - about = "", - fcm_token = token + fcmToken = token ) - database.reference.child("users") - .child(auth.uid.toString()) - .setValue(user) - .addOnSuccessListener { - dialog.dismiss() - Toast.makeText(this@Profile, "User Created", Toast.LENGTH_SHORT).show() - startActivity(Intent(this@Profile, MainActivity::class.java)) + + viewModel.createUserSuccess.observe(this) { success -> + if (success) { + // User creation was successful, navigate to the next screen + val intent = Intent(this, MainActivity::class.java) + startActivity(intent) finish() + } else { + // User creation failed, show an error message + Toast.makeText(this, "Failed to create user", Toast.LENGTH_SHORT).show() } - - + } }) } @@ -149,15 +140,14 @@ class Profile : AppCompatActivity() { ) { showDialogForPermissions() } - }).onSameThread().check(); + }).onSameThread().check() } // function for storage permission fun showDialogForPermissions() { AlertDialog.Builder(this@Profile).setMessage( - "" + - "Allow permission to use this feature" + "Allow permission to use this feature" ).setPositiveButton("Go to Settings") { _, _ -> try { val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) diff --git a/app/src/main/java/com/example/dm/presentation/activity/MainActivity.kt b/app/src/main/java/com/example/dm/presentation/activity/MainActivity.kt index 610e5ef..3964c7c 100644 --- a/app/src/main/java/com/example/dm/presentation/activity/MainActivity.kt +++ b/app/src/main/java/com/example/dm/presentation/activity/MainActivity.kt @@ -1,16 +1,12 @@ package com.example.dm.presentation.activity -import android.app.AlertDialog import android.app.Dialog import android.content.Intent import android.os.Bundle import android.view.Menu import android.view.MenuItem -import android.widget.Button -import android.widget.EditText import android.widget.Toast import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.ContentProviderCompat.requireContext import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import com.example.dm.R @@ -22,9 +18,6 @@ import com.example.dm.presentation.adapter.ViewPagerAdapter import com.example.dm.presentation.ui.chat import com.example.dm.presentation.ui.status import com.example.dm.utils.DialogUtils -import com.example.dm.utils.FirebaseUtils.contactRef -import com.example.dm.utils.FirebaseUtils.firebaseAuth -import com.example.dm.utils.FirebaseUtils.firebaseDatabase class MainActivity : AppCompatActivity() { @@ -41,13 +34,16 @@ class MainActivity : AppCompatActivity() { // initialisation of declared variable binding = ActivityMainBinding.inflate(layoutInflater) dialogBinding = SearchAlertDialogBinding.inflate(layoutInflater) + setContentView(binding.root) + variableInit() + subscribeUi() - setContentView(binding.root) + } + + private fun variableInit() { viewModel = ViewModelProvider(this)[ViewModel::class.java] loadingDialog = DialogUtils.buildLoadingDialog(this@MainActivity) - subscribeUi() - } private fun subscribeUi() { diff --git a/app/src/main/java/com/example/dm/presentation/adapter/ChatAdapter.kt b/app/src/main/java/com/example/dm/presentation/adapter/ChatAdapter.kt index 2fb474e..6ac56af 100644 --- a/app/src/main/java/com/example/dm/presentation/adapter/ChatAdapter.kt +++ b/app/src/main/java/com/example/dm/presentation/adapter/ChatAdapter.kt @@ -36,13 +36,13 @@ class ChatAdapter(var context: Context,var list: List):RecyclerView.Ad // 55 - if(user.activeStatus=="online") { + /* if(user.activeStatus=="online") { holder.binding.onlineStatus.visibility = View.VISIBLE holder.binding.offilneStatus.visibility = View.GONE }else { holder.binding.onlineStatus.visibility = View.GONE holder.binding.offilneStatus.visibility = View.VISIBLE - } + }*/ holder.itemView.setOnClickListener { diff --git a/app/src/main/java/com/example/dm/utils/ConstUtils.kt b/app/src/main/java/com/example/dm/utils/ConstUtils.kt index 029e0c5..2e157ae 100644 --- a/app/src/main/java/com/example/dm/utils/ConstUtils.kt +++ b/app/src/main/java/com/example/dm/utils/ConstUtils.kt @@ -7,6 +7,7 @@ object ConstUtils { const val cancel = "Cancel" const val chats = "chats" const val contact = "contact" + const val profile = "Profile" const val channelId = "DM_ID" diff --git a/app/src/main/java/com/example/dm/utils/FirebaseUtils.kt b/app/src/main/java/com/example/dm/utils/FirebaseUtils.kt index d7a1653..22c812c 100644 --- a/app/src/main/java/com/example/dm/utils/FirebaseUtils.kt +++ b/app/src/main/java/com/example/dm/utils/FirebaseUtils.kt @@ -2,6 +2,7 @@ package com.example.dm.utils import com.example.dm.utils.ConstUtils.chats import com.example.dm.utils.ConstUtils.contact +import com.example.dm.utils.ConstUtils.profile import com.example.dm.utils.ConstUtils.userNode import com.google.firebase.auth.FirebaseAuth import com.google.firebase.database.FirebaseDatabase @@ -19,6 +20,7 @@ object FirebaseUtils { var userRef = firebaseDatabase.getReference(userNode) val chatRef = firebaseDatabase.getReference(chats) val contactRef = firebaseDatabase.getReference(contact) + val storageRef = firebaseStorage.reference.child(profile) } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index eca29c5..7957563 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -63,27 +63,36 @@ android:src="@drawable/ic_baseline_photo_camera_24" /> - + app:layout_constraintTop_toBottomOf="@id/card" + app:startIconDrawable="@drawable/round_person_24"> + + + + - - - -