Compare commits
44 commits
azea/Room_
...
ophelia_ma
Author | SHA1 | Date | |
---|---|---|---|
8dc75190b5 | |||
e08986e8c1 | |||
3d8451b8cf | |||
956095e513 | |||
11913f3f2e | |||
3a8209433f | |||
235a9c400b | |||
6261f2da31 | |||
847b8072c7 | |||
0dadceb1b8 | |||
05822226af | |||
1b43a34586 | |||
70468fbb4b | |||
c92e657038 | |||
1f3c59c407 | |||
25a73f0970 | |||
dcc1cb3010 | |||
7ee1d54964 | |||
6eded27a9e | |||
2080658c4d | |||
160610e09c | |||
971c1b2a6f | |||
1be2a90d53 | |||
a3f65d4fff | |||
2f38327c74 | |||
749534f682 | |||
c93d38627f | |||
aaa5704e5d | |||
1b5726ff37 | |||
dff3e17a4e | |||
60deb40b95 | |||
56229c7d22 | |||
1ed455aeca | |||
295ea6413f | |||
a1ace2dcb6 | |||
8b6121715e | |||
d92e177a74 | |||
9869529c37 | |||
3ddab9d8b1 | |||
443745e32e | |||
1089745861 | |||
4f3c9e4971 | |||
c55d040ca0 | |||
ebe20655eb |
69 changed files with 2561 additions and 404 deletions
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
|
|
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
|
@ -1,4 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MarkdownSettingsMigration">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'com.google.devtools.ksp'
|
||||
}
|
||||
|
||||
android {
|
||||
|
@ -12,7 +13,7 @@ android {
|
|||
minSdk 27
|
||||
targetSdk 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
versionName "e1.0.0.b7"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
|
@ -27,11 +28,11 @@ android {
|
|||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
jvmTarget = '17'
|
||||
}
|
||||
buildFeatures {
|
||||
compose true
|
||||
|
@ -48,14 +49,24 @@ android {
|
|||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
def activity_version = '1.8.0'
|
||||
def lifecycle_version = "2.6.2"
|
||||
def arch_version = "2.2.0"
|
||||
def roomVersion = '2.3.0'
|
||||
def nav_version = "2.7.4" //Fragment
|
||||
def fragment_version = "1.6.1"
|
||||
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation "androidx.activity:activity-ktx:$activity_version"
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
|
||||
implementation 'androidx.activity:activity-compose:1.8.0'
|
||||
implementation platform('androidx.compose:compose-bom:2023.03.00')
|
||||
implementation 'androidx.compose.ui:ui'
|
||||
implementation 'androidx.compose.ui:ui-graphics'
|
||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||
implementation 'androidx.compose.material3:material3'
|
||||
implementation 'androidx.compose.material3:material3:1.1.2'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
|
@ -66,4 +77,57 @@ dependencies {
|
|||
implementation 'androidx.room:room-common:2.5.2'
|
||||
implementation 'androidx.room:room-ktx:2.5.2'
|
||||
implementation 'androidx.navigation:navigation-runtime-ktx:2.7.4'
|
||||
|
||||
implementation('androidx.constraintlayout:constraintlayout-compose-android:1.1.0-alpha13')
|
||||
implementation 'androidx.core:core-splashscreen:1.0.1'
|
||||
implementation "androidx.navigation:navigation-compose:$nav_version"
|
||||
|
||||
|
||||
// ViewModel
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
|
||||
// ViewModel utilities for Compose
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
|
||||
// LiveData
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
|
||||
// Lifecycles only (without ViewModel or LiveData)
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
|
||||
// Lifecycle utilities for Compose
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-compose:$lifecycle_version"
|
||||
|
||||
|
||||
|
||||
// Kotlin
|
||||
implementation "androidx.fragment:fragment-ktx:$fragment_version"
|
||||
|
||||
// Saved state module for ViewModel
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
|
||||
|
||||
ksp 'androidx.room:room-compiler:2.5.0'
|
||||
|
||||
// Annotation processor
|
||||
annotationProcessor "androidx.room:room-compiler:$roomVersion"
|
||||
// alternately - if using Java8, use the following instead of lifecycle-compiler
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
|
||||
|
||||
// optional - helpers for implementing LifecycleOwner in a Service
|
||||
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
|
||||
|
||||
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
|
||||
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
|
||||
|
||||
// optional - ReactiveStreams support for LiveData
|
||||
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
|
||||
|
||||
// optional - Test helpers for LiveData
|
||||
testImplementation "androidx.arch.core:core-testing:$arch_version"
|
||||
|
||||
// optional - Test helpers for Lifecycle runtime
|
||||
testImplementation "androidx.lifecycle:lifecycle-runtime-testing:$lifecycle_version"
|
||||
|
||||
//Runtime
|
||||
implementation "androidx.compose.runtime:runtime:1.5.3"
|
||||
implementation "androidx.compose.runtime:runtime-livedata:1.5.3"
|
||||
implementation "androidx.compose.runtime:runtime-rxjava2:1.5.3"
|
||||
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application
|
||||
android:name=".database.polycule.PolyculeApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
|
@ -13,16 +14,23 @@
|
|||
android:theme="@style/Theme.Ophelia"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name=".view.splash.SplashActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.Ophelia">
|
||||
android:theme="@style/SplashScreenTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
/>
|
||||
|
||||
<meta-data
|
||||
android:name="preloaded_fonts"
|
||||
android:resource="@array/preloaded_fonts" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,58 +1,27 @@
|
|||
package com.menagerie.ophelia
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Window
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeDatabase
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeApplication
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeDatabaseManager
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeRepository
|
||||
import com.menagerie.ophelia.ui.theme.OpheliaTheme
|
||||
import com.menagerie.ophelia.view.PolyculeApp
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
private val db by lazy { PolyculeDatabase.getDatabase(this) }
|
||||
private val polyculeRepository by lazy {
|
||||
PolyculeRepository(
|
||||
bioDao = db.bioDao()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
PolyculeDatabaseManager.polyculeRepository = polyculeRepository
|
||||
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
setContent {
|
||||
OpheliaTheme {
|
||||
// A surface container using the 'background' color from the theme
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
Greeting("Android")
|
||||
val repository = (application as PolyculeApplication).repository
|
||||
PolyculeDatabaseManager.polyculeRepository = repository
|
||||
Surface {
|
||||
PolyculeApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = "Hello $name!",
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun GreetingPreview() {
|
||||
OpheliaTheme {
|
||||
Greeting("Android")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
package com.menagerie.ophelia.database.polycule
|
||||
|
||||
import android.util.LruCache
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
abstract class CachedDao<K, V> (capacity: Int = 100) {
|
||||
|
||||
private val cache: LruCache<K, V> = LruCache(capacity)
|
||||
|
||||
private val cacheMutex: Mutex = Mutex()
|
||||
|
||||
protected suspend fun <R> withDaoCache(cacheBlock: suspend LruCache<K, V>.()->R): R {
|
||||
return cacheMutex.withLock {
|
||||
cacheBlock(cache)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.menagerie.ophelia.database.polycule
|
||||
|
||||
import android.app.Application
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
|
||||
class PolyculeApplication : Application() {
|
||||
|
||||
private val applicationScope = CoroutineScope(SupervisorJob())
|
||||
|
||||
val database by lazy { PolyculeDatabase.getDatabase(this, applicationScope) }
|
||||
val repository by lazy { PolyculeRepository(database.bioDao()) }
|
||||
}
|
|
@ -1,15 +1,19 @@
|
|||
package com.menagerie.ophelia.database.polycule
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.BioDao
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@Database(
|
||||
version = 1,
|
||||
version = 3,
|
||||
exportSchema = false,
|
||||
entities = [
|
||||
Bio::class
|
||||
|
@ -23,19 +27,53 @@ abstract class PolyculeDatabase : RoomDatabase() {
|
|||
@Volatile
|
||||
private var INSTANCE: PolyculeDatabase? = null
|
||||
|
||||
fun getDatabase(context: Context): PolyculeDatabase {
|
||||
fun getDatabase(
|
||||
context: Context,
|
||||
scope: CoroutineScope,
|
||||
): PolyculeDatabase {
|
||||
return INSTANCE ?: synchronized(this)
|
||||
{
|
||||
val instance = Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
PolyculeDatabase::class.java,
|
||||
PolyculeDatabase::class.java,
|
||||
"polycule.db"
|
||||
)
|
||||
.fallbackToDestructiveMigration()
|
||||
.addCallback(PolyculeDatabaseCallback(scope))
|
||||
.build()
|
||||
INSTANCE = instance
|
||||
instance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PolyculeDatabaseCallback(
|
||||
private val scope: CoroutineScope
|
||||
) : Callback() {
|
||||
override fun onCreate(db: SupportSQLiteDatabase) {
|
||||
super.onCreate(db)
|
||||
INSTANCE?.let { database ->
|
||||
scope.launch {
|
||||
//populateDatabase(database.bioDao())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun populateDatabase(bioDao: BioDao) {
|
||||
var bio = Bio(
|
||||
name = "Azea",
|
||||
)
|
||||
bioDao.insert(bio)
|
||||
|
||||
bio = Bio(
|
||||
name = "Darkwood Mill",
|
||||
)
|
||||
bioDao.insert(bio)
|
||||
|
||||
bio = Bio(
|
||||
name = "Blizzard",
|
||||
)
|
||||
bioDao.insert(bio)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,5 @@
|
|||
package com.menagerie.ophelia.database.polycule
|
||||
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
|
||||
object PolyculeDatabaseManager {
|
||||
|
||||
lateinit var polyculeRepository : PolyculeRepository
|
||||
|
||||
suspend fun post(bio: Bio) {
|
||||
polyculeRepository.upsertBio(bio)
|
||||
}
|
||||
lateinit var polyculeRepository: PolyculeRepository
|
||||
}
|
|
@ -1,15 +1,38 @@
|
|||
package com.menagerie.ophelia.database.polycule
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.asLiveData
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.BioDao
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class PolyculeRepository(
|
||||
private val bioDao: BioDao
|
||||
) {
|
||||
|
||||
suspend fun upsertBio(bio: Bio): Long {
|
||||
return bioDao.findOrInsert(bio)
|
||||
suspend fun upsertBio(bio: Bio) {
|
||||
bioDao.upsert(bio)
|
||||
}
|
||||
|
||||
fun getAlphabetisedBios(): Flow<List<Bio>> {
|
||||
return bioDao.getAllAlphabetisedBios()
|
||||
}
|
||||
|
||||
fun getBio(bioId: Long): Flow<Bio> {
|
||||
return bioDao.getBio(bioId)
|
||||
}
|
||||
|
||||
fun getAllBios(): Flow<List<Bio>> {
|
||||
return bioDao.getAllBios()
|
||||
}
|
||||
|
||||
suspend fun insert(bio: Bio) {
|
||||
bioDao.insert(bio)
|
||||
}
|
||||
|
||||
suspend fun delete(bio: Bio) {
|
||||
bioDao.delete(bio)
|
||||
}
|
||||
|
||||
fun hasPolycule() = false
|
||||
}
|
|
@ -1,19 +1,20 @@
|
|||
package com.menagerie.ophelia.database.polycule.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.menagerie.ophelia.R
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Identity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["uniqueId"]
|
||||
)
|
||||
]
|
||||
tableName = "bio_table",
|
||||
)
|
||||
data class Bio(
|
||||
@PrimaryKey(autoGenerate = true) val id: Long,
|
||||
/*FK*/ val uniqueId: Long
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
@ColumnInfo(name = "name") var name: String = "",
|
||||
@ColumnInfo(name = "subject_pronoun") val subjective: String = "",
|
||||
@ColumnInfo(name = "object_pronoun") val objective: String = "",
|
||||
@ColumnInfo(name = "possess_pronoun") val possessive: String = "",
|
||||
@ColumnInfo(name = "reflex_pronoun") val reflexive: String = "",
|
||||
@ColumnInfo(name="tags") var tags: Int = 0,
|
||||
@ColumnInfo(name = "pfpRes") val pfpRes: Int = R.drawable.ic_app_logo,
|
||||
)
|
|
@ -1,45 +1,34 @@
|
|||
package com.menagerie.ophelia.database.polycule.entity
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import com.menagerie.ophelia.database.polycule.CachedDao
|
||||
import androidx.room.Upsert
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class BioDao : CachedDao<Long, Bio>() {
|
||||
abstract class BioDao {
|
||||
|
||||
@Insert
|
||||
abstract suspend fun insert(newBio: Bio): Long
|
||||
|
||||
@Delete
|
||||
abstract suspend fun delete(bio: Bio)
|
||||
|
||||
@Update
|
||||
abstract suspend fun update(existingBio: Bio)
|
||||
|
||||
@Query("SELECT * FROM Bio WHERE uniqueId = :uniqueId")
|
||||
abstract suspend fun findByUniqueId(uniqueId: Long): Bio?
|
||||
@Query("SELECT * FROM bio_table ORDER BY name ASC")
|
||||
abstract fun getAllAlphabetisedBios(): Flow<List<Bio>>
|
||||
|
||||
@Transaction
|
||||
open suspend fun findOrInsert(bio: Bio): Long {
|
||||
return withDaoCache {
|
||||
val key = bio.uniqueId
|
||||
val returnVal: Bio =
|
||||
get(key)
|
||||
@Query("SELECT * FROM bio_table")
|
||||
abstract fun getAllBios(): Flow<List<Bio>>
|
||||
|
||||
?: findByUniqueId(key)
|
||||
?: run {
|
||||
val newId: Long = insert(bio)
|
||||
bio.copy(id = newId)
|
||||
}
|
||||
if (bio != returnVal) {
|
||||
if (returnVal.id == 0L) {
|
||||
insert(bio)
|
||||
} else {
|
||||
update(bio)
|
||||
}
|
||||
}
|
||||
put(key, returnVal)
|
||||
returnVal.id
|
||||
}
|
||||
}
|
||||
@Query("SELECT * FROM bio_table WHERE id = :bioId")
|
||||
abstract fun getBio(bioId: Long): Flow<Bio>
|
||||
|
||||
@Upsert
|
||||
abstract suspend fun upsert(bio: Bio): Long
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package com.menagerie.ophelia.database.polycule.entity
|
||||
|
||||
import android.graphics.drawable.Icon
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
|
||||
],
|
||||
indices = [
|
||||
|
||||
]
|
||||
)
|
||||
class Identity (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val uniqueId: Long = 0,
|
||||
val name: String = "",
|
||||
val icon: Icon,
|
||||
)
|
|
@ -1,21 +0,0 @@
|
|||
package com.menagerie.ophelia.database.polycule.entity
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import androidx.room.Update
|
||||
import com.menagerie.ophelia.database.polycule.entity.Identity
|
||||
|
||||
@Dao
|
||||
abstract class IdentityDao {
|
||||
@Insert
|
||||
abstract suspend fun insert(identity: Identity): Long
|
||||
|
||||
@Update
|
||||
abstract suspend fun update(idenity: Identity)
|
||||
|
||||
@Query("SELECT * FROM Identity WHERE uniqueId = :uniqueId")
|
||||
abstract suspend fun findByIdentity(uniqueId : Long): Identity?
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.menagerie.ophelia.database.polycule.entity.viewmodel
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.asLiveData
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeDatabaseManager
|
||||
|
||||
class BioDetailViewModel(
|
||||
id: Long
|
||||
) : ViewModel() {
|
||||
var bio = PolyculeDatabaseManager.polyculeRepository.getBio(id).asLiveData()
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.menagerie.ophelia.database.polycule.entity.viewmodel
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeDatabaseManager
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class BioListViewModel() : ViewModel() {
|
||||
|
||||
val allBios: LiveData<List<Bio>> =
|
||||
PolyculeDatabaseManager.polyculeRepository.getAllBios().asLiveData()
|
||||
|
||||
fun upsert(bio: Bio) = viewModelScope.launch {
|
||||
PolyculeDatabaseManager.polyculeRepository.upsertBio(bio)
|
||||
}
|
||||
|
||||
fun delete(bio: Bio) = viewModelScope.launch {
|
||||
PolyculeDatabaseManager.polyculeRepository.delete(bio)
|
||||
}
|
||||
|
||||
class BioListViewModelFactory() :
|
||||
ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
if (modelClass.isAssignableFrom(BioListViewModel::class.java)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return BioListViewModel() as T
|
||||
}
|
||||
throw IllegalArgumentException("Unknown ViewModel Class")
|
||||
}
|
||||
}
|
||||
class InputBioViewModel : ViewModel() {
|
||||
private val _bio: MutableLiveData<Bio> = MutableLiveData(Bio())
|
||||
val bio: LiveData<Bio> = _bio
|
||||
fun onNameChange(name: String) {
|
||||
val newBio = Bio(
|
||||
name = name,
|
||||
)
|
||||
_bio.value = newBio
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,65 @@
|
|||
package com.menagerie.ophelia.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val Purple80 = Color(0xFFD0BCFF)
|
||||
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||
val Pink80 = Color(0xFFEFB8C8)
|
||||
val md_theme_light_primary = Color(0xFF366A21)
|
||||
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
|
||||
val md_theme_light_primaryContainer = Color(0xFFB6F398)
|
||||
val md_theme_light_onPrimaryContainer = Color(0xFF052100)
|
||||
val md_theme_light_secondary = Color(0xFF55624C)
|
||||
val md_theme_light_onSecondary = Color(0xFFFFFFFF)
|
||||
val md_theme_light_secondaryContainer = Color(0xFFD8E7CB)
|
||||
val md_theme_light_onSecondaryContainer = Color(0xFF131F0D)
|
||||
val md_theme_light_tertiary = Color(0xFF386667)
|
||||
val md_theme_light_onTertiary = Color(0xFFFFFFFF)
|
||||
val md_theme_light_tertiaryContainer = Color(0xFFBBEBEC)
|
||||
val md_theme_light_onTertiaryContainer = Color(0xFF002021)
|
||||
val md_theme_light_error = Color(0xFFBA1A1A)
|
||||
val md_theme_light_errorContainer = Color(0xFFFFDAD6)
|
||||
val md_theme_light_onError = Color(0xFFFFFFFF)
|
||||
val md_theme_light_onErrorContainer = Color(0xFF410002)
|
||||
val md_theme_light_background = Color(0xFFFDFDF6)
|
||||
val md_theme_light_onBackground = Color(0xFF1A1C18)
|
||||
val md_theme_light_outline = Color(0xFF73796E)
|
||||
val md_theme_light_inverseOnSurface = Color(0xFFF1F1EA)
|
||||
val md_theme_light_inverseSurface = Color(0xFF2F312D)
|
||||
val md_theme_light_inversePrimary = Color(0xFF9BD67F)
|
||||
val md_theme_light_surfaceTint = Color(0xFF366A21)
|
||||
val md_theme_light_outlineVariant = Color(0xFFC3C8BB)
|
||||
val md_theme_light_scrim = Color(0xFF000000)
|
||||
val md_theme_light_surface = Color(0xFFD8D8C4)
|
||||
val md_theme_light_onSurface = Color(0xFF1A1C18)
|
||||
val md_theme_light_surfaceVariant = Color(0xFFDFE4D7)
|
||||
val md_theme_light_onSurfaceVariant = Color(0xFF43483F)
|
||||
|
||||
val Purple40 = Color(0xFF6650a4)
|
||||
val PurpleGrey40 = Color(0xFF625b71)
|
||||
val Pink40 = Color(0xFF7D5260)
|
||||
val md_theme_dark_primary = Color(0xFF9BD67F)
|
||||
val md_theme_dark_onPrimary = Color(0xFF0E3900)
|
||||
val md_theme_dark_primaryContainer = Color(0xFF1E5108)
|
||||
val md_theme_dark_onPrimaryContainer = Color(0xFFB6F398)
|
||||
val md_theme_dark_secondary = Color(0xFFBCCBB0)
|
||||
val md_theme_dark_onSecondary = Color(0xFF273421)
|
||||
val md_theme_dark_secondaryContainer = Color(0xFF3D4B36)
|
||||
val md_theme_dark_onSecondaryContainer = Color(0xFFD8E7CB)
|
||||
val md_theme_dark_tertiary = Color(0xFFA0CFD0)
|
||||
val md_theme_dark_onTertiary = Color(0xFF003738)
|
||||
val md_theme_dark_tertiaryContainer = Color(0xFF1E4E4F)
|
||||
val md_theme_dark_onTertiaryContainer = Color(0xFFBBEBEC)
|
||||
val md_theme_dark_error = Color(0xFFFFB4AB)
|
||||
val md_theme_dark_errorContainer = Color(0xFF93000A)
|
||||
val md_theme_dark_onError = Color(0xFF690005)
|
||||
val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
|
||||
val md_theme_dark_background = Color(0xFF1C1C18)
|
||||
val md_theme_dark_onBackground = Color(0xFFE3E3DC)
|
||||
val md_theme_dark_outline = Color(0xFF8D9287)
|
||||
val md_theme_dark_inverseOnSurface = Color(0xFF1A1C18)
|
||||
val md_theme_dark_inverseSurface = Color(0xFFE3E3DC)
|
||||
val md_theme_dark_inversePrimary = Color(0xFF366A21)
|
||||
val md_theme_dark_surfaceTint = Color(0xFF9BD67F)
|
||||
val md_theme_dark_outlineVariant = Color(0xFF43483F)
|
||||
val md_theme_dark_scrim = Color(0xFF000000)
|
||||
val md_theme_dark_surface = Color(0xFF2B2822)
|
||||
val md_theme_dark_onSurface = Color(0xFFC6C7C0)
|
||||
val md_theme_dark_surfaceVariant = Color(0xFF43483F)
|
||||
val md_theme_dark_onSurfaceVariant = Color(0xFFC3C8BB)
|
||||
|
||||
|
||||
val seed = Color(0xFF5E9546)
|
|
@ -1,54 +1,93 @@
|
|||
package com.menagerie.ophelia.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.WindowCompat
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Purple80,
|
||||
secondary = PurpleGrey80,
|
||||
tertiary = Pink80
|
||||
)
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Purple40,
|
||||
secondary = PurpleGrey40,
|
||||
tertiary = Pink40
|
||||
primary = md_theme_light_primary,
|
||||
onPrimary = md_theme_light_onPrimary,
|
||||
primaryContainer = md_theme_light_primaryContainer,
|
||||
onPrimaryContainer = md_theme_light_onPrimaryContainer,
|
||||
secondary = md_theme_light_secondary,
|
||||
onSecondary = md_theme_light_onSecondary,
|
||||
secondaryContainer = md_theme_light_secondaryContainer,
|
||||
onSecondaryContainer = md_theme_light_onSecondaryContainer,
|
||||
tertiary = md_theme_light_tertiary,
|
||||
onTertiary = md_theme_light_onTertiary,
|
||||
tertiaryContainer = md_theme_light_tertiaryContainer,
|
||||
onTertiaryContainer = md_theme_light_onTertiaryContainer,
|
||||
error = md_theme_light_error,
|
||||
errorContainer = md_theme_light_errorContainer,
|
||||
onError = md_theme_light_onError,
|
||||
onErrorContainer = md_theme_light_onErrorContainer,
|
||||
background = md_theme_light_background,
|
||||
onBackground = md_theme_light_onBackground,
|
||||
outline = md_theme_light_outline,
|
||||
inverseOnSurface = md_theme_light_inverseOnSurface,
|
||||
inverseSurface = md_theme_light_inverseSurface,
|
||||
inversePrimary = md_theme_light_inversePrimary,
|
||||
surfaceTint = md_theme_light_surfaceTint,
|
||||
outlineVariant = md_theme_light_outlineVariant,
|
||||
scrim = md_theme_light_scrim,
|
||||
surface = md_theme_light_surface,
|
||||
onSurface = md_theme_light_onSurface,
|
||||
surfaceVariant = md_theme_light_surfaceVariant,
|
||||
onSurfaceVariant = md_theme_light_onSurfaceVariant,
|
||||
)
|
||||
|
||||
/* Other default colors to override
|
||||
background = Color(0xFFFFFBFE),
|
||||
surface = Color(0xFFFFFBFE),
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.White,
|
||||
onTertiary = Color.White,
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
onSurface = Color(0xFF1C1B1F),
|
||||
*/
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = md_theme_dark_primary,
|
||||
onPrimary = md_theme_dark_onPrimary,
|
||||
primaryContainer = md_theme_dark_primaryContainer,
|
||||
onPrimaryContainer = md_theme_dark_onPrimaryContainer,
|
||||
secondary = md_theme_dark_secondary,
|
||||
onSecondary = md_theme_dark_onSecondary,
|
||||
secondaryContainer = md_theme_dark_secondaryContainer,
|
||||
onSecondaryContainer = md_theme_dark_onSecondaryContainer,
|
||||
tertiary = md_theme_dark_tertiary,
|
||||
onTertiary = md_theme_dark_onTertiary,
|
||||
tertiaryContainer = md_theme_dark_tertiaryContainer,
|
||||
onTertiaryContainer = md_theme_dark_onTertiaryContainer,
|
||||
error = md_theme_dark_error,
|
||||
errorContainer = md_theme_dark_errorContainer,
|
||||
onError = md_theme_dark_onError,
|
||||
onErrorContainer = md_theme_dark_onErrorContainer,
|
||||
background = md_theme_dark_background,
|
||||
onBackground = md_theme_dark_onBackground,
|
||||
outline = md_theme_dark_outline,
|
||||
inverseOnSurface = md_theme_dark_inverseOnSurface,
|
||||
inverseSurface = md_theme_dark_inverseSurface,
|
||||
inversePrimary = md_theme_dark_inversePrimary,
|
||||
surfaceTint = md_theme_dark_surfaceTint,
|
||||
outlineVariant = md_theme_dark_outlineVariant,
|
||||
scrim = md_theme_dark_scrim,
|
||||
surface = md_theme_dark_surface,
|
||||
onSurface = md_theme_dark_onSurface,
|
||||
surfaceVariant = md_theme_dark_surfaceVariant,
|
||||
onSurfaceVariant = md_theme_dark_onSurfaceVariant,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun OpheliaTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
// Dynamic color is available on Android 12+
|
||||
dynamicColor: Boolean = true,
|
||||
content: @Composable () -> Unit
|
||||
content: @Composable() () -> Unit
|
||||
) {
|
||||
val colorScheme = when {
|
||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||
val context = LocalContext.current
|
||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
}
|
||||
// dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||
// val context = LocalContext.current
|
||||
// if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
// }
|
||||
|
||||
darkTheme -> DarkColorScheme
|
||||
else -> LightColorScheme
|
||||
|
|
|
@ -4,17 +4,26 @@ import androidx.compose.material3.Typography
|
|||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// Set of Material typography styles to start with
|
||||
val Typography = Typography(
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontFamily = FontFamily.Serif,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
),
|
||||
displayLarge = TextStyle(
|
||||
fontFamily = FontFamily.Cursive,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 64.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp,
|
||||
textDecoration = TextDecoration.Underline
|
||||
),
|
||||
/* Other default text styles to override
|
||||
titleLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
|
|
67
app/src/main/java/com/menagerie/ophelia/view/HomeScreen.kt
Normal file
67
app/src/main/java/com/menagerie/ophelia/view/HomeScreen.kt
Normal file
|
@ -0,0 +1,67 @@
|
|||
package com.menagerie.ophelia.view
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.menagerie.ophelia.R
|
||||
import com.menagerie.ophelia.ui.theme.OpheliaTheme
|
||||
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
onClick: () -> Unit,
|
||||
|
||||
) {
|
||||
val text = if(true) R.string.welcome else R.string.welcome_back
|
||||
HeaderText(text, onClick)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HeaderText(
|
||||
text: Int,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 10.dp)
|
||||
.align(Alignment.Center),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Text(
|
||||
text = stringResource(id = R.string.app_name),
|
||||
style = MaterialTheme.typography.displayLarge
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.app_tag)
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Button(
|
||||
modifier = Modifier.padding(12.dp),
|
||||
onClick = onClick
|
||||
) {
|
||||
Text(text = stringResource(id = text))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.menagerie.ophelia.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun NewUserStartScreen(
|
||||
onGo: () -> Unit = {},
|
||||
) {
|
||||
|
||||
Scaffold {
|
||||
Column {
|
||||
OpheliaFace(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(top = 12.dp)
|
||||
)
|
||||
OpheliaWelcome(modifier = Modifier.weight(1f))
|
||||
Button(
|
||||
onClick = onGo,
|
||||
modifier = Modifier
|
||||
.padding(12.dp)
|
||||
.align(Alignment.End)
|
||||
) {
|
||||
Text(text = "Go")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun NewUserPreview(){
|
||||
NewUserStartScreen()
|
||||
}
|
168
app/src/main/java/com/menagerie/ophelia/view/Ophelia.kt
Normal file
168
app/src/main/java/com/menagerie/ophelia/view/Ophelia.kt
Normal file
|
@ -0,0 +1,168 @@
|
|||
package com.menagerie.ophelia.view
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.modifier.modifierLocalConsumer
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringArrayResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.Font
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.menagerie.ophelia.R
|
||||
|
||||
@Composable
|
||||
fun OpheliaSpanStyle(): SpanStyle {
|
||||
val fontFamily = FontFamily(
|
||||
Font(R.font.calligraffitti)
|
||||
)
|
||||
|
||||
return SpanStyle(
|
||||
letterSpacing = MaterialTheme.typography.bodyLarge.letterSpacing,
|
||||
fontFamily = fontFamily,
|
||||
fontSize = MaterialTheme.typography.bodyLarge.fontSize)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaFace(
|
||||
modifier: Modifier
|
||||
) {
|
||||
Image(
|
||||
modifier = modifier,
|
||||
painter = painterResource(id = R.drawable.ophelia_foreground),
|
||||
contentDescription = OpheliaSays()
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaSaysArray(
|
||||
id: Int,
|
||||
separator: String = "\n\n"
|
||||
): AnnotatedString {
|
||||
return buildAnnotatedString {
|
||||
pushStyle(OpheliaSpanStyle())
|
||||
append(stringArrayResource(id = id).joinToString(separator = separator))
|
||||
toAnnotatedString()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaSays(
|
||||
say: String
|
||||
): AnnotatedString {
|
||||
return buildAnnotatedString {
|
||||
pushStyle(OpheliaSpanStyle())
|
||||
append(say)
|
||||
toAnnotatedString()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaSays(): String {
|
||||
return stringResource(id = R.string.ophelia_says)
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun OpheliaWelcome(
|
||||
modifier: Modifier
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(24.dp)
|
||||
) {
|
||||
Text(
|
||||
text = OpheliaSaysArray(id = R.array.welcome_blurb)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaWhatsYourName(
|
||||
modifier: Modifier
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Text(text = OpheliaSaysArray(id = R.array.whats_your_name))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaPronounsIntroduction(
|
||||
modifier: Modifier,
|
||||
name: String
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Column {
|
||||
val context = LocalContext.current
|
||||
Text(text = OpheliaSays(context.resources.getString(R.string.introduction_with_name, name)))
|
||||
Text(text = OpheliaSaysArray(id = R.array.introduction_to_pronouns))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaTagsIntroduction(
|
||||
modifier: Modifier,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Column {
|
||||
Text(text = OpheliaSaysArray(R.array.introduction_to_tags))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaNewUserFinalCheck(
|
||||
modifier: Modifier,
|
||||
){
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Column {
|
||||
Text(text = OpheliaSays(stringResource(id = R.string.final_check_in)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OpheliaNewUserPolycule(
|
||||
modifier: Modifier,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Column {
|
||||
Text(text = OpheliaSaysArray(id = R.array.introduction_to_polycules))
|
||||
}
|
||||
}
|
||||
}
|
108
app/src/main/java/com/menagerie/ophelia/view/PolyculeApp.kt
Normal file
108
app/src/main/java/com/menagerie/ophelia/view/PolyculeApp.kt
Normal file
|
@ -0,0 +1,108 @@
|
|||
package com.menagerie.ophelia.view
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeDatabaseManager
|
||||
import com.menagerie.ophelia.view.biographies.AddBiography
|
||||
import com.menagerie.ophelia.view.biographies.AddEditBio
|
||||
import com.menagerie.ophelia.view.biographies.BioDetailsScreen
|
||||
import com.menagerie.ophelia.view.biographies.EditBiography
|
||||
import com.menagerie.ophelia.view.newUser.AddNameScreen
|
||||
import com.menagerie.ophelia.view.newUser.AddPronounsScreen
|
||||
import com.menagerie.ophelia.view.newUser.AddTagsScreen
|
||||
import com.menagerie.ophelia.view.newUser.ConfirmBio
|
||||
import com.menagerie.ophelia.view.polycule.AddPolyculeScreen
|
||||
import com.menagerie.ophelia.view.polycule.PolyculeHomeView
|
||||
|
||||
@Composable
|
||||
fun PolyculeApp() {
|
||||
val navController = rememberNavController()
|
||||
PolyculeNavHost(
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PolyculeNavHost(
|
||||
navController: NavHostController
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = "confirmBio"
|
||||
) {
|
||||
polyculeGraph(navController)
|
||||
welcomeGraph(navController)
|
||||
composable("home") {
|
||||
HomeScreen() {
|
||||
navController.navigate("newUserStart")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun NavGraphBuilder.welcomeGraph(navController: NavHostController) {
|
||||
composable("newUserStart") {
|
||||
NewUserStartScreen { navController.navigate("newUserName") }
|
||||
}
|
||||
composable("newUserName") {
|
||||
AddNameScreen { navController.navigate("newUserPronouns") }
|
||||
}
|
||||
composable("newUserPronouns") {
|
||||
AddPronounsScreen { navController.navigate("newUserTags") }
|
||||
}
|
||||
composable("newUserTags") {
|
||||
AddTagsScreen { navController.navigate("confirmBio") }
|
||||
}
|
||||
composable("confirmBio") {
|
||||
ConfirmBio {
|
||||
navController.popBackStack()
|
||||
navController.navigate("polyculeHome")
|
||||
}
|
||||
}
|
||||
composable("makePolycule") {
|
||||
AddPolyculeScreen()
|
||||
}
|
||||
}
|
||||
|
||||
fun NavGraphBuilder.polyculeGraph(navController: NavController) {
|
||||
composable("polyculeHome") {
|
||||
PolyculeHomeView(
|
||||
onBioClick = {
|
||||
navController.navigate("bioDetail/${it.id}")
|
||||
},
|
||||
onAddClick = {
|
||||
navController.navigate("addBio") {}
|
||||
}
|
||||
)
|
||||
}
|
||||
composable(
|
||||
"bioDetail/{bioId}",
|
||||
arguments = listOf(navArgument("bioId") {
|
||||
type = NavType.LongType
|
||||
})
|
||||
) {
|
||||
BioDetailsScreen(
|
||||
id = it.arguments?.getLong("bioId") ?: 0,
|
||||
onBackClick = { navController.navigateUp() },
|
||||
onEditClick = { id -> navController.navigate("editBio/${id}")}
|
||||
)
|
||||
}
|
||||
composable("addBio") {
|
||||
AddBiography()
|
||||
}
|
||||
composable(
|
||||
"editBio/{bioId}",
|
||||
arguments = listOf(navArgument("bioId") {
|
||||
type = NavType.LongType
|
||||
})
|
||||
){
|
||||
EditBiography(bioId = it.arguments?.getLong("bioId") ?: 0) { navController.navigateUp() }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,341 @@
|
|||
package com.menagerie.ophelia.view.biographies
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusDirection
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.menagerie.ophelia.R
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioDetailViewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioListViewModel
|
||||
import com.menagerie.ophelia.view.components.InputFieldState
|
||||
import com.menagerie.ophelia.view.components.fab.FABComponent
|
||||
import com.menagerie.ophelia.view.newUser.Tags
|
||||
|
||||
fun insertBioInDB(bio: Bio?, mBioListViewModel: BioListViewModel) {
|
||||
bio?.let {
|
||||
mBioListViewModel.upsert(it)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FinishBiography(
|
||||
bioId: Long,
|
||||
onGo: () -> Unit
|
||||
) {
|
||||
val mBioDetailViewModel = BioDetailViewModel(bioId)
|
||||
val bio = mBioDetailViewModel.bio.observeAsState().value
|
||||
|
||||
if (bio != null) {
|
||||
val inputViewModel = InputEditViewModel(bio)
|
||||
val ioBio: Bio by inputViewModel.bio.observeAsState(bio)
|
||||
AddEditBio(
|
||||
ioBio = ioBio,
|
||||
btnLabel = stringResource(id = R.string.finish),
|
||||
toast = stringResource(id = R.string.bio_finish_toast),
|
||||
onGo,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EditBiography(
|
||||
bioId: Long,
|
||||
onGo: () -> Unit
|
||||
) {
|
||||
val mBioDetailViewModel = BioDetailViewModel(bioId)
|
||||
val bio = mBioDetailViewModel.bio.observeAsState().value
|
||||
|
||||
if (bio != null) {
|
||||
val inputViewModel = InputEditViewModel(bio)
|
||||
val ioBio: Bio by inputViewModel.bio.observeAsState(bio)
|
||||
AddEditBio(
|
||||
ioBio = ioBio,
|
||||
btnLabel = stringResource(id = R.string.edit_bio),
|
||||
toast = stringResource(id = R.string.bio_edit_toast),
|
||||
onGo,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AddBiography() {
|
||||
|
||||
val inputViewModel = InputAddViewModel()
|
||||
val ioBio: Bio by inputViewModel.bio.observeAsState(Bio())
|
||||
AddEditBio(
|
||||
ioBio = ioBio,
|
||||
btnLabel = stringResource(id = R.string.edit_bio),
|
||||
toast = stringResource(id = R.string.bio_edit_toast),
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun AddEditBio(
|
||||
ioBio: Bio,
|
||||
btnLabel: String,
|
||||
toast: String,
|
||||
onGo: () -> Unit
|
||||
) {
|
||||
|
||||
val mBioListViewModel: BioListViewModel = viewModel(
|
||||
factory = BioListViewModel.BioListViewModelFactory()
|
||||
)
|
||||
val context = LocalContext.current
|
||||
|
||||
var name by remember { mutableStateOf(ioBio.name) }
|
||||
var sp by remember { mutableStateOf(ioBio.subjective) }
|
||||
var op by remember { mutableStateOf(ioBio.objective) }
|
||||
var pp by remember { mutableStateOf(ioBio.possessive) }
|
||||
var rp by remember { mutableStateOf(ioBio.reflexive) }
|
||||
var tags by remember { mutableIntStateOf(ioBio.tags) }
|
||||
|
||||
Scaffold(
|
||||
floatingActionButton = {
|
||||
FABComponent(text = btnLabel, onClick = {
|
||||
insertBioInDB(
|
||||
Bio(
|
||||
id = ioBio.id,
|
||||
name = name,
|
||||
subjective = sp,
|
||||
objective = op,
|
||||
possessive = pp,
|
||||
reflexive = rp,
|
||||
tags = tags,
|
||||
),
|
||||
mBioListViewModel
|
||||
)
|
||||
onGo()
|
||||
Toast.makeText(context, toast, Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
)
|
||||
{
|
||||
Column(
|
||||
modifier = Modifier.padding(12.dp)
|
||||
) {
|
||||
val modifier = Modifier
|
||||
.width(164.dp)
|
||||
.height(64.dp)
|
||||
val focusManager = LocalFocusManager.current
|
||||
InputFieldState(
|
||||
value = name,
|
||||
label = "name",
|
||||
modifier = modifier,
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.moveFocus(FocusDirection.Next) }
|
||||
)
|
||||
) { name = it }
|
||||
Box {
|
||||
Column {
|
||||
Row {
|
||||
InputFieldState(
|
||||
value = sp,
|
||||
label = "objective",
|
||||
modifier = modifier,
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.moveFocus(FocusDirection.Next) }
|
||||
)
|
||||
) { sp = it }
|
||||
Text(
|
||||
text = " / ",
|
||||
style = MaterialTheme.typography.displayMedium
|
||||
)
|
||||
InputFieldState(
|
||||
value = op,
|
||||
label = "subjective",
|
||||
modifier = modifier,
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.moveFocus(FocusDirection.Next) }
|
||||
)
|
||||
) { op = it }
|
||||
}
|
||||
Row {
|
||||
InputFieldState(
|
||||
value = pp,
|
||||
label = "possessive",
|
||||
modifier = modifier,
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.moveFocus(FocusDirection.Next) }
|
||||
)
|
||||
) { pp = it }
|
||||
Text(
|
||||
text = " / ",
|
||||
style = MaterialTheme.typography.displayMedium
|
||||
)
|
||||
InputFieldState(
|
||||
value = rp,
|
||||
label = "reflexive",
|
||||
modifier = modifier,
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.clearFocus() }
|
||||
)
|
||||
) { rp = it }
|
||||
}
|
||||
tagsBox(
|
||||
tags = tags,
|
||||
modifier = Modifier
|
||||
.padding(12.dp)
|
||||
.size(64.dp)
|
||||
) {
|
||||
tags = it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun tagsBox(
|
||||
tags: Int,
|
||||
modifier: Modifier,
|
||||
onValChange: (Int) -> Unit
|
||||
) {
|
||||
|
||||
Row {
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.TRANS,
|
||||
painter = painterResource(id = R.drawable.trans_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.FURRY,
|
||||
painter = painterResource(id = R.drawable.furry_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.ASEXUAL,
|
||||
painter = painterResource(id = R.drawable.asexual_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
}
|
||||
|
||||
|
||||
Row {
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.BDSM,
|
||||
painter = painterResource(id = R.drawable.bdsm_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.MONO,
|
||||
painter = painterResource(id = R.drawable.mono_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.ALCOHOL,
|
||||
painter = painterResource(id = R.drawable.liqour_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
}
|
||||
|
||||
Row {
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.WEED,
|
||||
painter = painterResource(id = R.drawable.weed_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.THERIAN,
|
||||
painter = painterResource(id = R.drawable.therian_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
|
||||
RememberableButton(
|
||||
tagList = tags,
|
||||
tag = Tags.PLURAL,
|
||||
painter = painterResource(id = R.drawable.plural_tag),
|
||||
modifier = modifier,
|
||||
onValChange = onValChange)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun RememberableButton(
|
||||
tagList: Int,
|
||||
tag: Tags,
|
||||
modifier: Modifier,
|
||||
painter: Painter,
|
||||
onValChange: (Int) -> Unit,
|
||||
) {
|
||||
var selected = tagList and tag.value == tag.value
|
||||
|
||||
Box {
|
||||
FilterChip(
|
||||
selected = selected,
|
||||
onClick = { onValChange(tagList xor tag.value) },
|
||||
modifier = modifier,
|
||||
shape = CircleShape,
|
||||
label = {
|
||||
Icon(
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
painter = painter,
|
||||
contentDescription = ""
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class InputEditViewModel(
|
||||
bio: Bio
|
||||
) : ViewModel() {
|
||||
private val _bio: MutableLiveData<Bio> = MutableLiveData(bio)
|
||||
val bio: LiveData<Bio> = _bio
|
||||
}
|
||||
|
||||
class InputAddViewModel() : ViewModel() {
|
||||
private val _bio: MutableLiveData<Bio> = MutableLiveData(Bio())
|
||||
val bio: LiveData<Bio> = _bio
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package com.menagerie.ophelia.view.biographies
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.menagerie.ophelia.R
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun BioCard(
|
||||
name: String,
|
||||
image: Int,
|
||||
onBioClick: () -> Unit,
|
||||
onDeleteClick: () -> Unit
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
Card(
|
||||
onClick = onBioClick,
|
||||
modifier = Modifier
|
||||
.padding(10.dp)
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight(),
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
elevation = CardDefaults.cardElevation(
|
||||
defaultElevation = 6.dp
|
||||
),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
),
|
||||
border = BorderStroke(1.dp, Color.Black),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.ic_app_logo),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(130.dp)
|
||||
.padding(8.dp),
|
||||
contentScale = ContentScale.Fit,
|
||||
)
|
||||
Column(modifier = Modifier.padding(8.dp)) {
|
||||
Text(
|
||||
text = name,
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxSize())
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.wrapContentSize(Alignment.TopStart)
|
||||
)
|
||||
{
|
||||
IconButton(
|
||||
onClick = { expanded = true }) {
|
||||
Icon(
|
||||
Icons.Default.MoreVert,
|
||||
contentDescription = ""
|
||||
)
|
||||
}
|
||||
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
|
||||
DropdownMenuItem(text = { Text(text = "Delete") }, onClick = onDeleteClick)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.menagerie.ophelia.view.biographies
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioListViewModel
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun BioCardList(
|
||||
bioList: List<Bio>,
|
||||
onBioClick: (Bio) -> Unit = {},
|
||||
) {
|
||||
val mBioListViewModel: BioListViewModel = viewModel(
|
||||
factory = BioListViewModel.BioListViewModelFactory()
|
||||
)
|
||||
|
||||
Box(modifier = Modifier.padding()) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
contentPadding = PaddingValues(8.dp)
|
||||
) {
|
||||
items(bioList) { bio ->
|
||||
BioCard(
|
||||
name = bio.name,
|
||||
image = bio.pfpRes,
|
||||
onBioClick = { onBioClick(bio) },
|
||||
onDeleteClick = { mBioListViewModel.delete(bio) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
package com.menagerie.ophelia.view.biographies
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.menagerie.ophelia.R
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioDetailViewModel
|
||||
import com.menagerie.ophelia.view.components.fab.FABComponent
|
||||
import com.menagerie.ophelia.view.components.utils.Dimens
|
||||
|
||||
data class BioDetailCallbacks(
|
||||
val onBackClick: () -> Unit,
|
||||
val onEditClick: (Long) -> Unit
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun BioDetailsScreen(
|
||||
id: Long,
|
||||
onBackClick: () -> Unit,
|
||||
onEditClick: (Long) -> Unit,
|
||||
) {
|
||||
val mBioDetailViewModel = BioDetailViewModel(id)
|
||||
|
||||
val bio = mBioDetailViewModel.bio.observeAsState().value
|
||||
|
||||
if (bio != null) {
|
||||
Surface {
|
||||
BioDetails(
|
||||
bio,
|
||||
BioDetailCallbacks(
|
||||
onBackClick = onBackClick,
|
||||
onEditClick = onEditClick,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BioDetails(
|
||||
bio: Bio,
|
||||
callbacks: BioDetailCallbacks,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Box(
|
||||
modifier
|
||||
.fillMaxSize()
|
||||
) {
|
||||
BioDetailContents(
|
||||
bio = bio,
|
||||
onEdit = callbacks.onEditClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BioDetailContents(
|
||||
bio: Bio,
|
||||
onEdit: (Long) -> Unit,
|
||||
) {
|
||||
Column {
|
||||
InfoDetails(
|
||||
bio = bio,
|
||||
onEdit = onEdit,
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun InfoDetails(
|
||||
bio: Bio,
|
||||
onEdit: (Long) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Scaffold(
|
||||
floatingActionButton = {
|
||||
FABComponent(
|
||||
text = "${stringResource(id = R.string.edit_bio)}",
|
||||
onClick = { onEdit(bio.id) }
|
||||
)
|
||||
}
|
||||
) {
|
||||
Column(modifier = modifier.padding(Dimens.PaddingLarge)) {
|
||||
Text(
|
||||
text = bio.name,
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = Dimens.PaddingSmall,
|
||||
end = Dimens.PaddingSmall,
|
||||
bottom = Dimens.PaddingNormal
|
||||
)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
Box(
|
||||
Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(
|
||||
start = Dimens.PaddingSmall,
|
||||
end = Dimens.PaddingSmall,
|
||||
bottom = Dimens.PaddingNormal
|
||||
)
|
||||
) {
|
||||
Text(text = "${bio.subjective} / ${bio.objective} / ${bio.possessive} / ${bio.reflexive}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.menagerie.ophelia.view.biographies
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun TagCard(
|
||||
name: String,
|
||||
painter: Painter,
|
||||
details: String,
|
||||
check: Boolean,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
var checked by remember { mutableStateOf(check) }
|
||||
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight(),
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
elevation = CardDefaults.cardElevation(
|
||||
defaultElevation = 6.dp
|
||||
),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor =
|
||||
if (checked) MaterialTheme.colorScheme.primaryContainer
|
||||
else MaterialTheme.colorScheme.surface
|
||||
),
|
||||
border = BorderStroke(1.dp, Color.Black),
|
||||
onClick = {
|
||||
checked = !checked
|
||||
onClick()
|
||||
},
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Image(
|
||||
painter = painter,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(80.dp)
|
||||
.padding(8.dp),
|
||||
contentScale = ContentScale.Fit,
|
||||
)
|
||||
Column(modifier = Modifier.padding(8.dp)) {
|
||||
Text(
|
||||
text = name,
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
//TODO: details blurbs
|
||||
// Text(
|
||||
// text = details,
|
||||
// style = MaterialTheme.typography.headlineSmall,
|
||||
// color = MaterialTheme.colorScheme.onSurface,
|
||||
// )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.menagerie.ophelia.view.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusDirection
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun InputFieldComponent(
|
||||
text: String,
|
||||
onChange: (String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
singleLine: Boolean = true,
|
||||
label: String = "Some val",
|
||||
keyboardActions: KeyboardActions = KeyboardActions.Default,
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = text,
|
||||
onValueChange = onChange,
|
||||
label = { Text(text = label)},
|
||||
modifier = modifier,
|
||||
singleLine = singleLine,
|
||||
keyboardActions = keyboardActions,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun InputFieldState(
|
||||
value: String,
|
||||
label: String,
|
||||
modifier: Modifier,
|
||||
keyboardActions: KeyboardActions = KeyboardActions.Default,
|
||||
onVal: (String) -> Unit,
|
||||
) {
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
) {
|
||||
InputField(value, label, modifier, onVal, keyboardActions)
|
||||
Spacer(modifier = Modifier.padding(10.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun InputField(
|
||||
text: String,
|
||||
label: String,
|
||||
modifier: Modifier,
|
||||
onValChange: ((String) -> Unit)?,
|
||||
keyboardActions: KeyboardActions,
|
||||
) {
|
||||
if (onValChange != null) {
|
||||
InputFieldComponent(
|
||||
text = text,
|
||||
onChange = onValChange,
|
||||
label = label,
|
||||
modifier = modifier,
|
||||
keyboardActions = keyboardActions,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.menagerie.ophelia.view.components.fab
|
||||
|
||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||
import androidx.compose.material3.FloatingActionButtonDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun FABComponent(
|
||||
text: String,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
ExtendedFloatingActionButton(
|
||||
onClick = onClick,
|
||||
elevation = FloatingActionButtonDefaults.elevation(8.dp)
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.menagerie.ophelia.view.components.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.menagerie.ophelia.R
|
||||
|
||||
|
||||
object Dimens {
|
||||
val PaddingSmall: Dp
|
||||
@Composable get() = dimensionResource(R.dimen.margin_small)
|
||||
|
||||
val PaddingNormal: Dp
|
||||
@Composable get() = dimensionResource(R.dimen.margin_normal)
|
||||
|
||||
val PaddingLarge: Dp = 24.dp
|
||||
|
||||
val PlantDetailAppBarHeight: Dp
|
||||
@Composable get() = dimensionResource(R.dimen.plant_detail_app_bar_height)
|
||||
|
||||
val ToolbarIconPadding = 12.dp
|
||||
|
||||
val ToolbarIconSize = 32.dp
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.menagerie.ophelia.view.components.utils
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.material3.Snackbar
|
||||
import androidx.compose.material3.SnackbarDuration
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun TextSnackbarContainer(
|
||||
snackbarText: String,
|
||||
showSnackbar: Boolean,
|
||||
onDismissSnackbar: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
snackbarHostState: SnackbarHostState = remember{ SnackbarHostState()},
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
Box(modifier) {
|
||||
content()
|
||||
|
||||
val onDismissState by rememberUpdatedState(onDismissSnackbar)
|
||||
LaunchedEffect(showSnackbar, snackbarText) {
|
||||
if (showSnackbar) {
|
||||
try {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = snackbarText,
|
||||
duration = SnackbarDuration.Short
|
||||
)
|
||||
} finally {
|
||||
onDismissState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MaterialTheme(shapes = Shapes()) {
|
||||
SnackbarHost(
|
||||
hostState = snackbarHostState,
|
||||
modifier = modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.systemBarsPadding()
|
||||
.padding(all = 8.dp),
|
||||
) {
|
||||
Snackbar(it)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.menagerie.ophelia.view.newUser
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioListViewModel
|
||||
import com.menagerie.ophelia.view.OpheliaFace
|
||||
import com.menagerie.ophelia.view.OpheliaWhatsYourName
|
||||
import com.menagerie.ophelia.view.biographies.insertBioInDB
|
||||
import com.menagerie.ophelia.view.components.InputFieldState
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun AddNameScreen(
|
||||
onGo: () -> Unit,
|
||||
) {
|
||||
val inputViewModel = BioListViewModel.InputBioViewModel()
|
||||
val mBioListViewModel: BioListViewModel = viewModel(
|
||||
factory = BioListViewModel.BioListViewModelFactory()
|
||||
)
|
||||
Scaffold {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
val bio: Bio by inputViewModel.bio.observeAsState(Bio())
|
||||
|
||||
OpheliaFace(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(top = 12.dp)
|
||||
)
|
||||
LinearProgressIndicator(
|
||||
progress = 0f,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
OpheliaWhatsYourName(modifier = Modifier)
|
||||
InputFieldState(
|
||||
value = bio.name,
|
||||
label = "name",
|
||||
modifier = Modifier
|
||||
.width(120.dp)
|
||||
) { inputViewModel.onNameChange(it) }
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.weight(1f)
|
||||
|
||||
)
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.align(Alignment.End),
|
||||
onClick = {
|
||||
insertBioInDB(inputViewModel.bio.value, mBioListViewModel)
|
||||
onGo()
|
||||
}
|
||||
) {
|
||||
Text(text = "Continue")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
package com.menagerie.ophelia.view.newUser
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusDirection
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioDetailViewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioListViewModel
|
||||
import com.menagerie.ophelia.view.OpheliaFace
|
||||
import com.menagerie.ophelia.view.OpheliaPronounsIntroduction
|
||||
import com.menagerie.ophelia.view.components.InputField
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun AddPronounsScreen(
|
||||
onGo : () -> Unit
|
||||
) {
|
||||
val mBioDetailViewModel = BioDetailViewModel(1)
|
||||
val mBioListViewModel: BioListViewModel = viewModel(
|
||||
factory = BioListViewModel.BioListViewModelFactory()
|
||||
)
|
||||
|
||||
val bio = mBioDetailViewModel.bio.observeAsState().value
|
||||
|
||||
Scaffold {
|
||||
if (bio != null) {
|
||||
Column {
|
||||
OpheliaFace(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(top = 12.dp)
|
||||
)
|
||||
LinearProgressIndicator(
|
||||
progress = .33f,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
OpheliaPronounsIntroduction(modifier = Modifier.weight(1f), name = bio.name)
|
||||
PronounBox(Modifier.weight(1f)) {
|
||||
val updateBio = Bio(
|
||||
id = bio.id,
|
||||
name = bio.name,
|
||||
subjective = it[0],
|
||||
objective = it[1],
|
||||
possessive = it[2],
|
||||
reflexive = it[3],
|
||||
)
|
||||
mBioListViewModel.upsert(updateBio)
|
||||
onGo()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PronounBox(
|
||||
modifier: Modifier,
|
||||
onClick: (List<String>) -> Unit,
|
||||
) {
|
||||
var subject by remember { mutableStateOf("") }
|
||||
var objec by remember { mutableStateOf("") }
|
||||
var possess by remember { mutableStateOf("") }
|
||||
var reflex by remember { mutableStateOf("") }
|
||||
|
||||
|
||||
Box(modifier = Modifier.fillMaxWidth())
|
||||
{
|
||||
Column {
|
||||
val focusManager = LocalFocusManager.current
|
||||
Row {
|
||||
InputField(
|
||||
text = subject,
|
||||
label = "subjective",
|
||||
modifier = modifier,
|
||||
onValChange = { subject = it },
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.moveFocus(FocusDirection.Next) }
|
||||
),
|
||||
)
|
||||
Text(
|
||||
text = " / ",
|
||||
style = MaterialTheme.typography.displayMedium
|
||||
)
|
||||
InputField(
|
||||
text = objec,
|
||||
label = "objective",
|
||||
modifier = modifier,
|
||||
onValChange = { objec = it },
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.moveFocus(FocusDirection.Next) }
|
||||
),
|
||||
)
|
||||
}
|
||||
Row {
|
||||
InputField(
|
||||
text = possess,
|
||||
label = "possessive",
|
||||
modifier = modifier,
|
||||
onValChange = { possess = it },
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.moveFocus(FocusDirection.Next) }
|
||||
),
|
||||
)
|
||||
Text(
|
||||
text = " / ",
|
||||
style = MaterialTheme.typography.displayMedium
|
||||
)
|
||||
InputField(
|
||||
text = reflex,
|
||||
label = "reflexive",
|
||||
modifier = modifier,
|
||||
onValChange = { reflex = it },
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { focusManager.clearFocus() }
|
||||
),
|
||||
)
|
||||
}
|
||||
Spacer(
|
||||
modifier = Modifier.size(60.dp)
|
||||
)
|
||||
Button(
|
||||
onClick = {
|
||||
onClick(listOf(subject, objec, possess, reflex))
|
||||
},
|
||||
modifier = Modifier
|
||||
.align(
|
||||
alignment = Alignment.End
|
||||
)
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Text(text = "Continue")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
package com.menagerie.ophelia.view.newUser
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.menagerie.ophelia.R
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioDetailViewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioListViewModel
|
||||
import com.menagerie.ophelia.view.OpheliaFace
|
||||
import com.menagerie.ophelia.view.OpheliaTagsIntroduction
|
||||
import com.menagerie.ophelia.view.biographies.TagCard
|
||||
|
||||
enum class Tags(val value: Int)
|
||||
{
|
||||
TRANS(1),
|
||||
FURRY(2),
|
||||
ASEXUAL(4),
|
||||
BDSM(8),
|
||||
MONO(16),
|
||||
ALCOHOL(32),
|
||||
WEED(64),
|
||||
THERIAN(128),
|
||||
PLURAL(256),
|
||||
}
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun AddTagsScreen(
|
||||
onGo : () -> Unit
|
||||
) {
|
||||
Scaffold {
|
||||
Column {
|
||||
OpheliaFace(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(top = 12.dp)
|
||||
)
|
||||
LinearProgressIndicator(
|
||||
progress = .66f,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
OpheliaTagsIntroduction(modifier = Modifier.weight(1f))
|
||||
MakeDefaultTagCards(modifier = Modifier.weight(2f))
|
||||
Button(
|
||||
onClick = onGo,
|
||||
modifier = Modifier
|
||||
.weight(.25f)
|
||||
.align(Alignment.End)) {
|
||||
Text(text = "Continue")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MakeDefaultTagCards(
|
||||
modifier: Modifier,
|
||||
) {
|
||||
var flags by remember { mutableIntStateOf(0) }
|
||||
|
||||
val mBioDetailViewModel = BioDetailViewModel(1)
|
||||
val mBioListViewModel: BioListViewModel = viewModel(
|
||||
factory = BioListViewModel.BioListViewModelFactory()
|
||||
)
|
||||
|
||||
val bio = mBioDetailViewModel.bio.observeAsState().value
|
||||
|
||||
if (bio != null) {
|
||||
val updateBio = Bio(
|
||||
id = bio.id,
|
||||
name = bio.name,
|
||||
subjective = bio.subjective,
|
||||
objective = bio.objective,
|
||||
possessive = bio.possessive,
|
||||
reflexive = bio.reflexive,
|
||||
tags = flags
|
||||
)
|
||||
mBioListViewModel.upsert(updateBio)
|
||||
|
||||
Box(modifier = modifier) {
|
||||
LazyColumn {
|
||||
item {
|
||||
TagCard(
|
||||
name = "Transgender",
|
||||
painter = painterResource(id = R.drawable.trans_tag),
|
||||
details = "",
|
||||
check = flags and Tags.TRANS.value == Tags.TRANS.value
|
||||
) {
|
||||
flags = flags xor Tags.TRANS.value
|
||||
}
|
||||
}
|
||||
item {
|
||||
TagCard(
|
||||
name = "Furry",
|
||||
painter = painterResource(id = R.drawable.furry_tag),
|
||||
details = "",
|
||||
check = flags and Tags.FURRY.value == Tags.FURRY.value
|
||||
) {
|
||||
flags = flags xor Tags.FURRY.value
|
||||
}
|
||||
}
|
||||
item {
|
||||
TagCard(
|
||||
name = "Therian",
|
||||
painter = painterResource(id = R.drawable.therian_tag),
|
||||
details = "",
|
||||
check = flags and Tags.THERIAN.value == Tags.THERIAN.value
|
||||
) {
|
||||
flags = flags xor Tags.THERIAN.value
|
||||
}
|
||||
}
|
||||
item {
|
||||
TagCard(
|
||||
name = "Monogamous",
|
||||
painter = painterResource(id = R.drawable.mono_tag),
|
||||
details = "",
|
||||
check = flags and Tags.MONO.value == Tags.MONO.value
|
||||
) {
|
||||
flags = flags xor Tags.MONO.value
|
||||
}
|
||||
}
|
||||
item {
|
||||
TagCard(
|
||||
name = "BDSM",
|
||||
painter = painterResource(id = R.drawable.bdsm_tag),
|
||||
details = "",
|
||||
check = flags and Tags.BDSM.value == Tags.BDSM.value
|
||||
) {
|
||||
flags = flags xor Tags.BDSM.value
|
||||
}
|
||||
}
|
||||
item {
|
||||
TagCard(
|
||||
name = "Plural",
|
||||
painter = painterResource(id = R.drawable.plural_tag),
|
||||
details = "",
|
||||
check = flags and Tags.PLURAL.value == Tags.PLURAL.value
|
||||
) {
|
||||
flags = flags xor Tags.PLURAL.value
|
||||
}
|
||||
}
|
||||
item {
|
||||
TagCard(
|
||||
name = "Asexual",
|
||||
painter = painterResource(id = R.drawable.asexual_tag),
|
||||
details = "",
|
||||
check = flags and Tags.ASEXUAL.value == Tags.ASEXUAL.value
|
||||
) {
|
||||
flags = flags xor Tags.ASEXUAL.value
|
||||
}
|
||||
}
|
||||
item {
|
||||
TagCard(
|
||||
name = "Alcohol",
|
||||
painter = painterResource(id = R.drawable.liqour_tag),
|
||||
details = "",
|
||||
check = flags and Tags.ALCOHOL.value == Tags.ALCOHOL.value
|
||||
) {
|
||||
flags = flags xor Tags.ALCOHOL.value
|
||||
}
|
||||
}
|
||||
item {
|
||||
TagCard(
|
||||
name = "Weed",
|
||||
painter = painterResource(id = R.drawable.weed_tag),
|
||||
details = "",
|
||||
check = flags and Tags.WEED.value == Tags.WEED.value
|
||||
) {
|
||||
flags = flags xor Tags.WEED.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.menagerie.ophelia.view.newUser
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.menagerie.ophelia.view.OpheliaFace
|
||||
import com.menagerie.ophelia.view.OpheliaNewUserFinalCheck
|
||||
import com.menagerie.ophelia.view.biographies.FinishBiography
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun ConfirmBio(
|
||||
onGo: () -> Unit
|
||||
) {
|
||||
Scaffold {
|
||||
Column {
|
||||
OpheliaFace(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(top = 12.dp)
|
||||
)
|
||||
LinearProgressIndicator(
|
||||
progress = 1f,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
OpheliaNewUserFinalCheck(modifier = Modifier)
|
||||
FinishBiography(
|
||||
bioId = 1,
|
||||
onGo = onGo,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.menagerie.ophelia.view.polycule
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.menagerie.ophelia.view.OpheliaFace
|
||||
import com.menagerie.ophelia.view.OpheliaNewUserPolycule
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun AddPolyculeScreen(
|
||||
) {
|
||||
Scaffold {
|
||||
Column {
|
||||
OpheliaFace(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(top = 12.dp)
|
||||
)
|
||||
OpheliaNewUserPolycule(modifier = Modifier)
|
||||
//TODO : Polycules
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.menagerie.ophelia.view.polycule
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioListViewModel
|
||||
import com.menagerie.ophelia.view.biographies.BioCardList
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun PolyculeHomeView(
|
||||
modifier: Modifier = Modifier,
|
||||
onBioClick: (Bio) -> Unit = {},
|
||||
onAddClick: () -> Unit,
|
||||
) {
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
PolyculeTopAppBar(
|
||||
onFilterClick = { },
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
}
|
||||
) {
|
||||
PolyculeHomeScreen(
|
||||
onBioClick = onBioClick,
|
||||
onAddClick = onAddClick,
|
||||
modifier = modifier.padding(it)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PolyculeHomeScreen(
|
||||
onBioClick: (Bio) -> Unit,
|
||||
onAddClick: () -> Unit = {},
|
||||
modifier: Modifier,
|
||||
) {
|
||||
val mBioListViewModel: BioListViewModel = viewModel(
|
||||
factory = BioListViewModel.BioListViewModelFactory()
|
||||
)
|
||||
val items = mBioListViewModel.allBios.observeAsState(listOf()).value
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
) {
|
||||
BioCardList(bioList = items, onBioClick = onBioClick)
|
||||
FloatingActionButton(
|
||||
onClick = onAddClick
|
||||
) {
|
||||
Icon(Icons.Filled.Add, "Add Bio")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun PolyculeTopAppBar(
|
||||
onFilterClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
scrollBehavior: TopAppBarScrollBehavior,
|
||||
) {
|
||||
TopAppBar(
|
||||
title = {
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
}
|
||||
},
|
||||
modifier = modifier.statusBarsPadding(),
|
||||
actions = {},
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.menagerie.ophelia.view.splash
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.menagerie.ophelia.MainActivity
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@SuppressLint("CustomSplashScreen")
|
||||
class SplashActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
val splashScreen = installSplashScreen()
|
||||
splashScreen.setKeepOnScreenCondition { true }
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
//TODO : Figure out how to update this properly
|
||||
lifecycleScope.launchWhenCreated {
|
||||
delay(1500)
|
||||
|
||||
val intent = Intent(
|
||||
this@SplashActivity,
|
||||
MainActivity::class.java
|
||||
)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
|
||||
}
|
||||
}
|
||||
}
|
5
app/src/main/res/drawable/asexual_tag.xml
Normal file
5
app/src/main/res/drawable/asexual_tag.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15.73,3H8.27L3,8.27v7.46L8.27,21h7.46L21,15.73V8.27L15.73,3zM17,15.74L15.74,17 12,13.26 8.26,17 7,15.74 10.74,12 7,8.26 8.26,7 12,10.74 15.74,7 17,8.26 13.26,12 17,15.74z"/>
|
||||
</vector>
|
7
app/src/main/res/drawable/bdsm_tag.xml
Normal file
7
app/src/main/res/drawable/bdsm_tag.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M10.1,15.9l1.42,-1.42C8.79,12.05 7,10.41 7,8.85C7,7.8 7.8,7 8.85,7c1.11,0 1.54,0.65 2.68,2h0.93c1.12,-1.31 1.53,-2 2.68,-2c0.87,0 1.55,0.54 1.77,1.32c0.35,-0.04 0.68,-0.06 1,-0.06c0.36,0 0.7,0.03 1.03,0.08C18.7,6.43 17.13,5 15.15,5c-0.12,0 -0.23,0.03 -0.35,0.04C14.92,4.71 15,4.37 15,4c0,-1.66 -1.34,-3 -3,-3S9,2.34 9,4c0,0.37 0.08,0.71 0.2,1.04C9.08,5.03 8.97,5 8.85,5C6.69,5 5,6.69 5,8.85C5,11.27 7.04,13.16 10.1,15.9z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M22.5,16.24c-0.32,-0.18 -0.66,-0.29 -1,-0.35c0.07,-0.1 0.15,-0.18 0.21,-0.28c1.08,-1.87 0.46,-4.18 -1.41,-5.26c-2.09,-1.21 -4.76,-0.39 -8.65,0.9l0.52,1.94c3.47,-1.14 5.79,-1.88 7.14,-1.1c0.91,0.53 1.2,1.61 0.68,2.53c-0.56,0.96 -1.33,1 -3.07,1.32l-0.47,0.81c0.58,1.62 0.97,2.33 0.39,3.32c-0.53,0.91 -1.61,1.2 -2.53,0.68c-0.06,-0.03 -0.11,-0.09 -0.17,-0.13c-0.3,0.67 -0.64,1.24 -1.03,1.73c0.07,0.04 0.13,0.09 0.2,0.14c1.87,1.08 4.18,0.46 5.26,-1.41c0.06,-0.1 0.09,-0.21 0.14,-0.32c0.22,0.27 0.48,0.51 0.8,0.69c1.43,0.83 3.27,0.34 4.1,-1.1S23.93,17.06 22.5,16.24z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12.32,14.01c-0.74,3.58 -1.27,5.95 -2.62,6.73c-0.91,0.53 -2,0.24 -2.53,-0.68c-0.56,-0.96 -0.2,-1.66 0.39,-3.32L7.1,15.93c-1.7,-0.31 -2.5,-0.33 -3.07,-1.32c-0.53,-0.91 -0.24,-2 0.68,-2.53c0.09,-0.05 0.19,-0.08 0.29,-0.11c-0.35,-0.56 -0.64,-1.17 -0.82,-1.85c-0.16,0.07 -0.32,0.14 -0.48,0.23c-1.87,1.08 -2.49,3.39 -1.41,5.26c0.06,0.1 0.14,0.18 0.21,0.28c-0.34,0.06 -0.68,0.17 -1,0.35c-1.43,0.83 -1.93,2.66 -1.1,4.1s2.66,1.93 4.1,1.1c0.32,-0.18 0.58,-0.42 0.8,-0.69c0.05,0.11 0.08,0.22 0.14,0.32c1.08,1.87 3.39,2.49 5.26,1.41c2.09,-1.21 2.71,-3.93 3.55,-7.94L12.32,14.01z"/>
|
||||
</vector>
|
11
app/src/main/res/drawable/bg_splash.xml
Normal file
11
app/src/main/res/drawable/bg_splash.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<color android:color="@color/purple_200"/>
|
||||
</item>
|
||||
<item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@drawable/ic_app_logo"/>
|
||||
</item>
|
||||
</layer-list>
|
13
app/src/main/res/drawable/bg_splash_12.xml
Normal file
13
app/src/main/res/drawable/bg_splash_12.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<color android:color="@color/purple_200"/>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:width="140dp"
|
||||
android:height="180dp"
|
||||
android:drawable="@drawable/ic_app_logo"
|
||||
android:gravity="center" />
|
||||
</layer-list>
|
9
app/src/main/res/drawable/furry_tag.xml
Normal file
9
app/src/main/res/drawable/furry_tag.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M4.5,9.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M9,5.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15,5.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M19.5,9.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M17.34,14.86c-0.87,-1.02 -1.6,-1.89 -2.48,-2.91 -0.46,-0.54 -1.05,-1.08 -1.75,-1.32 -0.11,-0.04 -0.22,-0.07 -0.33,-0.09 -0.25,-0.04 -0.52,-0.04 -0.78,-0.04s-0.53,0 -0.79,0.05c-0.11,0.02 -0.22,0.05 -0.33,0.09 -0.7,0.24 -1.28,0.78 -1.75,1.32 -0.87,1.02 -1.6,1.89 -2.48,2.91 -1.31,1.31 -2.92,2.76 -2.62,4.79 0.29,1.02 1.02,2.03 2.33,2.32 0.73,0.15 3.06,-0.44 5.54,-0.44h0.18c2.48,0 4.81,0.58 5.54,0.44 1.31,-0.29 2.04,-1.31 2.33,-2.32 0.31,-2.04 -1.3,-3.49 -2.61,-4.8z"/>
|
||||
</vector>
|
BIN
app/src/main/res/drawable/ic_app_logo.png
Normal file
BIN
app/src/main/res/drawable/ic_app_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 MiB |
|
@ -1,170 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
|
@ -1,30 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
6
app/src/main/res/drawable/liqour_tag.xml
Normal file
6
app/src/main/res/drawable/liqour_tag.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M3,14c0,1.3 0.84,2.4 2,2.82V20H3v2h6v-2H7v-3.18C8.16,16.4 9,15.3 9,14V6H3V14zM5,8h2v3H5V8z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M20.63,8.54l-0.95,-0.32C19.28,8.09 19,7.71 19,7.28V3c0,-0.55 -0.45,-1 -1,-1h-3c-0.55,0 -1,0.45 -1,1v4.28c0,0.43 -0.28,0.81 -0.68,0.95l-0.95,0.32C11.55,8.82 11,9.58 11,10.44V20c0,1.1 0.9,2 2,2h7c1.1,0 2,-0.9 2,-2v-9.56C22,9.58 21.45,8.82 20.63,8.54zM16,4h1v1h-1V4zM13,10.44l0.95,-0.32C15.18,9.72 16,8.57 16,7.28V7h1v0.28c0,1.29 0.82,2.44 2.05,2.85L20,10.44V12h-7V10.44zM20,20h-7v-2h7V20z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/mono_tag.xml
Normal file
5
app/src/main/res/drawable/mono_tag.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M20,12c0,-1.1 -0.9,-2 -2,-2V7c0,-1.1 -0.9,-2 -2,-2H8C6.9,5 6,5.9 6,7v3c-1.1,0 -2,0.9 -2,2v5h1.33L6,19h1l0.67,-2h8.67L17,19h1l0.67,-2H20V12zM16,10h-3V7h3V10zM8,7h3v3H8V7zM6,12h12v3H6V12z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/ophelia_background.xml
Normal file
10
app/src/main/res/drawable/ophelia_background.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#7dae7d"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
</vector>
|
5
app/src/main/res/drawable/ophelia_foreground.xml
Normal file
5
app/src/main/res/drawable/ophelia_foreground.xml
Normal file
File diff suppressed because one or more lines are too long
9
app/src/main/res/drawable/plural_tag.xml
Normal file
9
app/src/main/res/drawable/plural_tag.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M22,9l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0l0,-2z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M8,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4S4,5.79 4,8S5.79,12 8,12z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M8,13c-2.67,0 -8,1.34 -8,4v3h16v-3C16,14.34 10.67,13 8,13z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12.51,4.05C13.43,5.11 14,6.49 14,8s-0.57,2.89 -1.49,3.95C14.47,11.7 16,10.04 16,8S14.47,4.3 12.51,4.05z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M16.53,13.83C17.42,14.66 18,15.7 18,17v3h2v-3C20,15.55 18.41,14.49 16.53,13.83z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/therian_tag.xml
Normal file
5
app/src/main/res/drawable/therian_tag.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,7.77L18.39,18H5.61L12,7.77M12,4L2,20h20L12,4z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/trans_tag.xml
Normal file
5
app/src/main/res/drawable/trans_tag.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,8c1.93,0 3.5,1.57 3.5,3.5S13.93,15 12,15s-3.5,-1.57 -3.5,-3.5S10.07,8 12,8zM16.53,8.38l3.97,-3.96V7h2V1h-6v2h2.58l-3.97,3.97C14.23,6.36 13.16,6 12,6c-1.16,0 -2.23,0.36 -3.11,0.97L8.24,6.32l1.41,-1.41L8.24,3.49L6.82,4.9L4.92,3H7.5V1h-6v6h2V4.42l1.91,1.9L3.99,7.74l1.41,1.41l1.41,-1.41l0.65,0.65C6.86,9.27 6.5,10.34 6.5,11.5c0,2.7 1.94,4.94 4.5,5.41L11,19H9v2h2v2h2v-2h2v-2h-2l0,-2.09c2.56,-0.47 4.5,-2.71 4.5,-5.41C17.5,10.34 17.14,9.27 16.53,8.38z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/weed_tag.xml
Normal file
5
app/src/main/res/drawable/weed_tag.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,20H2v-2h5.75l0,0C7.02,15.19 4.81,12.99 2,12.26C2.64,12.1 3.31,12 4,12C8.42,12 12,15.58 12,20zM22,12.26C21.36,12.1 20.69,12 20,12c-2.93,0 -5.48,1.58 -6.88,3.93c0.29,0.66 0.53,1.35 0.67,2.07c0.13,0.65 0.2,1.32 0.2,2h2h6v-2h-5.75C16.98,15.19 19.19,12.99 22,12.26zM15.64,11.02c0.78,-2.09 2.23,-3.84 4.09,-5C15.44,6.16 12,9.67 12,14c0,0.01 0,0.02 0,0.02C12.95,12.75 14.2,11.72 15.64,11.02zM11.42,8.85C10.58,6.66 8.88,4.89 6.7,4C8.14,5.86 9,8.18 9,10.71c0,0.21 -0.03,0.41 -0.04,0.61c0.43,0.24 0.83,0.52 1.22,0.82C10.39,10.96 10.83,9.85 11.42,8.85z"/>
|
||||
</vector>
|
7
app/src/main/res/font/alex_brush.xml
Normal file
7
app/src/main/res/font/alex_brush.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
||||
app:fontProviderPackage="com.google.android.gms"
|
||||
app:fontProviderQuery="Alex Brush"
|
||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
||||
</font-family>
|
BIN
app/src/main/res/font/allura.ttf
Normal file
BIN
app/src/main/res/font/allura.ttf
Normal file
Binary file not shown.
7
app/src/main/res/font/calligraffitti.xml
Normal file
7
app/src/main/res/font/calligraffitti.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
||||
app:fontProviderPackage="com.google.android.gms"
|
||||
app:fontProviderQuery="Calligraffitti"
|
||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
||||
</font-family>
|
7
app/src/main/res/font/mentho.xml
Normal file
7
app/src/main/res/font/mentho.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<font
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="400"
|
||||
android:font="@font/alex_brush"/>
|
||||
</font-family>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<background android:drawable="@drawable/ophelia_background" />
|
||||
<foreground android:drawable="@drawable/ophelia_foreground" />
|
||||
<monochrome android:drawable="@drawable/ophelia_foreground" />
|
||||
</adaptive-icon>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<background android:drawable="@drawable/ophelia_background" />
|
||||
<foreground android:drawable="@drawable/ophelia_foreground" />
|
||||
<monochrome android:drawable="@drawable/ophelia_foreground" />
|
||||
</adaptive-icon>
|
6
app/src/main/res/navigation/nav_graph.xml
Normal file
6
app/src/main/res/navigation/nav_graph.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/nav_graph">
|
||||
|
||||
</navigation>
|
10
app/src/main/res/values-v31/themes.xml
Normal file
10
app/src/main/res/values-v31/themes.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.Ophelia" parent="android:ThemeOverlay.Material.Dark.ActionBar" />
|
||||
<style name="SplashScreenTheme" parent="Theme.Ophelia">
|
||||
<item name="windowSplashScreenBackground">@color/purple_200</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/bg_splash_12</item>
|
||||
<item name="windowSplashScreenAnimationDuration">800</item>
|
||||
<item name="postSplashScreenTheme">@style/Theme.Ophelia</item>
|
||||
</style>
|
||||
</resources>
|
37
app/src/main/res/values/dimens.xml
Normal file
37
app/src/main/res/values/dimens.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- Per Material Design specs: -->
|
||||
<!-- https://material.io/design/components/buttons-floating-action-button.html#specs -->
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
|
||||
<!-- Padding on the bottom of a screen so that the FAB won't overlap scrolled text. -->
|
||||
<dimen name="fab_bottom_padding">72dp</dimen>
|
||||
|
||||
<dimen name="plant_detail_app_bar_height">278dp</dimen>
|
||||
|
||||
<dimen name="margin_normal">16dp</dimen>
|
||||
<dimen name="margin_small">8dp</dimen>
|
||||
<dimen name="margin_extra_small">4dp</dimen>
|
||||
|
||||
<dimen name="padding_large">48dp</dimen>
|
||||
|
||||
<dimen name="plant_item_image_height">95dp</dimen>
|
||||
|
||||
<dimen name="card_side_margin">12dp</dimen>
|
||||
<dimen name="card_bottom_margin">26dp</dimen>
|
||||
<dimen name="card_elevation">2dp</dimen>
|
||||
<dimen name="card_corner_radius">12dp</dimen>
|
||||
|
||||
<!-- elevation for Plant Detail toolbar - used to convert to pixels when hiding/showing -->
|
||||
<dimen name="toolbar_elevation">5dp</dimen>
|
||||
|
||||
<!-- Plant List Header margin -->
|
||||
<dimen name="header_margin">24dp</dimen>
|
||||
|
||||
<dimen name="gallery_header_margin">72dp</dimen>
|
||||
|
||||
<!-- minimum height of plant detail page so that the collapsing toolbar can be shown on every page -->
|
||||
<dimen name="plant_description_min_height">555dp</dimen>
|
||||
|
||||
</resources>
|
17
app/src/main/res/values/font_certs.xml
Normal file
17
app/src/main/res/values/font_certs.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<array name="com_google_android_gms_fonts_certs">
|
||||
<item>@array/com_google_android_gms_fonts_certs_dev</item>
|
||||
<item>@array/com_google_android_gms_fonts_certs_prod</item>
|
||||
</array>
|
||||
<string-array name="com_google_android_gms_fonts_certs_dev">
|
||||
<item>
|
||||
MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
|
||||
</item>
|
||||
</string-array>
|
||||
<string-array name="com_google_android_gms_fonts_certs_prod">
|
||||
<item>
|
||||
MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
|
||||
</item>
|
||||
</string-array>
|
||||
</resources>
|
7
app/src/main/res/values/preloaded_fonts.xml
Normal file
7
app/src/main/res/values/preloaded_fonts.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<array name="preloaded_fonts" translatable="false">
|
||||
<item>@font/alex_brush</item>
|
||||
<item>@font/calligraffitti</item>
|
||||
</array>
|
||||
</resources>
|
|
@ -1,3 +1,68 @@
|
|||
<resources>
|
||||
##App Main
|
||||
<string name="app_name">Ophelia</string>
|
||||
<string name="app_tag">A Polycule Pocket-dex</string>
|
||||
<string name="welcome">Get Started</string>
|
||||
<string name="welcome_back">Welcome Back</string>
|
||||
|
||||
##Routes
|
||||
<string name="route_polyculeHome">polyculeHome</string>
|
||||
<string name="route_home">home</string>
|
||||
|
||||
##Bio
|
||||
<string name="add_bio">Add Bio</string>
|
||||
<string name="edit_bio">Edit Bio</string>
|
||||
<string name="finish">Finish</string>
|
||||
<string name="bio_load">Bio Loaded</string>
|
||||
<string name="open_context_menu">Open context menu</string>
|
||||
<string name="name">Name</string>
|
||||
<string name="bio_add_toast">New Bio Added!</string>
|
||||
<string name="bio_edit_toast">Bio Edited!</string>
|
||||
<string name="bio_finish_toast">Welcome Aboard!</string>
|
||||
|
||||
|
||||
##Tags
|
||||
<string name="mono">Monogamous</string>
|
||||
<string name="plural">Plural</string>
|
||||
<string name="furry">Furry</string>
|
||||
<string name="therian">Therian</string>
|
||||
<string name="bdsm">BDSM</string>
|
||||
<string name="alcohol">Alcohol</string>
|
||||
<string name="weed">Weed</string>
|
||||
<string name="asexual">Asexual</string>
|
||||
<string name="trans">Transgender</string>
|
||||
|
||||
##Ophelia
|
||||
<string name = "ophelia_says">Ophelia Says</string>
|
||||
<string name = "final_check_in">What do you think; looks like you?</string>
|
||||
<string-array name="welcome_blurb">
|
||||
<item>Hi!</item>
|
||||
<item>I\'m Ophelia, a Polycule companion system designed to help you keep track of your metas, reference a charter, and find things in common with your polycule.</item>
|
||||
<item>I\'m meant to work dynamically with how polyamory works for you, so what all those words mean will be something we work out together later.</item>
|
||||
<item>First, I need to get to know "you".</item>
|
||||
<item>Click Go to get started.</item>
|
||||
</string-array>
|
||||
<string-array name="whats_your_name">
|
||||
<item>I\'m Ophelia, what\'s your name\?</item>
|
||||
<item>Your Name is how you\'ll be addressed in the app, and is the primary way you\'ll be referred to in polycules.</item>
|
||||
<item>But don\'t worry; your name, like everything about you, can be changed at any time!</item>
|
||||
</string-array>
|
||||
<string name="introduction_with_name">"Nice to meet you,%1$s!</string>
|
||||
<string-array name="introduction_to_pronouns">
|
||||
<item>Personal Pronouns are words used to refer to a person without always using their name.</item>
|
||||
<item>Since Pronouns are a personal choice, I want to leave them as open as possible for you!</item>
|
||||
<item>We\'re dealing with four Personal Pronouns, and using mine as an example: She (subjective) / Her (objective) / Hers (possessive) / Herself (reflexive)</item>
|
||||
<item>Your Pronouns will be used when referring to you in specific contexts, and are displayed alongside your name in most contexts.</item>
|
||||
</string-array>
|
||||
<string-array name="introduction_to_tags">
|
||||
<item>Tags are a way to highlight important things about yourself.</item>
|
||||
<item>They also lead to more detailed parts of you bio, where you can flesh out specific parts of your bio.</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="introduction_to_polycules">
|
||||
<item>Great!</item>
|
||||
<item>Now, there\'s just one more thing! We need to create a polycule for you. A "polycule" for our purposes is defined as a group of people with a shared relationship process.</item>
|
||||
<item>A person may be in a polycule with any number of people, including just themselves, and in any number of polycules.</item>
|
||||
<item>All we need to get started is a name:</item>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -1,5 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Theme.Ophelia" parent="android:Theme.Material.Light.NoActionBar" />
|
||||
<style name="SplashScreenTheme" parent="Theme.Ophelia">
|
||||
<item name="android:windowBackground">@drawable/bg_splash</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -1,5 +1,6 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id 'com.android.application' version '8.1.2' apply false
|
||||
id 'com.android.application' version '8.1.3' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
|
||||
id 'com.google.devtools.ksp' version '1.8.10-1.0.9' apply false
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue