main
Alexis Drai 3 years ago
parent bf4d530ac0
commit e064615a9d

@ -1,8 +1,10 @@
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
} }
android { android {
namespace 'fr.uca.iut.urbandictionarylight' namespace 'fr.uca.iut.urbandictionarylight'
compileSdk 33 compileSdk 33
@ -39,7 +41,6 @@ android {
} }
dependencies { dependencies {
implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.0' implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.8.0' implementation 'com.google.android.material:material:1.8.0'
@ -47,4 +48,10 @@ dependencies {
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
def room_version = "2.5.0"
def kotlin_version = "1.7.21"
def nav_version = "2.5.3"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
} }

@ -2,6 +2,7 @@ package fr.uca.iut.urbandictionarylight
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import fr.uca.iut.urbandictionarylight.data.UrbanDictionaryDatabase
import fr.uca.iut.urbandictionarylight.databinding.ActivityMainBinding import fr.uca.iut.urbandictionarylight.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {

@ -0,0 +1,22 @@
package fr.uca.iut.urbandictionarylight.data
import androidx.room.*
import fr.uca.iut.urbandictionarylight.model.Definition
@Dao
interface DefinitionDao {
@Query("SELECT * FROM definitions")
fun queryAll(): Set<Definition>
@Query("SELECT * FROM entries WHERE id == :id")
fun query(id: Int): Definition?
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(entry: Definition)
@Update
fun update(entry: Definition)
@Delete
fun delete(entry: Definition)
}

@ -0,0 +1,23 @@
package fr.uca.iut.urbandictionarylight.data
import androidx.room.*
import fr.uca.iut.urbandictionarylight.model.EntryWithDefinitions
@Dao
interface EntryDao {
@Query("SELECT * FROM entries")
fun queryAll(): List<EntryWithDefinitions>
@Query("SELECT * FROM entries WHERE id == :id")
fun query(id: Int): EntryWithDefinitions?
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(entry: EntryWithDefinitions)
@Update
fun update(entry: EntryWithDefinitions)
@Delete
fun delete(entry: EntryWithDefinitions)
}

@ -0,0 +1,96 @@
package fr.uca.iut.urbandictionarylight.data
import android.app.Application
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import fr.uca.iut.urbandictionarylight.model.Definition
import fr.uca.iut.urbandictionarylight.model.Entry
import fr.uca.iut.urbandictionarylight.model.EntryWithDefinitions
private const val DB_FILE = "u_d_light.db"
@Database(entities = [Entry::class, Definition::class], version = 1)
abstract class UrbanDictionaryDatabase : RoomDatabase() {
abstract fun entryDao(): EntryDao
abstract fun definitionDao(): DefinitionDao
companion object {
private lateinit var application: Application
@Volatile
private var instance: UrbanDictionaryDatabase? = null
fun getInstance(): UrbanDictionaryDatabase {
if (Companion::application.isInitialized) {
if (instance == null)
synchronized(this) {
if (instance == null) {
instance = Room.databaseBuilder(
application.applicationContext,
UrbanDictionaryDatabase::class.java,
DB_FILE
)
.allowMainThreadQueries()
.build()
instance?.entryDao()?.let {
if (it.queryAll().isEmpty()) emptyDatabaseStub(it)
}
}
}
return instance!!
} else
throw RuntimeException("the database must be initialized first")
}
//????
@Synchronized
fun initialize(app: Application) {
if (Companion::application.isInitialized)
throw RuntimeException("the database must not be initialized twice")
application = app
}
private fun emptyDatabaseStub(
entryDao: EntryDao,
definitionDao: DefinitionDao
): () -> Unit = {
val def1 = Definition("bleep", "bleep blap bloop", 1)
val def2 = Definition("blarp", "bleeeep blap bloop", 7)
val def3 = Definition("blep", "bleep blap blooop", 4)
val def4 = Definition("blupo", "bleep blaap bloop", 56)
with(definitionDao) {
insert(def1)
insert(def2)
insert(def3)
insert(def4)
}
with(entryDao) {
insert(
EntryWithDefinitions(
Entry("shrimping"),
listOf(def1, def4)
)
)
insert(
EntryWithDefinitions(
Entry("blunderkegel"),
listOf(def2)
)
)
insert(
EntryWithDefinitions(
Entry("something horrible and dumb"),
listOf(def3)
)
)
}
}
}
}

@ -1,11 +1,14 @@
package fr.uca.iut.urbandictionarylight.model package fr.uca.iut.urbandictionarylight.model
data class Definition(val content: String, val example: String) { import androidx.room.Entity
private var upvotes: UInt = 0u import androidx.room.PrimaryKey
fun getUpvotes() = upvotes const val NEW_DEFINITION_ID = 0L
fun upvote() { @Entity(tableName = "definitions")
upvotes++ data class Definition(
} val content: String,
} val example: String,
var upvotes: Int = 0,
@PrimaryKey(autoGenerate = true) val id: Long = NEW_DEFINITION_ID
)

@ -1,5 +1,9 @@
// UHM THIS WILL PROBABLY BE THE REPOSITORY ITSELF
/*
package fr.uca.iut.urbandictionarylight.model package fr.uca.iut.urbandictionarylight.model
@Entity
class Dictionary { class Dictionary {
private val entries: MutableSet<Entry> = mutableSetOf() private val entries: MutableSet<Entry> = mutableSetOf()
@ -38,4 +42,4 @@ class Dictionary {
} }
// TODO ? redefine equals and hashset ? // TODO ? redefine equals and hashset ?
} }*/

@ -1,61 +1,12 @@
package fr.uca.iut.urbandictionarylight.model package fr.uca.iut.urbandictionarylight.model
import fr.uca.iut.urbandictionarylight.utils.Sorting import androidx.room.Entity
import androidx.room.PrimaryKey
class Entry(val phrase: String) { const val NEW_ENTRY_ID = 0L
private val definitions: MutableSet<Definition> = mutableSetOf()
fun createDefinition(definition: Definition) { @Entity(tableName = "entries")
if (definition.content.isNotBlank() && definition.example.isNotBlank()) { data class Entry(
definitions.add(definition) val phrase: String,
} @PrimaryKey(autoGenerate = true) val id: Long = NEW_ENTRY_ID
} )
fun readDefinition(id: Int): Definition {
// TODO implement once ORM is in place
return Definition(
content = "poopy butt",
example = "Yeah, that's right -- poopy butt. This method hasn't been implemented yet."
)
}
fun readAllDefinitions() = definitions.toSet()
// TODO implement
fun readAllDefinitions(criterion: Sorting): Set<Definition> {
when (criterion) {
Sorting.ASC -> {
print("implement asc sorting!")
return readAllDefinitions()
}
Sorting.DESC -> {
print("implement desc sorting!")
return readAllDefinitions()
}
else -> return readAllDefinitions()
}
}
fun updateDefinition(definition: Definition) {
// TODO implement once ORM is in place
// removeDefinition(definition.id)
createDefinition(definition)
}
// TODO throw this away soon
fun updateDefinition(old: Definition, new: Definition) {
deleteDefinition(old)
createDefinition(new)
}
fun deleteDefinition(definition: Definition) {
definitions.remove(definition)
}
fun deleteDefinition(id: Int) {
// TODO implement once ORM is in place
// definitions.removeIf { def -> id == def.id }
}
// TODO redefine equals and hashset
}

@ -0,0 +1,12 @@
package fr.uca.iut.urbandictionarylight.model
import androidx.room.Embedded
import androidx.room.Relation
data class EntryWithDefinitions(
@Embedded val entry: Entry,
@Relation(
parentColumn = "id",
entityColumn = "entryId"
) val definitions: List<Definition>
)

@ -7,7 +7,7 @@
tools:context=".MainActivity"> tools:context=".MainActivity">
<SearchView <SearchView
android:id="@+id/searchView" android:id="@+id/search_view"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@ -19,7 +19,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recycler_view"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@ -29,10 +29,10 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchView" /> app:layout_constraintTop_toBottomOf="@+id/search_view" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addDefinitionBtn" android:id="@+id/add_definition_btn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
@ -42,11 +42,11 @@
android:focusable="true" android:focusable="true"
app:backgroundTint="#55752F" app:backgroundTint="#55752F"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchView" app:layout_constraintTop_toBottomOf="@+id/search_view"
app:srcCompat="@android:drawable/ic_input_add" /> app:srcCompat="@android:drawable/ic_input_add" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addTermBtn" android:id="@+id/add_term_btn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:layout_marginStart="24dp"
@ -56,27 +56,27 @@
android:focusable="true" android:focusable="true"
app:backgroundTint="#3E4E83" app:backgroundTint="#3E4E83"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchView" app:layout_constraintTop_toBottomOf="@+id/search_view"
app:srcCompat="@android:drawable/ic_input_add" /> app:srcCompat="@android:drawable/ic_input_add" />
<TextView <TextView
android:id="@+id/textView" android:id="@+id/add_definition_btn_lbl"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/add_term_lbl" android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent" android:text="@string/add_def_lbl"
app:layout_constraintTop_toBottomOf="@+id/addTermBtn" /> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_definition_btn" />
<TextView <TextView
android:id="@+id/textView2" android:id="@+id/add_term_btn_lbl"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" android:text="@string/add_term_lbl"
android:text="@string/add_def_lbl" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/add_term_btn" />
app:layout_constraintTop_toBottomOf="@+id/addDefinitionBtn" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save