Commit 61f93aaf by Paktalin

Saves changes only to the local Vocabulary

parent 080d3fb8
package com.paktalin.vocabularynotebook
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.rule.ActivityTestRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.paktalin.vocabularynotebook.ui.activities.MainActivity
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class HelloWorldEspressoTest {
@get:Rule
val activityRule = ActivityTestRule(MainActivity::class.java)
@Test
fun listGoesOverTheFold() {
onView(withId(R.id.container_main)).perform(click())
}
}
\ No newline at end of file
package com.paktalin.vocabularynotebook.ui.activities
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.intent.rule.IntentsTestRule
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.ActivityTestRule
import com.paktalin.vocabularynotebook.R
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class LogInActivityTest {
@get:Rule
val activityRule = ActivityTestRule(LogInActivity::class.java)
@get:Rule
var mLoginActivityActivityTestRule: IntentsTestRule<LogInActivity> = IntentsTestRule(LogInActivity::class.java)
@Test
fun user_can_enter_username() {
onView(withId(R.id.etUsername)).perform(typeText("likorn"))
}
@Test
fun user_can_enter_password() {
onView(withId(R.id.etPassword)).perform(typeText("123456"))
}
@Test
fun user_can_login() {
onView(withId(R.id.btnLogIn)).perform(click())
}
@Test
fun user_can_sign_up() {
onView(withId(R.id.btnSignUp)).perform(click())
}
}
\ No newline at end of file
......@@ -4,25 +4,38 @@ import com.google.firebase.Timestamp
import com.google.firebase.firestore.DocumentSnapshot
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.utils.FirestoreManager.Companion.vocabularyId
import com.paktalin.vocabularynotebook.utils.Log
class Vocabulary() {
private var words: MutableList<WordItem> = mutableListOf()
private var allWords: MutableList<WordItem> = mutableListOf()
private var displayed: MutableList<WordItem> = mutableListOf()
constructor(vocabulary: Vocabulary) : this() {
copyWordsFrom(vocabulary)
}
companion object {
private val TAG = "VN/" + Vocabulary::class.java.simpleName
const val SORT_BY_TIME = 0
const val SORT_BY_WORD = 1
const val SORT_BY_TRANSLATION = 2
constructor(documents: MutableList<DocumentSnapshot>) : this() {
documents.forEach { ref ->
words.add(WordItem(
ref["word"].toString(),
ref["translation"].toString(),
(ref["time"] as Timestamp).toDate(),
ref.id, vocabularyId!!))
fun createFromDocs(documents: MutableList<DocumentSnapshot>): Vocabulary {
val wordsFromDocs = mutableListOf<WordItem>()
documents.forEach { ref ->
wordsFromDocs.add(WordItem(
ref["word"].toString(),
ref["translation"].toString(),
(ref["time"] as Timestamp).toDate(),
ref.id, vocabularyId!!))
}
return Vocabulary(wordsFromDocs)
}
}
// TODO make private
constructor(words: MutableList<WordItem>): this() {
this.allWords.addAll(words)
this.displayed.addAll(words)
}
fun sort(sortOrder:Int) {
when(sortOrder) {
SORT_BY_TIME -> sortByTime()
......@@ -31,56 +44,50 @@ class Vocabulary() {
}
}
fun deleteWord(position:Int) {
words[position].delete() // delete word from the database
words.removeAt(position) // delete word from the list
fun deleteWord(wordItem: WordItem) {
allWords.remove(wordItem)
displayed.remove(wordItem)
}
fun addWord(newWord: WordItem) {
words.add(0, newWord)
Log.d(TAG, "vocabulary addWord")
allWords.add(0, newWord)
displayed.add(0, newWord)
displayed.forEach { w -> Log.d(TAG, w.toString()) }
}
fun copyWordsFrom(vocabulary: Vocabulary) {
words.addAll(vocabulary.get())
fun displayAll() {
displayed.addAll(allWords)
}
fun addWordsFittingQuery(vocabulary: Vocabulary, query:String) {
vocabulary.get().filter { wordItem -> wordItem.contains(query) }.toCollection(words)
fun displayByQuery(query: String) {
allWords.filter { wordItem -> wordItem.contains(query) }.toCollection(displayed)
}
fun updateWord(updatedWord: WordItem) {
val updatedItemIndex = words.indexOf(updatedWord)
words[updatedItemIndex] = updatedWord
allWords[allWords.indexOf(updatedWord)] = updatedWord
displayed[displayed.indexOf(updatedWord)] = updatedWord
}
fun getAt(position: Int): WordItem {
return words[position]
fun displayedAt(position: Int): WordItem {
return displayed[position]
}
fun get():MutableList<WordItem> { return words }
fun displayedSize():Int { return displayed.size }
fun size():Int { return words.size }
fun clear() { words.clear() }
fun clearDisplayed() { displayed.clear() }
private fun sortByTime() {
words.sortWith(Comparator { item1, item2 ->
displayed.sortWith(Comparator { item1, item2 ->
-item1.pojo.time!!.compareTo(item2.pojo.time) })
}
private fun sortByWord() {
words.sortWith(Comparator { item1, item2 ->
displayed.sortWith(Comparator { item1, item2 ->
item1.pojo.word.toLowerCase().compareTo(item2.pojo.word.toLowerCase()) })
}
private fun sortByTranslation() {
words.sortWith(Comparator { item1, item2 ->
displayed.sortWith(Comparator { item1, item2 ->
item1.pojo.translation.toLowerCase().compareTo(item2.pojo.translation.toLowerCase()) })
}
companion object {
private val TAG = "VN/" + Vocabulary::class.java.simpleName
const val SORT_BY_TIME = 0
const val SORT_BY_WORD = 1
const val SORT_BY_TRANSLATION = 2
}
}
\ No newline at end of file
......@@ -9,11 +9,11 @@ import android.view.*
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.ui.fragments.EditWordFragment
import com.paktalin.vocabularynotebook.ui.activities.MainActivity
import com.paktalin.vocabularynotebook.utils.Log
import com.paktalin.vocabularynotebook.utils.addFragment
class VocabularyAdapter(private val fullVocabulary: Vocabulary, private val mainActivity: MainActivity) : RecyclerView.Adapter<ViewHolder>() {
class VocabularyAdapter(private val vocabulary: Vocabulary, private val mainActivity: MainActivity) : RecyclerView.Adapter<ViewHolder>() {
private var displayedVocabulary = Vocabulary(fullVocabulary)
private lateinit var recyclerView: RecyclerView
var sortOrder: Int = 0
......@@ -33,11 +33,11 @@ class VocabularyAdapter(private val fullVocabulary: Vocabulary, private val main
}
override fun getItemCount(): Int {
return displayedVocabulary.size()
return vocabulary.displayedSize()
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
val wordItem = displayedVocabulary.getAt(position)
val wordItem = vocabulary.displayedAt(position)
viewHolder.init(wordItem, position) { view, p -> showPopupMenu(view, p)}
//todo set click listener to menu
}
......@@ -46,8 +46,8 @@ class VocabularyAdapter(private val fullVocabulary: Vocabulary, private val main
val popup = PopupMenu(mainActivity, v)
popup.menuInflater.inflate(R.menu.word_item_menu, popup.menu)
popup.setOnMenuItemClickListener {
if (it.itemId == R.id.option_delete) { deleteWord(position) }
if (it.itemId == R.id.option_edit) { startEditFragment(v, displayedVocabulary.getAt(position)) }
if (it.itemId == R.id.option_delete) { deleteWord(vocabulary.displayedAt(position), position) }
if (it.itemId == R.id.option_edit) { startEditFragment(v, vocabulary.displayedAt(position)) }
true
}
// if not edit mode, then start EditFragment
......@@ -63,28 +63,26 @@ class VocabularyAdapter(private val fullVocabulary: Vocabulary, private val main
}*/
}
private fun deleteWord(position: Int) {
//TODO delete from fullVocabulary
displayedVocabulary.deleteWord(position)
private fun deleteWord(wordItem: WordItem, position: Int) {
vocabulary.deleteWord(wordItem)
recyclerView.removeViewAt(position)
this.notifyItemRemoved(position)
this.notifyItemRangeChanged(position, displayedVocabulary.size())
this.notifyItemRangeChanged(position, vocabulary.displayedSize())
}
fun addWord(newWord: WordItem) {
displayedVocabulary.addWord(newWord)
// TODO add word to fullVocabulary
Log.d(TAG, "vocabularyAdapter addWord")
vocabulary.addWord(newWord)
this.sort()
}
fun updateWord(updatedWord: WordItem) {
displayedVocabulary.updateWord(updatedWord)
// TODO update word in fullVocabulary
vocabulary.updateWord(updatedWord)
this.sort()
}
private fun sort() {
displayedVocabulary.sort(sortOrder)
vocabulary.sort(sortOrder)
this.notifyDataSetChanged()
}
......@@ -102,11 +100,11 @@ class VocabularyAdapter(private val fullVocabulary: Vocabulary, private val main
}
fun filter(query: String) {
displayedVocabulary.clear()
vocabulary.clearDisplayed()
if (query.isEmpty())
displayedVocabulary.copyWordsFrom(fullVocabulary)
vocabulary.displayAll()
else
displayedVocabulary.addWordsFittingQuery(fullVocabulary, query.toLowerCase())
vocabulary.displayByQuery(query.toLowerCase())
notifyDataSetChanged()
}
......
package com.paktalin.vocabularynotebook.firestoreitems
import com.paktalin.vocabularynotebook.utils.FirestoreManager
import java.io.Serializable
import java.util.Date
class WordItem(word: String, translation: String, time: Date?, var id: String?, private val vocabularyId: String?) : Serializable {
var pojo: Pojo = Pojo(word, translation, time)
class Pojo(var word: String, var translation: String, var time:Date?) : Serializable {
class Pojo(var word: String, var translation: String, var time:Date? = null) : Serializable {
init {
if (time == null) time = Date(System.currentTimeMillis())
}
......@@ -18,10 +17,6 @@ class WordItem(word: String, translation: String, time: Date?, var id: String?,
constructor(pojo: Pojo) : this(pojo, null, null)
fun delete() {
FirestoreManager().deleteWord(id!!)
}
fun contains(string:String):Boolean {
return pojo.word.toLowerCase().contains(string) ||
pojo.translation.toLowerCase().contains(string)
......
......@@ -89,7 +89,7 @@ class MainActivity : AppCompatActivity() {
FirestoreManager().extractVocabulary { documents ->
run {
if (documents.isNotEmpty()) {
vocabularyAdapter = VocabularyAdapter(Vocabulary(documents), this@MainActivity)
vocabularyAdapter = VocabularyAdapter(Vocabulary.createFromDocs(documents), this@MainActivity)
recyclerView.adapter = vocabularyAdapter
}
else showToastNoWords()
......
package com.paktalin.vocabularynotebook
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import org.junit.Assert.*
import org.junit.Test
class VocabularyTest {
@Test
fun constructorTest() {
val wordList = mutableListOf(
WordItem(WordItem.Pojo("ciao", "hi")),
WordItem(WordItem.Pojo("grazie", "thanks")),
WordItem(WordItem.Pojo("prego", "you're welcome")),
WordItem(WordItem.Pojo("per favore", "please")),
WordItem(WordItem.Pojo("bene", "good")))
val vocabulary = Vocabulary(wordList)
assertEquals(wordList[0], vocabulary.displayedAt(0))
}
}
\ No newline at end of file
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