Finish project

This commit is contained in:
tonywesoly 2022-10-28 02:55:00 +02:00
parent ec8f6bbf54
commit bcc1a1368e
18 changed files with 307 additions and 9 deletions

View File

@ -3,10 +3,15 @@
<component name="DesignSurface"> <component name="DesignSurface">
<option name="filePathToZoomLevelMap"> <option name="filePathToZoomLevelMap">
<map> <map>
<entry key="app/src/main/res/drawable/received_border.xml" value="0.332" />
<entry key="app/src/main/res/layout/activity_chat.xml" value="0.4375" />
<entry key="app/src/main/res/layout/activity_log_in.xml" value="0.4375" /> <entry key="app/src/main/res/layout/activity_log_in.xml" value="0.4375" />
<entry key="app/src/main/res/layout/activity_login.xml" value="0.37083333333333335" /> <entry key="app/src/main/res/layout/activity_login.xml" value="0.37083333333333335" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.35625" /> <entry key="app/src/main/res/layout/activity_main.xml" value="0.35625" />
<entry key="app/src/main/res/layout/activity_sign_up.xml" value="0.4375" /> <entry key="app/src/main/res/layout/activity_sign_up.xml" value="0.4375" />
<entry key="app/src/main/res/layout/receive.xml" value="0.3098958333333333" />
<entry key="app/src/main/res/layout/received.xml" value="0.4375" />
<entry key="app/src/main/res/layout/sent.xml" value="0.43645833333333334" />
<entry key="app/src/main/res/layout/user_layout.xml" value="0.25" /> <entry key="app/src/main/res/layout/user_layout.xml" value="0.25" />
<entry key="app/src/main/res/menu/main_menu.xml" value="0.4375" /> <entry key="app/src/main/res/menu/main_menu.xml" value="0.4375" />
</map> </map>

View File

@ -48,4 +48,5 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation platform('com.google.firebase:firebase-bom:31.0.1') implementation platform('com.google.firebase:firebase-bom:31.0.1')
implementation 'com.google.firebase:firebase-analytics-ktx' implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.android.gms:play-services-ads:21.3.0'
} }

View File

@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.lsm.chatapplication"> package="com.lsm.chatapplication">
<uses-permission android:name="android.permission.INTERNET"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
@ -15,7 +15,8 @@
tools:targetApi="31"> tools:targetApi="31">
<activity <activity
android:name=".ChatActivity" android:name=".ChatActivity"
android:exported="false" /> android:exported="false"
android:parentActivityName=".MainActivity"/>
<activity <activity
android:name=".SignUp" android:name=".SignUp"
android:exported="false" android:exported="false"
@ -32,6 +33,12 @@
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="false" /> android:exported="false" />
<!-- Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713"/>
</application> </application>
</manifest> </manifest>

View File

@ -1,11 +1,81 @@
package com.lsm.chatapplication package com.lsm.chatapplication
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.widget.LinearLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.ValueEventListener
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
import com.lsm.chatapplication.databinding.ActivityChatBinding
class ChatActivity : AppCompatActivity() { class ChatActivity : AppCompatActivity() {
private lateinit var binding: ActivityChatBinding
private lateinit var messageAdapter: MessageAdapter
private lateinit var messageList: ArrayList<Message>
private lateinit var mDbRef: DatabaseReference
private var receiverRoom: String? = null
private var senderRoom: String? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat) binding = ActivityChatBinding.inflate(layoutInflater)
setContentView(binding.root)
val name = intent.getStringExtra("name")
val receiverUid = intent.getStringExtra("uid")
val senderUid = FirebaseAuth.getInstance().currentUser?.uid
mDbRef = Firebase.database("https://chatapplication-4eb49-default-rtdb.europe-west1.firebasedatabase.app/").reference
senderRoom = receiverUid + senderUid
receiverRoom = senderUid + receiverUid
supportActionBar?.title = name
messageList = ArrayList()
messageAdapter = MessageAdapter(messageList)
binding.messagesRecyclerView.layoutManager = LinearLayoutManager(this)
binding.messagesRecyclerView.adapter = messageAdapter
mDbRef.child("chats").child(senderRoom!!).child("messages").
addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
messageList.clear()
snapshot.children.forEach{
val message = it.getValue(Message::class.java)
messageList.add(message!!)
}
messageAdapter.notifyItemInserted(messageList.size-1)
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
binding.sendMessageButton.setOnClickListener{
val message = binding.messageBox.text.toString()
if (message != ""){
val messageObject = Message(message,senderUid)
mDbRef.child("chats").child(senderRoom!!).child("messages").push()
.setValue(messageObject).addOnSuccessListener {
mDbRef.child("chats").child(receiverRoom!!).child("messages").push()
.setValue(messageObject)
}
binding.messageBox.text.clear()
}
}
} }
} }

View File

@ -34,6 +34,10 @@ class LogIn : AppCompatActivity() {
} }
} }
private fun logIn(email: String, password: String){ private fun logIn(email: String, password: String){
if(email.isEmpty() or password.isEmpty()){
Toast.makeText(this@LogIn,"Field cannot be empty",Toast.LENGTH_SHORT).show()
return
}
mAuth.signInWithEmailAndPassword(email, password) mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task -> .addOnCompleteListener(this) { task ->
if (task.isSuccessful) { if (task.isSuccessful) {

View File

@ -6,6 +6,10 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener
import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.DataSnapshot import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError import com.google.firebase.database.DatabaseError
@ -35,6 +39,8 @@ class MainActivity : AppCompatActivity() {
binding.userRecyclerView.adapter = adapter binding.userRecyclerView.adapter = adapter
readUsersFromDatabase() readUsersFromDatabase()
val adRequest = AdRequest.Builder().build()
binding.adView.loadAd(adRequest)
} }
private fun readUsersFromDatabase(){ private fun readUsersFromDatabase(){

View File

@ -0,0 +1,5 @@
package com.lsm.chatapplication
class Message(val message: String?, val senderId: String?) {
constructor(): this(null, null)
}

View File

@ -0,0 +1,63 @@
package com.lsm.chatapplication
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.auth.FirebaseAuth
import com.lsm.chatapplication.databinding.ReceivedBinding
import com.lsm.chatapplication.databinding.SentBinding
import com.lsm.chatapplication.databinding.UserLayoutBinding
class MessageAdapter(val messageList: ArrayList<Message>): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val ITEM_RECEIVED = 0
private val ITEM_SENT = 1
class SentViewHolder(val binding: SentBinding): RecyclerView.ViewHolder(binding.root)
class ReceivedViewHolder(val binding: ReceivedBinding): RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if(viewType == ITEM_RECEIVED){
ReceivedViewHolder(
ReceivedBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}else{
SentViewHolder(
SentBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val currentMessage = messageList[position]
if(holder.javaClass == SentViewHolder::class.java){
val viewHolder = holder as SentViewHolder
holder.binding.txtSentMessage.text = currentMessage.message
}else{
val viewHolder = holder as ReceivedViewHolder
holder.binding.txtReceivedMessage.text = currentMessage.message
}
}
override fun getItemCount(): Int {
return messageList.size
}
override fun getItemViewType(position: Int): Int {
val currentMessage = messageList[position]
return if(FirebaseAuth.getInstance().currentUser?.uid.equals(currentMessage.senderId)){
ITEM_SENT
}else{
ITEM_RECEIVED
}
}
}

View File

@ -35,6 +35,10 @@ class SignUp : AppCompatActivity() {
} }
} }
private fun signUp(name:String, email: String, password: String){ private fun signUp(name:String, email: String, password: String){
if(email.isEmpty() or password.isEmpty() or name.isEmpty()){
Toast.makeText(this@SignUp,"Field cannot be empty",Toast.LENGTH_SHORT).show()
return
}
mAuth.createUserWithEmailAndPassword(email, password) mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task -> .addOnCompleteListener(this) { task ->
if (task.isSuccessful) { if (task.isSuccessful) {

View File

@ -1,11 +1,13 @@
package com.lsm.chatapplication package com.lsm.chatapplication
import android.content.Intent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.auth.FirebaseAuth
import com.lsm.chatapplication.databinding.UserLayoutBinding import com.lsm.chatapplication.databinding.UserLayoutBinding
//class UserAdapter(val userList: ArrayList<User>): //class UserAdapter(val userList: ArrayList<User>):
@ -20,6 +22,7 @@ import com.lsm.chatapplication.databinding.UserLayoutBinding
// override fun onBindViewHolder(holder: UserViewHolder, position: Int) { // override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
// val currentUser = userList[position] // val currentUser = userList[position]
// holder.binding.userName.text = currentUser.name // holder.binding.userName.text = currentUser.name
// holder.binding.itemView
// } // }
// //
// override fun getItemCount(): Int { // override fun getItemCount(): Int {
@ -47,7 +50,16 @@ class UserAdapter():
override fun onBindViewHolder(holder: UserViewHolder, position: Int) { override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
val currentUser = getItem(position) val currentUser = getItem(position)
//?
val context = holder.binding.root.context
holder.binding.userName.text = currentUser.name holder.binding.userName.text = currentUser.name
} holder.itemView.setOnClickListener{
val intent = Intent(context,ChatActivity::class.java)
intent.putExtra("name",currentUser.name)
intent.putExtra("uid", currentUser.uid)
context.startActivity(intent)
}
}
} }

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="48dp"
android:tint="#3700B3" android:viewportHeight="24"
android:viewportWidth="24" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="15dp"/>
<stroke android:color="@color/purple_700" android:width="3dp"/>
</shape>

View File

@ -6,4 +6,39 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ChatActivity"> tools:context=".ChatActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/messages_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toTopOf="@+id/send_message_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
<EditText
android:id="@+id/message_box"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:hint="@string/message_box_hint"
android:inputType="textPersonName"
app:layout_constraintBottom_toBottomOf="@+id/send_message_button"
app:layout_constraintEnd_toStartOf="@+id/send_message_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/send_message_button" />
<ImageView
android:id="@+id/send_message_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_send_blue" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -29,6 +29,7 @@
android:ems="10" android:ems="10"
android:hint="@string/email_hint" android:hint="@string/email_hint"
android:inputType="textEmailAddress" android:inputType="textEmailAddress"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_logo" /> app:layout_constraintTop_toBottomOf="@+id/app_logo" />
@ -41,6 +42,7 @@
android:ems="10" android:ems="10"
android:hint="@string/password_hint" android:hint="@string/password_hint"
android:inputType="textPassword" android:inputType="textPassword"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="@+id/edt_email" app:layout_constraintEnd_toEndOf="@+id/edt_email"
app:layout_constraintHorizontal_bias="1.0" app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/edt_email" app:layout_constraintStart_toStartOf="@+id/edt_email"

View File

@ -9,10 +9,23 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/user_recycler_view" android:id="@+id/user_recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
tools:listitem="@layout/user_layout" app:layout_constraintBottom_toTopOf="@+id/ad_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
tools:listitem="@layout/user_layout" />
<com.google.android.gms.ads.AdView
android:id="@+id/ad_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:adSize="BANNER"
app:adUnitId="ca-app-pub-3940256099942544/6300978111"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent" />
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
app:cardCornerRadius="15dp"
app:cardElevation="4dp"
app:contentPadding="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:strokeColor="@color/purple_700"
app:strokeWidth="3dp">
<TextView
android:id="@+id/txt_received_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is received message"
android:textSize="18sp" />
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
app:cardBackgroundColor="@color/purple_700"
app:cardCornerRadius="15dp"
app:cardElevation="4dp"
app:contentPadding="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/txt_sent_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is sent message"
android:textColor="@color/white"
android:textSize="18sp" />
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,5 @@
<resources> <resources>
<string name="app_name">ChatApplication</string> <string name="app_name">Chat Application</string>
<string name="email_hint">Email</string> <string name="email_hint">Email</string>
<string name="password_hint">Password</string> <string name="password_hint">Password</string>
<string name="log_in_btn_text">Log In</string> <string name="log_in_btn_text">Log In</string>
@ -7,4 +7,5 @@
<string name="sign_up_btn_text">Create new account</string> <string name="sign_up_btn_text">Create new account</string>
<string name="options_separator_text">Or</string> <string name="options_separator_text">Or</string>
<string name="logout_menu">Log Out</string> <string name="logout_menu">Log Out</string>
<string name="message_box_hint">Type a message</string>
</resources> </resources>