diff --git a/.gitignore b/.gitignore index 56cc642..db84e80 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,4 @@ lint/generated/ lint/outputs/ lint/tmp/ # lint/reports/ +/app/google-services.json diff --git a/.idea/misc.xml b/.idea/misc.xml index 3ff393f..bc48748 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,11 +3,25 @@ diff --git a/.idea/render.experimental.xml b/.idea/render.experimental.xml index 5cad4e0..cb2003e 100644 --- a/.idea/render.experimental.xml +++ b/.idea/render.experimental.xml @@ -2,5 +2,6 @@ \ No newline at end of file diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 7b25c8e..10ad9f3 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,5 +1,14 @@ ## 0.0.2 1. Login, Reset Password & Sign-in Activity +2. Added Firebase SDK for basic analytics. +3. Added Firebase SDK for Performance. +4. Added Firebase SDK for Crash Logs (If anytime the app crashes). +5. Added Google SafetyNet for extra security. +6. Project structure created. +7. Splash Screen Re-structured. +8. Dark/Light Mode added. +9. Added Profile check in settings. +10. Code cleanup. ## 0.0.1 1. Three Tabbed view diff --git a/LICENSE.MD b/LICENSE.MD new file mode 100644 index 0000000..98b40d9 --- /dev/null +++ b/LICENSE.MD @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2022 PSMForums + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 2c4a8b4..ba5fff2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,47 @@ # chatcom Chat with anyone you like through the power of chatcom. +This app provides End-To-End Encryption so that the word doesn't leak out. -By PSM & Masood +## Features: +1. Login, Reset Password & Sign-in Activity +2. Added Firebase SDK for basic analytics. +3. Added Firebase SDK for Performance. +4. Added Firebase SDK for Crash Logs (If anytime the app crashes). +5. Added Google SafetyNet for extra security. +6. Dark/Light Mode added. +7. Profile check in settings. +8. Three Tabbed view + +For More info view the [CHANGELOGS HERE](https://github.com/psavarmattas/chatcom/blob/main/CHANGELOG.MD) + +## ScreenShots: + +![Splash Screen](https://github.com/psavarmattas/chatcom/blob/main/screenshots/SplashScreenSS.png "Splash Screen") +![Chat Screen](https://github.com/psavarmattas/chatcom/blob/main/screenshots/ChatScreenSS.png "Chat Screen") +![Contacts Screen](https://github.com/psavarmattas/chatcom/blob/main/screenshots/ContactsScreenSS.png "Contacts Screen") +![Settings Screen](https://github.com/psavarmattas/chatcom/blob/main/screenshots/SettingsScreenSS.png "Settings Screen") +![Profile Screen](https://github.com/psavarmattas/chatcom/blob/main/screenshots/ProfileScreenSS.png "Profile Screen") +![Login Screen](https://github.com/psavarmattas/chatcom/blob/main/screenshots/LoginScreenSS.png "Login Screen") +![SignUp Screen](https://github.com/psavarmattas/chatcom/blob/main/screenshots/ContactsScreenSS.png "SignUp Screen") + +## Contributors: + + + + + +## [License](https://github.com/psavarmattas/chatcom/blob/main/LICENSE.MD) + +Copyright 2022 PSMForums + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/app/build.gradle b/app/build.gradle index 6626f3f..9c6c3d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,10 @@ plugins { id 'com.android.application' id 'kotlin-android' + id 'kotlin-android-extensions' + id 'com.google.gms.google-services' + id 'com.google.firebase.firebase-perf' + id 'com.google.firebase.crashlytics' } android { @@ -11,7 +15,7 @@ android { minSdk 21 targetSdk 32 versionCode 1 - versionName '0.0.1' + versionName '0.0.2' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" signingConfig signingConfigs.debug @@ -31,6 +35,10 @@ android { } buildToolsVersion '32.0.0' ndkVersion '23.1.7779620' + buildFeatures { + viewBinding true + dataBinding = true + } } dependencies { @@ -40,7 +48,31 @@ dependencies { implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' + implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + + //viewpager2 Dependency + implementation 'androidx.viewpager2:viewpager2:1.0.0' + + //Material Design + implementation 'com.google.android.material:material:1.5.0' + + //Firebase Dependencies + //The Firebase BoM + implementation platform('com.google.firebase:firebase-bom:29.0.4') + //Firebase SDK for Google Analytics + implementation 'com.google.firebase:firebase-analytics-ktx' + //Firebase SDK for SafetyNet + implementation 'com.google.firebase:firebase-appcheck-safetynet:16.0.0-beta04' + //Firebase SDK for Performance + implementation 'com.google.firebase:firebase-perf-ktx' + //Firebase SDk for Crashlytics + implementation 'com.google.firebase:firebase-crashlytics-ktx' + //Firebase SDK for User Authentication + implementation 'com.firebaseui:firebase-ui-auth:8.0.0' + implementation 'com.google.firebase:firebase-auth-ktx:21.0.1' + } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9810d2..84090c8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + @@ -18,10 +21,21 @@ + + + + - + android:exported="true" /> \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..95d10c6 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/example/chatcom/MainActivity.kt b/app/src/main/java/com/example/chatcom/MainActivity.kt index 414ac45..08c7319 100644 --- a/app/src/main/java/com/example/chatcom/MainActivity.kt +++ b/app/src/main/java/com/example/chatcom/MainActivity.kt @@ -2,60 +2,69 @@ package com.example.chatcom import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.view.ViewGroup +import android.widget.Button import android.widget.Toolbar import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.viewpager.widget.PagerAdapter import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.widget.ViewPager2 +import com.example.chatcom.adapters.ViewPagerAdapter import com.example.chatcom.mainScreens.Chats import com.example.chatcom.mainScreens.Contacts import com.example.chatcom.mainScreens.Settings import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator +import com.google.firebase.FirebaseApp +import com.google.firebase.analytics.FirebaseAnalytics +import com.google.firebase.analytics.ktx.analytics +import com.google.firebase.appcheck.FirebaseAppCheck +import com.google.firebase.appcheck.safetynet.SafetyNetAppCheckProviderFactory +import com.google.firebase.ktx.Firebase + + +private lateinit var firebaseAnalytics: FirebaseAnalytics + +val tabItemList = arrayOf( + "Chats", + "Contacts", + "Settings" +) class MainActivity : AppCompatActivity() { - private lateinit var viewPager2: ViewPager2 - private lateinit var tabLayout : TabLayout - private lateinit var toolbar: androidx.appcompat.widget.Toolbar - private lateinit var appPagerAdapter: AppPagerAdapter - private var titles = arrayListOf("Chats","Contacts","Settings") - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - toolbar = findViewById(R.id.toolbarMain) - tabLayout = findViewById(R.id.tabLayoutMain) - viewPager2 = findViewById(R.id.viewPager2Main) - toolbar.title = "ChatCom" + firebaseAnalytics = Firebase.analytics - setSupportActionBar(toolbar) + FirebaseApp.initializeApp(this) + val firebaseAppCheck = FirebaseAppCheck.getInstance() + firebaseAppCheck.installAppCheckProviderFactory( + SafetyNetAppCheckProviderFactory.getInstance() + ) - appPagerAdapter = AppPagerAdapter( this) - viewPager2.adapter = appPagerAdapter + val tabLayout = findViewById(R.id.tabBar) + val viewPager2 = findViewById(R.id.viewPager) - TabLayoutMediator(tabLayout,viewPager2){ - tab,position-> - tab.text = titles[position] + val adapter = ViewPagerAdapter(supportFragmentManager,lifecycle) + + viewPager2.adapter = adapter + + TabLayoutMediator(tabLayout,viewPager2){tab, position -> + when(position){ + 0 -> { + tab.text="Chats" + } + 1 -> { + tab.text="Contacts" + } + 2 -> { + tab.text="Settings" + } + } }.attach() } - - class AppPagerAdapter(fragmentActivity: FragmentActivity):FragmentStateAdapter(fragmentActivity) { - override fun getItemCount(): Int { - return 3 - } - - override fun createFragment(position: Int): Fragment { - return when(position) - { - 0-> Chats() - 2-> Contacts() - 3-> Settings() - else -> Chats() - } - } - } - } \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/accountScreens/LoginActivity.kt b/app/src/main/java/com/example/chatcom/accountScreens/LoginActivity.kt new file mode 100644 index 0000000..557e866 --- /dev/null +++ b/app/src/main/java/com/example/chatcom/accountScreens/LoginActivity.kt @@ -0,0 +1,149 @@ +package com.example.chatcom.accountScreens + +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.util.Patterns +import android.widget.Toast +import com.example.chatcom.R +import com.google.android.gms.auth.api.signin.GoogleSignIn +import com.google.android.gms.auth.api.signin.GoogleSignInAccount +import com.google.android.gms.auth.api.signin.GoogleSignInClient +import com.google.android.gms.auth.api.signin.GoogleSignInOptions +import com.google.android.gms.common.api.ApiException +import com.google.android.gms.tasks.Task +import com.google.firebase.auth.FirebaseAuth +import com.google.firebase.auth.FirebaseUser +import com.google.firebase.auth.GoogleAuthProvider +import kotlinx.android.synthetic.main.activity_login.* + +class LoginActivity : AppCompatActivity() { + + private lateinit var auth: FirebaseAuth + + //for google sign in/ + val RC_SIGN_IN: Int = 1 + lateinit var mGoogleSignInClient: GoogleSignInClient + lateinit var mGoogleSignInOptions: GoogleSignInOptions + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_login) + configureGoogleSignIn() + setupUI() + auth = FirebaseAuth.getInstance() + + + btnSign_up.setOnClickListener { + startActivity(Intent(this, SignupActivity::class.java)) + finish() + } + btnSign_in.setOnClickListener { + doLogin() + } + reset_pswd.setOnClickListener { + startActivity(Intent(this,ResetPasswordActivity::class.java)) + } + } + + private fun doLogin() { + if (username.text.toString().isEmpty()) { + username.error = "Please enter username" + username.requestFocus() + return + } + if (!Patterns.EMAIL_ADDRESS.matcher(username.text.toString()).matches()) { + username.error = "Please enter valid email" + username.requestFocus() + return + } + if (password.text.toString().isEmpty()) { + password.error = "Please enter Password" + password.requestFocus() + return + + } + auth.signInWithEmailAndPassword(username.text.toString(), password.text.toString()) + .addOnCompleteListener(this) { task -> + if (task.isSuccessful) { + val user = auth.currentUser + Toast.makeText(baseContext, "Sign In Successful!", Toast.LENGTH_SHORT).show() + updateUI(user) + } else { + Toast.makeText( + baseContext, "Sign in Failed!", + Toast.LENGTH_SHORT + ).show() + updateUI(null) + } + } + } + + public override fun onStart() { + super.onStart() + val currentUser = auth.currentUser + updateUI(currentUser) + } + + fun updateUI(currentUser: FirebaseUser?) { + if (currentUser !== null) { + startActivity(Intent(this, ProfileActivity::class.java)) + finish() + } +// else { +// Toast.makeText( +// baseContext, "Sign in Failed!", +// Toast.LENGTH_LONG +// ).show() +// } + } + + //google sign in starts here // + private fun configureGoogleSignIn() { + mGoogleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) + .requestIdToken(getString(R.string.default_web_client_id)) + .requestEmail() + .build() + mGoogleSignInClient = GoogleSignIn.getClient(this, mGoogleSignInOptions) + } + + private fun setupUI() { + GSignin.setOnClickListener { + signIn() + } + + } + + private fun signIn() { + val signInIntent: Intent = mGoogleSignInClient.signInIntent + startActivityForResult(signInIntent, RC_SIGN_IN) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == RC_SIGN_IN) { + val task: Task = GoogleSignIn.getSignedInAccountFromIntent(data) + try { + val account = task.getResult(ApiException::class.java) + if (account != null) { + firebaseAuthWithGoogle(account) + } + } catch (e: ApiException) { + Toast.makeText(this, "Google sign in failed:(", Toast.LENGTH_LONG).show() + } + } + } + + private fun firebaseAuthWithGoogle(acct: GoogleSignInAccount) { + val credential = GoogleAuthProvider.getCredential(acct.idToken, null) + auth.signInWithCredential(credential).addOnCompleteListener { + if (it.isSuccessful) { + startActivity(Intent(this, ProfileActivity::class.java)) + finish() + } else { + Toast.makeText(this, "Google sign in failed:(", Toast.LENGTH_LONG).show() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/accountScreens/ProfileActivity.kt b/app/src/main/java/com/example/chatcom/accountScreens/ProfileActivity.kt new file mode 100644 index 0000000..f3270bd --- /dev/null +++ b/app/src/main/java/com/example/chatcom/accountScreens/ProfileActivity.kt @@ -0,0 +1,38 @@ +package com.example.chatcom.accountScreens + +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.widget.Toast +import com.example.chatcom.MainActivity +import com.example.chatcom.R +import com.google.firebase.auth.FirebaseAuth +import kotlinx.android.synthetic.main.activity_profile.* + +class ProfileActivity : AppCompatActivity() { + private lateinit var auth: FirebaseAuth + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_profile) + auth = FirebaseAuth.getInstance() + + val user = FirebaseAuth.getInstance().currentUser + + user?.let { + val email = user.email + welcome.setText("Welcome "+email+"!") + } + + btnSign_out.setOnClickListener {view-> + Toast.makeText(baseContext,"Logging Out!", Toast.LENGTH_SHORT).show() + signOut() + } + } + + private fun signOut() { + FirebaseAuth.getInstance().signOut() + startActivity(Intent(this, MainActivity::class.java)) + finish() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/accountScreens/ResetPasswordActivity.kt b/app/src/main/java/com/example/chatcom/accountScreens/ResetPasswordActivity.kt new file mode 100644 index 0000000..6b64b2e --- /dev/null +++ b/app/src/main/java/com/example/chatcom/accountScreens/ResetPasswordActivity.kt @@ -0,0 +1,41 @@ +package com.example.chatcom.accountScreens + +import android.content.Intent +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.example.chatcom.MainActivity +import com.example.chatcom.R +import com.google.firebase.auth.FirebaseAuth +import kotlinx.android.synthetic.main.activity_reset_password.* + +class ResetPasswordActivity : AppCompatActivity() { + + private lateinit var auth: FirebaseAuth + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_reset_password) + auth = FirebaseAuth.getInstance() + + reset_pswd.setOnClickListener { + password_reset() + } + } + + + fun password_reset(){ + auth.sendPasswordResetEmail(username.text.toString()) + .addOnCompleteListener { task -> + if (task.isSuccessful) { + Toast.makeText(baseContext,"Reset link Sent!", Toast.LENGTH_SHORT).show() + startActivity(Intent(this, MainActivity::class.java)) + finish() + } + else { + Toast.makeText(baseContext, "User not found!", + Toast.LENGTH_SHORT).show() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/accountScreens/SignupActivity.kt b/app/src/main/java/com/example/chatcom/accountScreens/SignupActivity.kt new file mode 100644 index 0000000..0da1e4d --- /dev/null +++ b/app/src/main/java/com/example/chatcom/accountScreens/SignupActivity.kt @@ -0,0 +1,57 @@ +package com.example.chatcom.accountScreens + +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.util.Patterns +import android.widget.Toast +import com.example.chatcom.MainActivity +import com.example.chatcom.R +import com.google.firebase.auth.FirebaseAuth +import kotlinx.android.synthetic.main.activity_signup.* + +class SignupActivity : AppCompatActivity() { + + private lateinit var auth: FirebaseAuth + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_signup) + auth = FirebaseAuth.getInstance() + + btnSign_up.setOnClickListener { + signupUser() + } + + } + fun signupUser(){ + if (username.toString().isEmpty()){ + username.error = "Please enter email" + username.requestFocus() + return + } + if(!Patterns.EMAIL_ADDRESS.matcher(username.text.toString()).matches()){ + username.error = "Please enter valid Email" + username.requestFocus() + return + } + if (password.text.toString().isEmpty()){ + password.error = "Please enter Password" + password.requestFocus() + return + + } + auth.createUserWithEmailAndPassword(username.text.toString(), password.text.toString()) + .addOnCompleteListener(this) { task -> + if (task.isSuccessful) { + Toast.makeText(baseContext,"Yay! You are registered!", Toast.LENGTH_SHORT).show() + startActivity(Intent(this, MainActivity::class.java)) + finish() + } else { + Toast.makeText(baseContext, "Sign Up Failed", + Toast.LENGTH_SHORT).show() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/adapters/ViewPagerAdapter.kt b/app/src/main/java/com/example/chatcom/adapters/ViewPagerAdapter.kt new file mode 100644 index 0000000..2fe014c --- /dev/null +++ b/app/src/main/java/com/example/chatcom/adapters/ViewPagerAdapter.kt @@ -0,0 +1,32 @@ +package com.example.chatcom.adapters + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.Lifecycle +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.example.chatcom.mainScreens.Chats +import com.example.chatcom.mainScreens.Contacts +import com.example.chatcom.mainScreens.Settings + +class ViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle): FragmentStateAdapter(fragmentManager, lifecycle) { + override fun getItemCount(): Int { + return 3 + } + + override fun createFragment(position: Int): Fragment { + return when(position){ + 0 -> { + Chats() + } + 1 -> { + Contacts() + } + 2 -> { + Settings() + } + else -> { + Fragment() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/mainScreens/Chats.kt b/app/src/main/java/com/example/chatcom/mainScreens/Chats.kt index 193ae80..a883e45 100644 --- a/app/src/main/java/com/example/chatcom/mainScreens/Chats.kt +++ b/app/src/main/java/com/example/chatcom/mainScreens/Chats.kt @@ -7,27 +7,9 @@ import android.view.View import android.view.ViewGroup import com.example.chatcom.R -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" - -/** - * A simple [Fragment] subclass. - * Use the [Chats.newInstance] factory method to - * create an instance of this fragment. - */ class Chats : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - arguments?.let { - param1 = it.getString(ARG_PARAM1) - param2 = it.getString(ARG_PARAM2) - } } override fun onCreateView( @@ -37,24 +19,4 @@ class Chats : Fragment() { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_chats, container, false) } - - companion object { - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment Chats. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - Chats().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/mainScreens/Contacts.kt b/app/src/main/java/com/example/chatcom/mainScreens/Contacts.kt index b08afde..8da824f 100644 --- a/app/src/main/java/com/example/chatcom/mainScreens/Contacts.kt +++ b/app/src/main/java/com/example/chatcom/mainScreens/Contacts.kt @@ -7,27 +7,11 @@ import android.view.View import android.view.ViewGroup import com.example.chatcom.R -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" -/** - * A simple [Fragment] subclass. - * Use the [Contacts.newInstance] factory method to - * create an instance of this fragment. - */ class Contacts : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - arguments?.let { - param1 = it.getString(ARG_PARAM1) - param2 = it.getString(ARG_PARAM2) - } } override fun onCreateView( @@ -37,24 +21,4 @@ class Contacts : Fragment() { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_contacts, container, false) } - - companion object { - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment Contacts. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - Contacts().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/mainScreens/Settings.kt b/app/src/main/java/com/example/chatcom/mainScreens/Settings.kt index fc69c52..c0cfff1 100644 --- a/app/src/main/java/com/example/chatcom/mainScreens/Settings.kt +++ b/app/src/main/java/com/example/chatcom/mainScreens/Settings.kt @@ -1,60 +1,41 @@ package com.example.chatcom.mainScreens +import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import com.example.chatcom.R +import com.example.chatcom.accountScreens.LoginActivity +import com.google.firebase.auth.FirebaseAuth +import kotlinx.android.synthetic.main.fragment_settings.* -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" -/** - * A simple [Fragment] subclass. - * Use the [Settings.newInstance] factory method to - * create an instance of this fragment. - */ -class Settings : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - arguments?.let { - param1 = it.getString(ARG_PARAM1) - param2 = it.getString(ARG_PARAM2) +class Settings : Fragment(R.layout.fragment_settings) { + + private lateinit var auth: FirebaseAuth + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + auth = FirebaseAuth.getInstance() + + val user = FirebaseAuth.getInstance().currentUser + + user?.let { + val email = user.email +// FirebaseAuth.getInstance().currentUser?.displayName + profilePageText.setText("Id: " + email + "!") + } + + checkProfile.setOnClickListener { + //FirebaseAuth.getInstance().signOut() + Toast.makeText(activity, "Checking Profile Status", Toast.LENGTH_LONG).show() + val intent = Intent(activity, LoginActivity::class.java) + activity?.startActivity(intent) } } - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_settings, container, false) - } - - companion object { - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment Settings. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - Settings().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/example/chatcom/SplashActivity.kt b/app/src/main/java/com/example/chatcom/splashScreen/SplashScreen.kt similarity index 63% rename from app/src/main/java/com/example/chatcom/SplashActivity.kt rename to app/src/main/java/com/example/chatcom/splashScreen/SplashScreen.kt index ee7214b..0a7f47e 100644 --- a/app/src/main/java/com/example/chatcom/SplashActivity.kt +++ b/app/src/main/java/com/example/chatcom/splashScreen/SplashScreen.kt @@ -1,19 +1,21 @@ -package com.example.chatcom +package com.example.chatcom.splashScreen import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.os.Handler -import android.os.Looper +import android.view.WindowManager import android.widget.ImageView +import com.example.chatcom.MainActivity +import com.example.chatcom.R -class SplashActivity : AppCompatActivity() { +class SplashScreen : AppCompatActivity() { private lateinit var imageSplash: ImageView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_splash) + setContentView(R.layout.splash_screen) - imageSplash = findViewById(R.id.splashView) + imageSplash = findViewById(R.id.SplashScreenImage) Handler().postDelayed( { val intent = Intent(this, MainActivity::class.java) diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d1..0000000 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/splash.jpg b/app/src/main/res/drawable-v24/splash.jpg deleted file mode 100644 index d3ef9c2..0000000 Binary files a/app/src/main/res/drawable-v24/splash.jpg and /dev/null differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9..0000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_login_email_icon.xml b/app/src/main/res/drawable/ic_login_email_icon.xml new file mode 100644 index 0000000..6943b4c --- /dev/null +++ b/app/src/main/res/drawable/ic_login_email_icon.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..1a7cdfd --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + +