Skip to content

Commit 8d91497

Browse files
Fix part of #116 (#149)
* Chat feature added * Change Send button color
1 parent b4d9a4a commit 8d91497

19 files changed

+643
-67
lines changed

app/build.gradle

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -27,74 +27,72 @@ android {
2727

2828
dependencies {
2929
implementation fileTree(dir: "libs", include: ["*.jar"])
30+
31+
// Language lib
32+
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.4.21'
33+
34+
// Support
3035
implementation 'androidx.appcompat:appcompat:1.2.0'
31-
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
32-
implementation 'com.google.android.material:material:1.3.0'
3336
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
34-
implementation 'com.google.firebase:firebase-storage:19.2.2'
35-
testImplementation 'junit:junit:4.13.1'
36-
implementation 'com.airbnb.android:lottie:3.6.1'
37-
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
38-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
39-
implementation 'com.firebaseui:firebase-ui-firestore:6.2.1'
40-
implementation 'com.google.firebase:firebase-database:19.7.0'
37+
implementation 'com.google.android.material:material:1.3.0'
38+
39+
//Android Jetpack Navigation
40+
implementation "androidx.navigation:navigation-fragment:2.3.4"
41+
implementation "androidx.navigation:navigation-ui:2.3.4"
42+
43+
// Custom View
44+
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
4145
implementation 'de.hdodenhof:circleimageview:3.1.0'
46+
implementation 'com.ismaeldivita.chipnavigation:chip-navigation-bar:1.3.4'
47+
implementation 'com.github.TalbotGooday:AvatarView:0.0.2'
4248
implementation 'com.github.cachapa:ExpandableLayout:2.9.2'
4349

50+
// Firebase core
4451
implementation platform('com.google.firebase:firebase-bom:26.1.0')
45-
implementation 'com.squareup.picasso:picasso:2.71828'
46-
androidTestImplementation 'androidx.test:runner:1.3.0'
47-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
48-
implementation 'com.google.android.gms:play-services-base:17.6.0'
49-
implementation 'com.google.android.libraries.places:places:2.4.0'
50-
implementation 'com.google.android.gms:play-services-maps:17.0.0'
51-
implementation 'com.squareup.picasso:picasso:2.71828'
52-
implementation 'com.google.android.gms:play-services-location:18.0.0'
53-
// FirebaseUI for Firebase Realtime Database
54-
implementation 'com.firebaseui:firebase-ui-database:6.3.0'
52+
implementation 'com.google.firebase:firebase-storage'
53+
implementation 'com.google.firebase:firebase-database'
54+
implementation 'com.google.firebase:firebase-core'
55+
implementation 'com.google.firebase:firebase-firestore'
56+
implementation 'com.google.firebase:firebase-analytics'
57+
implementation 'com.google.firebase:firebase-auth'
58+
implementation 'com.firebase:firebase-client-android:2.3.1'
5559

56-
// FirebaseUI for Cloud Firestore
60+
// Firebase UI
61+
implementation 'com.firebaseui:firebase-ui-firestore:6.2.1'
62+
implementation 'com.firebaseui:firebase-ui-database:6.3.0'
5763
implementation 'com.firebaseui:firebase-ui-firestore:6.2.1'
58-
59-
// FirebaseUI for Firebase Auth
6064
implementation 'com.firebaseui:firebase-ui-auth:6.2.1'
61-
62-
// FirebaseUI for Cloud Storage
6365
implementation 'com.firebaseui:firebase-ui-storage:6.2.1'
6466

65-
implementation 'com.google.firebase:firebase-core:18.0.2'
66-
implementation 'com.google.firebase:firebase-firestore:22.1.2'
67-
implementation 'com.google.firebase:firebase-analytics:18.0.2'
68-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
69-
implementation 'com.google.firebase:firebase-auth:20.0.3'
67+
// Play services
7068
implementation 'com.google.android.gms:play-services-auth:19.0.0'
71-
implementation 'com.google.firebase:firebase-database:19.7.0'
72-
73-
implementation 'com.firebase:firebase-client-android:2.3.1'
74-
75-
//Android Jetpack Navigation
76-
implementation "androidx.navigation:navigation-fragment:2.3.4"
77-
implementation "androidx.navigation:navigation-ui:2.3.4"
69+
implementation 'com.google.android.gms:play-services-base:17.6.0'
70+
implementation 'com.google.android.libraries.places:places:2.4.0'
71+
implementation 'com.google.android.gms:play-services-maps:17.0.0'
72+
implementation 'com.google.android.gms:play-services-location:18.0.0'
7873

79-
//Glide
74+
// Network loading
75+
implementation 'com.squareup.picasso:picasso:2.71828'
8076
implementation 'com.github.bumptech.glide:glide:4.11.0'
8177
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
82-
implementation 'com.google.android.gms:play-services-auth:19.0.0'
78+
implementation 'com.android.volley:volley:1.2.0'
79+
implementation 'io.github.ponnamkarthik:richlinkpreview:1.0.9'
80+
implementation 'org.jsoup:jsoup:1.10.2'
8381

84-
//custom Bottom nav bar
85-
implementation 'com.ismaeldivita.chipnavigation:chip-navigation-bar:1.3.4'
86-
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.4.21'
82+
implementation 'com.airbnb.android:lottie:3.6.1'
8783

8884
//App Intro
8985
implementation 'com.github.AppIntro:AppIntro:6.1.0'
86+
9087
//EasyPref
9188
implementation 'com.pixplicity.easyprefs:library:1.9.0'
89+
9290
//Animatoo Library
9391
implementation 'com.github.mohammadatif:Animatoo:master'
94-
//Volley
95-
implementation 'com.android.volley:volley:1.2.0'
96-
97-
implementation 'io.github.ponnamkarthik:richlinkpreview:1.0.9'
98-
implementation 'org.jsoup:jsoup:1.10.2'
9992

93+
// Testing
94+
testImplementation 'junit:junit:4.13.1'
95+
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
96+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
97+
androidTestImplementation 'androidx.test:runner:1.3.0'
10098
}

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="com.cswala.cswala">
44

5-
<uses-permission android:name="android.permission.INTERNET"/>
6-
5+
<uses-permission android:name="android.permission.INTERNET" />
76
<application
87
android:name=".utils.MyApplication"
98
android:allowBackup="true"
@@ -12,7 +11,6 @@
1211
android:roundIcon="@mipmap/ic_launcher_round"
1312
android:supportsRtl="true"
1413
android:theme="@style/AppTheme">
15-
1614
<activity android:name=".Activities.ResetPassword"></activity>
1715
<activity android:name=".Activities.Register" />
1816
<activity android:name=".Activities.LoginWithEmail" />
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.cswala.cswala.Adapters;
2+
3+
import android.content.Context;
4+
import android.view.LayoutInflater;
5+
import android.view.View;
6+
import android.view.ViewGroup;
7+
8+
import androidx.annotation.NonNull;
9+
10+
import com.cswala.cswala.R;
11+
import com.cswala.cswala.Models.Message;
12+
import com.cswala.cswala.utils.MessageListener;
13+
import com.cswala.cswala.viewholders.MessageHolder;
14+
import com.firebase.ui.database.FirebaseRecyclerAdapter;
15+
import com.firebase.ui.database.FirebaseRecyclerOptions;
16+
import com.google.firebase.database.DatabaseError;
17+
18+
public class MessageAdapter extends FirebaseRecyclerAdapter<Message, MessageHolder> {
19+
20+
private final MessageListener messageListener;
21+
private final String uId;
22+
private final Context context;
23+
24+
public MessageAdapter(@NonNull FirebaseRecyclerOptions<Message> options, MessageListener messageListener, String uId, Context context) {
25+
super(options);
26+
this.messageListener = messageListener;
27+
this.uId = uId;
28+
this.context = context;
29+
}
30+
31+
@Override
32+
protected void onBindViewHolder(@NonNull MessageHolder holder, int position, @NonNull Message model) {
33+
holder.bind(model, uId);
34+
}
35+
36+
@Override
37+
public void onError(@NonNull DatabaseError error) {
38+
super.onError(error);
39+
}
40+
41+
@Override
42+
public void onDataChanged() {
43+
super.onDataChanged();
44+
messageListener.onMessageReceived();
45+
}
46+
47+
48+
49+
@NonNull
50+
@Override
51+
public MessageHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
52+
View view = LayoutInflater.from(parent.getContext())
53+
.inflate(R.layout.message_item_view, parent, false);
54+
return new MessageHolder(view, context);
55+
}
56+
}
Lines changed: 158 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,177 @@
11
package com.cswala.cswala.Fragments;
22

3+
import android.content.Context;
34
import android.os.Bundle;
4-
5-
import androidx.fragment.app.Fragment;
6-
5+
import android.text.Editable;
6+
import android.text.TextWatcher;
77
import android.view.LayoutInflater;
88
import android.view.View;
99
import android.view.ViewGroup;
10+
import android.view.inputmethod.InputMethodManager;
11+
import android.widget.EditText;
12+
import android.widget.FrameLayout;
13+
import android.widget.LinearLayout;
14+
15+
import androidx.annotation.NonNull;
16+
import androidx.annotation.Nullable;
17+
import androidx.appcompat.widget.AppCompatImageButton;
18+
import androidx.fragment.app.Fragment;
19+
import androidx.recyclerview.widget.LinearLayoutManager;
20+
import androidx.recyclerview.widget.RecyclerView;
1021

1122
import com.cswala.cswala.R;
23+
import com.cswala.cswala.Adapters.MessageAdapter;
24+
import com.cswala.cswala.observer.ScrollToBottomObserver;
25+
import com.cswala.cswala.Models.Message;
26+
import com.cswala.cswala.utils.MessageListener;
27+
import com.firebase.ui.database.FirebaseRecyclerOptions;
28+
import com.google.android.material.snackbar.Snackbar;
29+
import com.google.firebase.auth.FirebaseAuth;
30+
import com.google.firebase.database.DatabaseError;
31+
import com.google.firebase.database.DatabaseReference;
32+
import com.google.firebase.database.FirebaseDatabase;
33+
import com.google.firebase.database.Query;
34+
35+
import java.util.Date;
1236

1337

1438
public class CommunityFragment extends Fragment {
1539

40+
private EditText msgInput;
41+
private AppCompatImageButton sendBtn;
42+
private MessageAdapter adapter;
43+
private FirebaseDatabase database;
44+
private FirebaseAuth auth;
45+
private RecyclerView chatRv;
46+
private LinearLayout sendMsgContainer;
47+
private FrameLayout progContainer;
1648

1749
@Override
1850
public View onCreateView(LayoutInflater inflater, ViewGroup container,
1951
Bundle savedInstanceState) {
20-
2152
return inflater.inflate(R.layout.fragment_community, container, false);
2253
}
54+
55+
@Override
56+
public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
57+
chatRv = view.findViewById(R.id.chat_rv);
58+
msgInput = view.findViewById(R.id.msg_input);
59+
sendBtn = view.findViewById(R.id.send_btn);
60+
sendMsgContainer = view.findViewById(R.id.send_msg_container);
61+
progContainer = view.findViewById(R.id.prog_container);
62+
63+
MessageListener messageListener = new MessageListener() {
64+
@Override
65+
public void onMessageReceived() {
66+
progContainer.setVisibility(View.GONE);
67+
}
68+
69+
@Override
70+
public void onError(DatabaseError error) {
71+
Snackbar.make(view, "Some error occurred", Snackbar.LENGTH_SHORT).show();
72+
}
73+
};
74+
75+
database = FirebaseDatabase.getInstance();
76+
auth = FirebaseAuth.getInstance();
77+
78+
// chatRv.setVisibility(View.GONE);
79+
// sendMsgContainer.setVisibility(View.GONE);
80+
progContainer.setVisibility(View.VISIBLE);
81+
82+
Query query = database
83+
.getReference()
84+
.child("chats")
85+
.limitToLast(50);
86+
87+
FirebaseRecyclerOptions<Message> options =
88+
new FirebaseRecyclerOptions.Builder<Message>()
89+
.setQuery(query, Message.class)
90+
.build();
91+
92+
LinearLayoutManager llm = new LinearLayoutManager(getContext());
93+
llm.setStackFromEnd(true);
94+
chatRv.setLayoutManager(llm);
95+
96+
adapter = new MessageAdapter(options, messageListener, auth.getCurrentUser().getUid(), getContext());
97+
chatRv.setAdapter(adapter);
98+
adapter.registerAdapterDataObserver(new ScrollToBottomObserver(chatRv, adapter, llm));
99+
100+
sendBtn.setOnClickListener(new View.OnClickListener() {
101+
@Override
102+
public void onClick(View v) {
103+
String content = msgInput.getText().toString().trim();
104+
if (content.equals("")) return;
105+
106+
closeKeyboard();
107+
DatabaseReference ref = database.getReference().child("chats").push();
108+
109+
String msgId = ref.getKey();
110+
String senderId = auth.getCurrentUser().getUid();
111+
String senderName = auth.getCurrentUser().getDisplayName();
112+
113+
if (senderName == null || senderName.trim().equals("")) {
114+
senderName = "Unknown";
115+
}
116+
117+
Message message = new Message(msgId, senderName, senderId, content, new Date().getTime());
118+
119+
ref.setValue(message);
120+
121+
122+
msgInput.setText("");
123+
124+
}
125+
});
126+
msgInput.addTextChangedListener(new TextWatcher() {
127+
boolean prevEmpty = true;
128+
129+
@Override
130+
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
131+
}
132+
133+
@Override
134+
public void onTextChanged(CharSequence s, int start, int before, int count) {
135+
}
136+
137+
@Override
138+
public void afterTextChanged(Editable s) {
139+
final boolean isEmpty = s.toString().trim().equals("");
140+
if (isEmpty == prevEmpty) return;
141+
prevEmpty = isEmpty;
142+
143+
if (isEmpty) {
144+
sendBtn.setVisibility(View.GONE);
145+
} else {
146+
sendBtn.setVisibility(View.VISIBLE);
147+
}
148+
}
149+
});
150+
}
151+
152+
@Override
153+
public void onStart() {
154+
super.onStart();
155+
if (adapter != null) {
156+
adapter.startListening();
157+
}
158+
}
159+
160+
@Override
161+
public void onStop() {
162+
super.onStop();
163+
if (adapter != null) {
164+
adapter.stopListening();
165+
}
166+
}
167+
168+
private void closeKeyboard() {
169+
try {
170+
View view = getActivity().getCurrentFocus();
171+
if (view != null) {
172+
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
173+
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
174+
}
175+
} catch(Exception ignored) {}
176+
}
23177
}

app/src/main/java/com/cswala/cswala/MainActivity.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import android.content.Intent;
44
import android.os.Bundle;
5-
import android.view.View;
6-
import android.widget.TextView;
75

86
import androidx.appcompat.app.AppCompatActivity;
97
import androidx.fragment.app.Fragment;

0 commit comments

Comments
 (0)