Commit e0b964a6 by Paktalin

Refactoring

parent 98806c93
......@@ -16,7 +16,7 @@
android:theme="@style/AppTheme">
<activity
android:label="@string/app_name"
android:name=".ui.MainActivity"
android:name=".ui.activities.MainActivity"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
......@@ -26,7 +26,7 @@
android:resource="@xml/searchable" />
</activity>
<activity
android:name=".ui.LogInActivity"
android:name=".ui.activities.LogInActivity"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......
......@@ -6,7 +6,7 @@ import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.text.TextUtils
import android.widget.Toast
import com.paktalin.vocabularynotebook.ui.ProgressFragment
import com.paktalin.vocabularynotebook.ui.fragments.ProgressFragment
val progressFragment: Fragment = ProgressFragment()
......
......@@ -3,7 +3,7 @@ package com.paktalin.vocabularynotebook
import android.util.Log
import com.google.firebase.auth.FirebaseUser
import com.paktalin.vocabularynotebook.appsetup.ConfiguredFirestore
import com.paktalin.vocabularynotebook.ui.LogInActivity
import com.paktalin.vocabularynotebook.ui.activities.LogInActivity
import com.paktalin.vocabularynotebook.firestoreitems.UserPojo
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary.Companion.VOCABULARIES
......
......@@ -10,8 +10,8 @@ import android.widget.LinearLayout
import android.widget.TextView
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.ui.EditWordFragment
import com.paktalin.vocabularynotebook.ui.MainActivity
import com.paktalin.vocabularynotebook.ui.fragments.EditWordFragment
import com.paktalin.vocabularynotebook.ui.activities.MainActivity
import kotlinx.android.synthetic.main.word_item.view.*
class VocabularyAdapter(private val displayedVocabulary: Vocabulary, private val mainActivity: MainActivity) : RecyclerView.Adapter<VocabularyAdapter.ViewHolder>() {
......
package com.paktalin.vocabularynotebook.ui
import android.util.Log
import android.view.View
import com.paktalin.vocabularynotebook.R
import com.paktalin.vocabularynotebook.appsetup.ConfiguredFirestore
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary.Companion.VOCABULARIES
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary.Companion.WORDS
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.shortToast
import kotlinx.android.synthetic.main.fragment_new_word.*
class AddWordFragment : WordFragment() {
override fun saveToFirestore(word:String, translation:String, vocabularyId: String) {
val wordPojo = WordItem.Pojo(word, translation, null)
ConfiguredFirestore.instance
.collection(VOCABULARIES).document(vocabularyId)
.collection(WORDS).add(wordPojo)
.addOnSuccessListener {
Log.i(TAG, "Successfully added a new word")
clearFields()
mainActivity.removeProgressBar()
val wordItem = WordItem(wordPojo, it.id, vocabularyId)
updateRecycleView(wordItem) }
.addOnFailureListener {
Log.w(TAG, "addNewWordToDb:failure", it.fillInStackTrace())
shortToast(mainActivity, getString(R.string.toast_new_word_fail))
}
}
override fun updateRecycleView(wordItem: WordItem) {
mainActivity.vocabularyFragment.addWord(wordItem)
}
override fun updateButtons() {
super.updateButtons()
if (!wordEmpty || !translationEmpty) showClearButton()
if (wordEmpty && translationEmpty) hideClearButton()
}
private fun hideClearButton() { btnClear.visibility = View.INVISIBLE }
private fun showClearButton() { btnClear.visibility = View.VISIBLE }
companion object { private val TAG = "VN/" + AddWordFragment::class.java.simpleName }
}
\ No newline at end of file
package com.paktalin.vocabularynotebook.ui
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import com.paktalin.vocabularynotebook.R
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.appsetup.ConfiguredFirestore
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary.Companion.VOCABULARIES
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary.Companion.WORDS
import com.paktalin.vocabularynotebook.removeFragment
import com.paktalin.vocabularynotebook.shortToast
import kotlinx.android.synthetic.main.fragment_new_word.*
import kotlinx.android.synthetic.main.notebook_sheet.*
import kotlinx.android.synthetic.main.word_item.view.*
class EditWordFragment : WordFragment() {
private lateinit var wordItem: WordItem
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mainActivity = activity as MainActivity
hidePreviousViews(container)
wordItem = arguments!!["wordItem"] as WordItem
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setWordItemData()
setFocusOnWord()
}
private fun setWordItemData() {
word.setText(wordItem.pojo.word)
translation.setText(wordItem.pojo.translation)
}
private fun setFocusOnWord() {
word.requestFocus()
val imm = mainActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
imm!!.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
}
private fun hidePreviousViews(container: ViewGroup?) {
if (container != null) {
container.line.visibility = View.GONE
container.word.visibility = View.GONE
container.translation.visibility = View.GONE
}
}
override fun saveToFirestore(word:String, translation:String, vocabularyId: String) {
val wordPojo = WordItem.Pojo(word, translation, wordItem.pojo.time)
ConfiguredFirestore.instance
.collection(VOCABULARIES).document(vocabularyId)
.collection(WORDS).document(wordItem.id).set(wordPojo)
.addOnSuccessListener {
Log.i(TAG, "Successfully updated the word")
hideSubmitButton()
mainActivity.removeProgressBar()
wordItem.pojo = wordPojo
updateRecycleView(wordItem)
stop()
}
.addOnFailureListener {
Log.w(TAG, "updateExistingWord:failure", it.fillInStackTrace())
shortToast(mainActivity, getString(R.string.toast_update_word_failed))
stop()
}
}
private fun stop() {
// set onClickListener from AddWordFragment
mainActivity.btnSubmit.setOnClickListener { (mainActivity.fragmentAddWord as AddWordFragment).submitWord() }
removeFragment(mainActivity.supportFragmentManager, this)
}
override fun updateRecycleView(wordItem: WordItem) {
mainActivity.vocabularyFragment.updateWord(wordItem)
}
companion object {
private val TAG = "VN/" + EditWordFragment::class.java.simpleName
}
}
\ No newline at end of file
package com.paktalin.vocabularynotebook.ui
import android.annotation.SuppressLint
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.google.firebase.auth.FirebaseAuth
import com.paktalin.vocabularynotebook.*
import kotlinx.android.synthetic.main.activity_log_in.*
class LogInActivity : AppCompatActivity() {
private var mAuth: FirebaseAuth? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_log_in)
mAuth = FirebaseAuth.getInstance()
btnLogIn!!.setOnClickListener({ logIn() })
btnSignUp!!.setOnClickListener({ signUp() })
btnRandomUser!!.setOnClickListener({ createRandomUser() })
}
override fun onStart() {
super.onStart()
if (mAuth!!.currentUser != null) { startUserActivity() }
}
private fun logIn() {
val email = etEmail!!.text.toString()
val password = etPassword!!.text.toString()
if (fieldsNotEmpty(email, password, "Please, enter email and password", this)) {
showProgressBar()
mAuth!!.signInWithEmailAndPassword(email, password)
.addOnCompleteListener { hideProgressBar() }
.addOnSuccessListener {
Log.d(TAG, "Successfully signed in")
startUserActivity()
}
.addOnFailureListener {
Log.w(TAG, "signInWithEmail:failure", it)
shortToast(this@LogInActivity, getString(R.string.toast_auth_failed))
}
}
}
private fun signUp() {
val email = etEmail!!.text.toString()
val password = etPassword!!.text.toString()
if (fieldsNotEmpty(email, password, "Please, enter email and password", this)) {
//todo check if the password is good
// todo verify email
showProgressBar()
mAuth!!.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener { hideProgressBar() }
.addOnSuccessListener { _ ->
Log.d(TAG, "Successfully signed up a new user")
UserManager.addNewUserToDb(mAuth!!.currentUser!!, this)
}
.addOnFailureListener {
Log.d(TAG, "createUserWithEmail:failure", it.fillInStackTrace())
shortToast(this@LogInActivity, it.message!!)
}
}
}
fun startUserActivity() {
Log.d(TAG, "Logged in successfully")
val userActivityIntent = Intent(this@LogInActivity, MainActivity::class.java)
startActivity(userActivityIntent)
}
private fun showProgressBar() { addProgressBar(supportFragmentManager, R.id.container_login) }
private fun hideProgressBar() { removeProgressBar(supportFragmentManager) }
@SuppressLint("SetTextI18n")
private fun createRandomUser() {
etEmail.setText("random@gmail.com")
etPassword.setText("123456")
signUp()
}
companion object { private val TAG = "VN/" + LogInActivity::class.simpleName }
}
\ No newline at end of file
package com.paktalin.vocabularynotebook.ui
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentReference
import kotlinx.android.synthetic.main.activity_main.*
import android.view.WindowManager
import android.app.Activity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.InputMethodManager
import com.paktalin.vocabularynotebook.appsetup.ConfiguredFirestore
import kotlinx.android.synthetic.main.fragment_vocabulary.*
import android.support.v7.widget.SearchView
import com.paktalin.vocabularynotebook.*
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary.Companion.VOCABULARIES
class MainActivity : AppCompatActivity() {
lateinit var vocabularyId: String
lateinit var vocabularyFragment: VocabularyFragment
lateinit var searchView: SearchView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
hideKeyboard()
setUpNavigationView()
extractVocabularyData()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.options_menu, menu)
searchView = menu!!.findItem(R.id.search).actionView as SearchView
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if (item!!.itemId == R.id.sort)
(recyclerView.adapter as VocabularyAdapter).updateSortOrder()
return super.onOptionsItemSelected(item)
}
private fun logOut() {
Log.i(TAG, "User logged out")
FirebaseAuth.getInstance()!!.signOut()
val intentLogInActivity = Intent(this@MainActivity, LogInActivity::class.java)
startActivity(intentLogInActivity)
}
private fun setUpNavigationView() {
navigationView.setNavigationItemSelectedListener { menuItem ->
menuItem.isChecked = true
if(menuItem.itemId == R.id.logOut) { logOut() }
drawerLayout!!.closeDrawers()
true
}
}
private fun extractVocabularyData() {
val userId = FirebaseAuth.getInstance()!!.currentUser!!.uid
val db = ConfiguredFirestore.instance
val userDocument = db.collection("users").document(userId)
addProgressBar()
userDocument.get()
.addOnSuccessListener { task ->
removeProgressBar()
//todo move Firestore logic and collections names to a separate class
if (task.get(VOCABULARIES) != null) {
val vocabularies: List<DocumentReference> = task.get(VOCABULARIES) as List<DocumentReference>
val vocabulary = db.collection(VOCABULARIES).document(vocabularies[0].id)
vocabularyId = vocabulary.id
// start VocabularyFragment
vocabularyFragment = VocabularyFragment()
val arguments = Bundle()
arguments.putString("vocabularyId", vocabularyId)
addFragment(supportFragmentManager, vocabularyFragment, R.id.container_vocabulary, arguments)
} else {
Log.w(TAG, "There's no collection \"vocabularies\"")
showToastNoWords() }
}
}
private fun hideKeyboard() {
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
}
fun hideKeyboardNotFromActivity(activity: Activity) {
val imm = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
var view = activity.currentFocus
if (view == null) { view = View(activity) }
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
fun addProgressBar() {
addProgressBar(supportFragmentManager, R.id.container_main)
}
fun removeProgressBar() {
removeProgressBar(supportFragmentManager)
}
fun showToastNoWords() {
shortToast(this, getString(R.string.toast_no_words))
}
override fun onPause() {
super.onPause()
hideKeyboard()
}
companion object { private val TAG = "VN/" + MainActivity::class.simpleName }
}
\ No newline at end of file
package com.paktalin.vocabularynotebook.ui
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.paktalin.vocabularynotebook.R
class ProgressFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_progress, container, false)
}
}
package com.paktalin.vocabularynotebook.ui
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.firebase.Timestamp
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.Query
import com.paktalin.vocabularynotebook.*
import com.paktalin.vocabularynotebook.appsetup.ConfiguredFirestore
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary.Companion.VOCABULARIES
import com.paktalin.vocabularynotebook.firestoreitems.Vocabulary.Companion.WORDS
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import kotlinx.android.synthetic.main.fragment_vocabulary.*
class VocabularyFragment : Fragment() {
companion object {
private val TAG = "VN/" + VocabularyFragment::class.simpleName
}
private val db = ConfiguredFirestore.instance
private lateinit var mainActivity: MainActivity
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_vocabulary, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mainActivity = activity as MainActivity
setEmptyAdapter()
retrieveWordsData(arguments!!["vocabularyId"] as String)
}
private fun setEmptyAdapter() {
val emptyList: MutableList<WordItem> = mutableListOf()
recyclerView.adapter = VocabularyAdapter(Vocabulary(emptyList), mainActivity)
val mLayoutManager = LinearLayoutManager(mainActivity)
recyclerView.layoutManager = mLayoutManager
}
private fun retrieveWordsData(vocabularyId: String) {
db.collection(VOCABULARIES).document(vocabularyId).collection(WORDS)
.orderBy("time", Query.Direction.DESCENDING)
.get()
.addOnSuccessListener {
if (it.documents.size != 0)
setVocabularyAdapter(it.documents, vocabularyId)
else {
Log.i(TAG, "There are no documents in collection \"words\"")
mainActivity.showToastNoWords()
}}
}
private fun setVocabularyAdapter(documents: MutableList<DocumentSnapshot>, vocabularyId: String) {
val wordItems: MutableList<WordItem> = mutableListOf()
for (ref in documents) {
val word = ref["word"].toString()
val translation = ref["translation"].toString()
val time = ref["time"] as Timestamp
wordItems.add(WordItem(word, translation, time.toDate(), ref.id, vocabularyId))
}
val vocabulary = Vocabulary(wordItems)
val adapter = VocabularyAdapter(vocabulary, mainActivity)
recyclerView.adapter = adapter
}
fun addWord(newWord: WordItem) { (recyclerView.adapter as VocabularyAdapter).addWord(newWord) }
fun updateWord(updatedWord: WordItem) {
(recyclerView.adapter as VocabularyAdapter).updateWord(updatedWord) }
}
\ No newline at end of file
package com.paktalin.vocabularynotebook.ui
import android.os.Bundle
import android.support.v4.app.Fragment
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.paktalin.vocabularynotebook.R
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import kotlinx.android.synthetic.main.fragment_new_word.*
import kotlinx.android.synthetic.main.notebook_sheet.*
abstract class WordFragment : Fragment() {
protected lateinit var mainActivity: MainActivity
internal var wordEmpty: Boolean = true
set(value) { field = value; updateButtons() }
internal var translationEmpty: Boolean = true
set(value) { field = value; updateButtons() }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_new_word, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mainActivity = activity as MainActivity
mainActivity.btnSubmit.setOnClickListener { submitWord() }
word.addTextChangedListener(textWatcher {
wordEmpty = word.text.isEmpty() })
translation.addTextChangedListener(textWatcher {
translationEmpty = translation.text.isEmpty() })
btnClear.setOnClickListener { clearFields() }
}
open fun updateButtons() {
if (!wordEmpty && !translationEmpty) showSubmitButton()
if (wordEmpty || translationEmpty) hideSubmitButton()
}
private fun textWatcher(setEmpty: () -> Unit): TextWatcher {
return object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { }
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { }
override fun afterTextChanged(editable: Editable) { setEmpty() }
}
}
private fun showSubmitButton() {
mainActivity.btnSubmitLayout.visibility = View.VISIBLE }
protected fun hideSubmitButton() {
mainActivity.btnSubmitLayout.visibility = View.GONE }
fun submitWord() {
mainActivity.hideKeyboardNotFromActivity(mainActivity)
val word = word.text.toString()
val translation = translation.text.toString()
val vocabularyId = mainActivity.vocabularyId
mainActivity.addProgressBar()
saveToFirestore(word, translation, vocabularyId)
return
}
protected fun clearFields() {
word.text.clear()
translation.text.clear()
}
protected abstract fun saveToFirestore(word:String, translation:String, vocabularyId:String)
protected abstract fun updateRecycleView(wordItem: WordItem)
}
\ No newline at end of file
......@@ -6,7 +6,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.LogInActivity">
tools:context=".ui.activities.LogInActivity">
<EditText
android:id="@+id/etEmail"
......
......@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.paktalin.vocabularynotebook.ui.VocabularyFragment">
tools:context="com.paktalin.vocabularynotebook.ui.fragments.VocabularyFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
......
......@@ -26,7 +26,7 @@
<fragment
android:id="@+id/fragmentAddWord"
android:name="com.paktalin.vocabularynotebook.ui.AddWordFragment"
android:name="com.paktalin.vocabularynotebook.ui.fragments.AddWordFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment