Commit 977460e3 by Paktalin

Split vocabulary into several classes

parent f1da1510
package com.paktalin.vocabularynotebook.vocabulary package com.paktalin.vocabularynotebook
import android.support.v7.widget.SearchView import android.support.v7.widget.SearchView
import com.paktalin.vocabularynotebook.ui.VocabularyAdapter
class OnQueryTextListener(var adapter: VocabularyAdapter) : SearchView.OnQueryTextListener { class OnQueryTextListener(var adapter: VocabularyAdapter) : SearchView.OnQueryTextListener {
......
...@@ -3,7 +3,7 @@ package com.paktalin.vocabularynotebook.firestoreitems ...@@ -3,7 +3,7 @@ package com.paktalin.vocabularynotebook.firestoreitems
import java.io.Serializable import java.io.Serializable
import java.util.Date import java.util.Date
class WordItem(word: String, translation: String, time: Date?, var id: String?, private val vocabularyId: String?) : Serializable { class WordItem(word: String, translation: String, time: Date?, var id: String?) : Serializable {
var pojo: Pojo = Pojo(word, translation, time) var pojo: Pojo = Pojo(word, translation, time)
var modifiedLabel: ModifiedLabel? = null var modifiedLabel: ModifiedLabel? = null
...@@ -13,10 +13,10 @@ class WordItem(word: String, translation: String, time: Date?, var id: String?, ...@@ -13,10 +13,10 @@ class WordItem(word: String, translation: String, time: Date?, var id: String?,
} }
} }
constructor(pojo: Pojo, id: String?, vocabularyId: String?) constructor(pojo: Pojo, id: String?)
: this(pojo.word, pojo.translation, pojo.time, id, vocabularyId) : this(pojo.word, pojo.translation, pojo.time, id)
constructor(pojo: Pojo) : this(pojo, null, null) constructor(pojo: Pojo) : this(pojo, null)
fun contains(string:String):Boolean { fun contains(string:String):Boolean {
return pojo.word.toLowerCase().contains(string) || return pojo.word.toLowerCase().contains(string) ||
......
package com.paktalin.vocabularynotebook.vocabulary package com.paktalin.vocabularynotebook.ui
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.View import android.view.View
......
package com.paktalin.vocabularynotebook.vocabulary package com.paktalin.vocabularynotebook.ui
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Build import android.os.Build
...@@ -6,20 +6,24 @@ import android.os.Bundle ...@@ -6,20 +6,24 @@ import android.os.Bundle
import android.support.v7.widget.PopupMenu import android.support.v7.widget.PopupMenu
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.* import android.view.*
import com.paktalin.vocabularynotebook.OnQueryTextListener
import com.paktalin.vocabularynotebook.R import com.paktalin.vocabularynotebook.R
import com.paktalin.vocabularynotebook.firestoreitems.WordItem import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.ui.fragments.EditWordFragment import com.paktalin.vocabularynotebook.ui.fragments.EditWordFragment
import com.paktalin.vocabularynotebook.ui.activities.MainActivity import com.paktalin.vocabularynotebook.ui.activities.MainActivity
import com.paktalin.vocabularynotebook.utils.Log import com.paktalin.vocabularynotebook.utils.Log
import com.paktalin.vocabularynotebook.utils.addFragment import com.paktalin.vocabularynotebook.utils.addFragment
import com.paktalin.vocabularynotebook.vocabulary.Sort
import com.paktalin.vocabularynotebook.vocabulary.VocabSet
class VocabularyAdapter(private val vocabulary: Vocabulary, private val mainActivity: MainActivity) : RecyclerView.Adapter<ViewHolder>() { class VocabularyAdapter(private val vocabulary: VocabSet, private val mainActivity: MainActivity) : RecyclerView.Adapter<ViewHolder>() {
private lateinit var recyclerView: RecyclerView private lateinit var recyclerView: RecyclerView
var sortOrder: Int = 0 var sort: Sort = Sort.BY_TIME
set(value) { set(value) {
field = value; sort() field = value
sort()
} }
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
...@@ -83,7 +87,7 @@ class VocabularyAdapter(private val vocabulary: Vocabulary, private val mainActi ...@@ -83,7 +87,7 @@ class VocabularyAdapter(private val vocabulary: Vocabulary, private val mainActi
} }
private fun sort() { private fun sort() {
vocabulary.sort(sortOrder) vocabulary.sort(sort)
this.notifyDataSetChanged() this.notifyDataSetChanged()
} }
...@@ -110,7 +114,7 @@ class VocabularyAdapter(private val vocabulary: Vocabulary, private val mainActi ...@@ -110,7 +114,7 @@ class VocabularyAdapter(private val vocabulary: Vocabulary, private val mainActi
} }
fun getModifiedWords(): MutableSet<WordItem> { fun getModifiedWords(): MutableSet<WordItem> {
return vocabulary.modified.get() return vocabulary.getModified()
} }
companion object { companion object {
......
...@@ -10,13 +10,11 @@ import android.view.View ...@@ -10,13 +10,11 @@ import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import com.paktalin.vocabularynotebook.R import com.paktalin.vocabularynotebook.R
import com.paktalin.vocabularynotebook.vocabulary.Vocabulary import com.paktalin.vocabularynotebook.ui.VocabularyAdapter
import com.paktalin.vocabularynotebook.vocabulary.Vocabulary.Companion.SORT_BY_TIME
import com.paktalin.vocabularynotebook.vocabulary.Vocabulary.Companion.SORT_BY_TRANSLATION
import com.paktalin.vocabularynotebook.vocabulary.Vocabulary.Companion.SORT_BY_WORD
import com.paktalin.vocabularynotebook.vocabulary.VocabularyAdapter
import com.paktalin.vocabularynotebook.ui.views.LockableLayoutManager import com.paktalin.vocabularynotebook.ui.views.LockableLayoutManager
import com.paktalin.vocabularynotebook.utils.* import com.paktalin.vocabularynotebook.utils.*
import com.paktalin.vocabularynotebook.vocabulary.Sort
import com.paktalin.vocabularynotebook.vocabulary.VocabSet
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.* import kotlinx.android.synthetic.main.content_main.*
import java.lang.Exception import java.lang.Exception
...@@ -46,11 +44,11 @@ class MainActivity : AppCompatActivity() { ...@@ -46,11 +44,11 @@ class MainActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem?): Boolean { override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if (item!!.itemId == R.id.sortByTime) if (item!!.itemId == R.id.sortByTime)
vocabularyAdapter.sortOrder = SORT_BY_TIME vocabularyAdapter.sort = Sort.BY_TIME
if (item.itemId == R.id.sortByWord) if (item.itemId == R.id.sortByWord)
vocabularyAdapter.sortOrder = SORT_BY_WORD vocabularyAdapter.sort = Sort.BY_WORD
if (item.itemId == R.id.sortByTranslation) if (item.itemId == R.id.sortByTranslation)
vocabularyAdapter.sortOrder = SORT_BY_TRANSLATION vocabularyAdapter.sort = Sort.BY_TRANSLATION
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
...@@ -89,7 +87,7 @@ class MainActivity : AppCompatActivity() { ...@@ -89,7 +87,7 @@ class MainActivity : AppCompatActivity() {
FirestoreManager().extractVocabulary { querySnapshot -> FirestoreManager().extractVocabulary { querySnapshot ->
run { run {
if (querySnapshot != null && !querySnapshot.isEmpty) { if (querySnapshot != null && !querySnapshot.isEmpty) {
vocabularyAdapter = VocabularyAdapter(Vocabulary.createFromSnapshot(querySnapshot), this@MainActivity) vocabularyAdapter = VocabularyAdapter(VocabSet.createFromSnapshot(querySnapshot), this@MainActivity)
recyclerView.adapter = vocabularyAdapter recyclerView.adapter = vocabularyAdapter
} }
else showToastNoWords() else showToastNoWords()
......
...@@ -37,7 +37,7 @@ class AddWordFragment : WordFragment() { ...@@ -37,7 +37,7 @@ class AddWordFragment : WordFragment() {
} }
override fun save(word:String, translation:String) { override fun save(word:String, translation:String) {
// TODO add entry point // TODO addAll entry point
clearFields() clearFields()
mainActivity.vocabularyAdapter.addWord(WordItem(WordItem.Pojo(word, translation, null))) mainActivity.vocabularyAdapter.addWord(WordItem(WordItem.Pojo(word, translation, null)))
this.word.requestFocus() this.word.requestFocus()
......
...@@ -34,14 +34,14 @@ class FirestoreManager { ...@@ -34,14 +34,14 @@ class FirestoreManager {
} }
fun addNewUser(firebaseUser: FirebaseUser, logInActivity: LogInActivity) { fun addNewUser(firebaseUser: FirebaseUser, logInActivity: LogInActivity) {
//todo add condition to writing to the db in Firebase Console (request.auth.uid) //todo addAll condition to writing to the db in Firebase Console (request.auth.uid)
vocabularyCollection.add(VocabularyPojo(null)) vocabularyCollection.add(VocabularyPojo(null))
.addOnSuccessListener { firstVocabularyRef -> .addOnSuccessListener { firstVocabularyRef ->
Log.d(TAG, "VocabularyPojo successfully created: " + firstVocabularyRef.path) Log.d(TAG, "VocabularyPojo successfully created: " + firstVocabularyRef.path)
setNewUserWithVocabularyData(firebaseUser, firstVocabularyRef, logInActivity) setNewUserWithVocabularyData(firebaseUser, firstVocabularyRef, logInActivity)
} }
.addOnFailureListener { .addOnFailureListener {
Log.w(TAG, "Couldn't add user to the database", it.cause) Log.w(TAG, "Couldn't addAll user to the database", it.cause)
mDeleteUser(firebaseUser) mDeleteUser(firebaseUser)
} }
} }
......
package com.paktalin.vocabularynotebook.vocabulary
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
class DisplayedVocabulary(override var wordList: MutableList<WordItem>): Vocabulary(wordList) {
var sort: Sort = Sort.BY_TIME
fun clear() {
wordList.clear()
}
fun size(): Int {
return wordList.size
}
fun at(index: Int): WordItem {
return wordList[index]
}
fun byQuery(query: String, allWords: MutableList<WordItem>) {
allWords.filter { wordItem -> wordItem.contains(query) }.toCollection(wordList)
}
fun sort(sort: Sort) {
this.sort = sort
when (sort) {
Sort.BY_TIME -> {
wordList.sortWith(Comparator { item1, item2 ->
-item1.pojo.time!!.compareTo(item2.pojo.time)
})
}
Sort.BY_WORD -> {
wordList.sortWith(Comparator { item1, item2 ->
item1.pojo.word.toLowerCase().compareTo(item2.pojo.word.toLowerCase())
})
}
Sort.BY_TRANSLATION -> {
wordList.sortWith(Comparator { item1, item2 ->
item1.pojo.translation.toLowerCase().compareTo(item2.pojo.translation.toLowerCase())
})
}
}
}
}
package com.paktalin.vocabularynotebook.vocabulary
import com.paktalin.vocabularynotebook.firestoreitems.ModifiedLabel
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.utils.FirestoreManager
class ModifiedVocabulary : Vocabulary() {
override var wordList = mutableListOf<WordItem>()
private val maxPermitted = 9
override fun addWord(newWord: WordItem) {
add(newWord, ModifiedLabel.ADDED)
}
override fun updateWord(updatedWord: WordItem) {
add(updatedWord, ModifiedLabel.UPDATED)
}
override fun deleteWord(wordItem: WordItem) {
add(wordItem, ModifiedLabel.DELETED)
}
override fun addAll(words: MutableList<WordItem>) { }
fun add(wordItem: WordItem, modifiedLabel: ModifiedLabel) {
wordItem.modifiedLabel = modifiedLabel
wordList.add(wordItem)
if (wordList.size == maxPermitted) {
FirestoreManager().saveWords(wordList.toMutableSet())
wordList.clear()
}
}
fun get(): MutableSet<WordItem> {
return wordList.toMutableSet()
}
}
package com.paktalin.vocabularynotebook.vocabulary
import com.paktalin.vocabularynotebook.firestoreitems.ModifiedLabel
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.utils.FirestoreManager
private const val MAX_PERMITTED = 9
class ModifiedWords {
private var modified = mutableSetOf<WordItem>()
fun add(wordItem: WordItem, modifiedLabel: ModifiedLabel) {
wordItem.modifiedLabel = modifiedLabel
modified.add(wordItem)
if (modified.size == MAX_PERMITTED) {
FirestoreManager().saveWords(modified)
modified.clear()
}
}
fun get(): MutableSet<WordItem> {
return modified
}
}
package com.paktalin.vocabularynotebook.vocabulary
enum class Sort {
BY_TIME, BY_WORD, BY_TRANSLATION
}
\ No newline at end of file
package com.paktalin.vocabularynotebook.vocabulary
import com.google.firebase.Timestamp
import com.google.firebase.firestore.QueryDocumentSnapshot
import com.google.firebase.firestore.QuerySnapshot
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
class VocabSet(override var wordList: MutableList<WordItem>) : Vocabulary() {
var fullVocabulary = Vocabulary(wordList)
private var displayedVocabulary = DisplayedVocabulary(wordList)
var modifiedVocabulary = ModifiedVocabulary()
private val vocabs = setOf(fullVocabulary, displayedVocabulary, modifiedVocabulary)
companion object {
fun createFromSnapshot(querySnapshot: QuerySnapshot): VocabSet {
val wordList = mutableListOf<WordItem>()
querySnapshot.forEach { s -> wordList.add(toWordItem(s)) }
return VocabSet(wordList)
}
private fun toWordItem(snapshot: QueryDocumentSnapshot): WordItem {
return WordItem(
snapshot["word"].toString(),
snapshot["translation"].toString(),
(snapshot["time"] as Timestamp).toDate(),
snapshot.id)
}
}
override fun addAll(words: MutableList<WordItem>) {
vocabs.forEach { v -> v.addAll(words) }
}
override fun updateWord(updatedWord: WordItem) {
vocabs.forEach { v -> v.updateWord(updatedWord) }
}
override fun deleteWord(wordItem: WordItem) {
vocabs.forEach { v -> v.deleteWord(wordItem) }
}
override fun addWord(newWord: WordItem) {
vocabs.forEach { v -> v.addWord(newWord) }
}
fun sort(sort: Sort) {
displayedVocabulary.sort(sort)
}
fun displayAll() {
displayedVocabulary.addAll(wordList)
}
fun displayByQuery(query: String) {
displayedVocabulary.byQuery(query, wordList)
}
fun displayedAt(position: Int): WordItem {
return displayedVocabulary.at(position)
}
fun displayedSize():Int { return displayedVocabulary.size() }
fun clearDisplayed() { displayedVocabulary.clear() }
fun getModified(): MutableSet<WordItem> { return modifiedVocabulary.get() }
}
\ No newline at end of file
package com.paktalin.vocabularynotebook.vocabulary package com.paktalin.vocabularynotebook.vocabulary
import android.util.Log
import com.google.firebase.Timestamp
import com.google.firebase.firestore.QuerySnapshot
import com.paktalin.vocabularynotebook.firestoreitems.ModifiedLabel
import com.paktalin.vocabularynotebook.firestoreitems.WordItem import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.utils.FirestoreManager.Companion.vocabularyId
class Vocabulary() { open class Vocabulary() {
private var allWords = mutableListOf<WordItem>() open lateinit var wordList: MutableList<WordItem>
private var displayed = mutableListOf<WordItem>()
internal var modified = ModifiedWords()
companion object { constructor(wordList: MutableList<WordItem>): this() {
private val TAG = "VN/" + Vocabulary::class.java.simpleName this.wordList = wordList
const val SORT_BY_TIME = 0
const val SORT_BY_WORD = 1
const val SORT_BY_TRANSLATION = 2
fun createFromSnapshot(querySnapshot: QuerySnapshot): Vocabulary {
val wordsFromDocs = mutableListOf<WordItem>()
querySnapshot.forEach { snapshot ->
wordsFromDocs.add(WordItem(
snapshot["word"].toString(),
snapshot["translation"].toString(),
(snapshot["time"] as Timestamp).toDate(),
snapshot.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) { open fun addAll(words: MutableList<WordItem>) {
when(sortOrder) { wordList.addAll(words)
SORT_BY_TIME -> sortByTime()
SORT_BY_WORD -> sortByWord()
SORT_BY_TRANSLATION -> sortByTranslation()
}
} }
fun deleteWord(wordItem: WordItem) { open fun deleteWord(wordItem: WordItem) {
allWords.remove(wordItem) wordList.remove(wordItem)
displayed.remove(wordItem)
modified.add(wordItem, ModifiedLabel.DELETED)
} }
fun addWord(newWord: WordItem) { open fun addWord(newWord: WordItem) {
allWords.add(0, newWord) wordList.add(0, newWord)
displayed.add(0, newWord)
modified.add(newWord, ModifiedLabel.ADDED)
} }
fun updateWord(updatedWord: WordItem) { open fun updateWord(updatedWord: WordItem) {
allWords[allWords.indexOf(updatedWord)] = updatedWord wordList[wordList.indexOf(updatedWord)] = updatedWord
displayed[displayed.indexOf(updatedWord)] = updatedWord
modified.add(updatedWord, ModifiedLabel.UPDATED)
}
fun displayAll() {
displayed.addAll(allWords)
}
fun displayByQuery(query: String) {
allWords.filter { wordItem -> wordItem.contains(query) }.toCollection(displayed)
}
fun displayedAt(position: Int): WordItem {
return displayed[position]
}
fun displayedSize():Int { return displayed.size }
fun clearDisplayed() { displayed.clear() }
private fun sortByTime() {
displayed.sortWith(Comparator { item1, item2 ->
-item1.pojo.time!!.compareTo(item2.pojo.time) })
}
private fun sortByWord() {
displayed.sortWith(Comparator { item1, item2 ->
item1.pojo.word.toLowerCase().compareTo(item2.pojo.word.toLowerCase()) })
}
private fun sortByTranslation() {
displayed.sortWith(Comparator { item1, item2 ->
item1.pojo.translation.toLowerCase().compareTo(item2.pojo.translation.toLowerCase()) })
} }
} }
\ No newline at end of file
...@@ -24,4 +24,8 @@ ...@@ -24,4 +24,8 @@
android:title="@string/sort_by_translation" android:title="@string/sort_by_translation"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/addTag"
android:title="@string/add_tag"
app:showAsAction="never" />
</menu> </menu>
\ No newline at end of file
...@@ -23,4 +23,5 @@ ...@@ -23,4 +23,5 @@
<string name="toast_enter_username_password">Please, enter username and password</string> <string name="toast_enter_username_password">Please, enter username and password</string>
<string name="toast_invalid_username">Please, create a username using letters a–z, numbers 0–9 and characters -_.</string> <string name="toast_invalid_username">Please, create a username using letters a–z, numbers 0–9 and characters -_.</string>
<string name="toast_incorrect_username_password">Username or password is incorrect</string> <string name="toast_incorrect_username_password">Username or password is incorrect</string>
<string name="add_tag">Add tag</string>
</resources> </resources>
package com.paktalin.vocabularynotebook
import com.paktalin.vocabularynotebook.firestoreitems.WordItem
import com.paktalin.vocabularynotebook.vocabulary.Vocabulary
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