clean_up #5
22 changed files with 62 additions and 99 deletions
|
@ -8,6 +8,6 @@ class PolyculeApplication : Application() {
|
|||
|
||||
private val applicationScope = CoroutineScope(SupervisorJob())
|
||||
|
||||
val database by lazy { PolyculeDatabase.getDatabase(this, applicationScope)}
|
||||
val repository by lazy { PolyculeRepository(database.bioDao())}
|
||||
val database by lazy { PolyculeDatabase.getDatabase(this, applicationScope) }
|
||||
val repository by lazy { PolyculeRepository(database.bioDao()) }
|
||||
}
|
|
@ -6,11 +6,9 @@ import androidx.room.Database
|
|||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.menagerie.ophelia.R
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.BioDao
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.count
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
|
@ -72,7 +70,6 @@ abstract class PolyculeDatabase : RoomDatabase() {
|
|||
var bio = Bio(
|
||||
name = "Azea",
|
||||
description = init,
|
||||
pfpRes = R.drawable.ic_app_logo
|
||||
)
|
||||
bioDao.insert(bio)
|
||||
|
||||
|
@ -85,7 +82,6 @@ abstract class PolyculeDatabase : RoomDatabase() {
|
|||
bio = Bio(
|
||||
name = "Darkwood Mill",
|
||||
description = init,
|
||||
pfpRes = R.drawable.ic_app_logo
|
||||
)
|
||||
bioDao.insert(bio)
|
||||
|
||||
|
@ -97,11 +93,8 @@ abstract class PolyculeDatabase : RoomDatabase() {
|
|||
bio = Bio(
|
||||
name = "Blizzard",
|
||||
description = init,
|
||||
pfpRes = R.drawable.ic_app_logo
|
||||
)
|
||||
bioDao.insert(bio)
|
||||
val count = bioDao.getAllAlphabetisedBios().count()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,7 @@ package com.menagerie.ophelia.database.polycule
|
|||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
object PolyculeDatabaseManager {
|
||||
|
||||
lateinit var polyculeRepository : PolyculeRepository
|
||||
lateinit var polyculeRepository: PolyculeRepository
|
||||
|
||||
suspend fun post(bio: Bio) {
|
||||
polyculeRepository.upsertBio(bio)
|
||||
|
|
|
@ -4,11 +4,9 @@ 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) {
|
||||
return bioDao.upsert(bio)
|
||||
}
|
||||
|
@ -24,7 +22,8 @@ class PolyculeRepository(
|
|||
fun getAllBios(): Flow<List<Bio>> {
|
||||
return bioDao.getAllBios()
|
||||
}
|
||||
suspend fun insert(bio : Bio) {
|
||||
|
||||
suspend fun insert(bio: Bio) {
|
||||
bioDao.insert(bio)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ abstract class BioDao {
|
|||
abstract suspend fun delete(bio: Bio)
|
||||
|
||||
@Update
|
||||
abstract suspend fun update(existingBio: Bio) : Int
|
||||
abstract suspend fun update(existingBio: Bio): Int
|
||||
|
||||
@Query("SELECT * FROM bio_table ORDER BY name ASC")
|
||||
abstract fun getAllAlphabetisedBios(): Flow<List<Bio>>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.menagerie.ophelia.database.polycule.entity
|
||||
|
||||
import android.graphics.drawable.Icon
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
|
@ -14,7 +13,5 @@ import androidx.room.PrimaryKey
|
|||
)
|
||||
class Identity (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val uniqueId: Long = 0,
|
||||
val name: String = "",
|
||||
val icon: Icon,
|
||||
)
|
|
@ -13,8 +13,8 @@ abstract class IdentityDao {
|
|||
@Update
|
||||
abstract suspend fun update(idenity: Identity)
|
||||
|
||||
@Query("SELECT * FROM Identity WHERE uniqueId = :uniqueId")
|
||||
abstract suspend fun findByIdentity(uniqueId : Long): Identity?
|
||||
@Query("SELECT * FROM Identity WHERE id = :uniqueId")
|
||||
abstract suspend fun findByIdentity(uniqueId: Int): Identity?
|
||||
|
||||
|
||||
}
|
|
@ -1,25 +1,20 @@
|
|||
package com.menagerie.ophelia.database.polycule.entity.viewmodel
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.asLiveData
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeDatabaseManager
|
||||
import com.menagerie.ophelia.database.polycule.PolyculeRepository
|
||||
|
||||
class BioDetailViewModel() : ViewModel(){
|
||||
class BioDetailViewModel() : ViewModel() {
|
||||
|
||||
private var bioId: Int = 0
|
||||
var bio = PolyculeDatabaseManager.polyculeRepository.getBio(bioId).asLiveData()
|
||||
|
||||
fun setBio(bioId: Int)
|
||||
{
|
||||
fun setBio(bioId: Int) {
|
||||
this.bioId = bioId
|
||||
bio = PolyculeDatabaseManager.polyculeRepository.getBio(bioId).asLiveData()
|
||||
}
|
||||
|
||||
|
||||
|
||||
class BioDetailViewModelFactory() :
|
||||
ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>, ): T {
|
||||
|
|
|
@ -12,7 +12,8 @@ import kotlinx.coroutines.launch
|
|||
|
||||
class BioListViewModel() : ViewModel() {
|
||||
|
||||
val allBios: LiveData<List<Bio>> = PolyculeDatabaseManager.polyculeRepository.getAllBios().asLiveData()
|
||||
val allBios: LiveData<List<Bio>> =
|
||||
PolyculeDatabaseManager.polyculeRepository.getAllBios().asLiveData()
|
||||
|
||||
fun upsert(bio: Bio) = viewModelScope.launch {
|
||||
PolyculeDatabaseManager.polyculeRepository.upsertBio(bio)
|
||||
|
|
|
@ -5,7 +5,6 @@ import androidx.compose.ui.graphics.Color
|
|||
val Purple80 = Color(0xFFFF00FF)
|
||||
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||
val Pink80 = Color(0xFFEFB8C8)
|
||||
val Transparent = Color(0x00000000)
|
||||
|
||||
val Purple40 = Color(0x0000FF22)
|
||||
val PurpleGrey40 = Color(0xFF625b71)
|
||||
|
|
|
@ -25,16 +25,6 @@ private val LightColorScheme = lightColorScheme(
|
|||
primary = Purple40,
|
||||
secondary = PurpleGrey40,
|
||||
tertiary = Pink40
|
||||
|
||||
/* 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),
|
||||
*/
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
|
@ -9,7 +9,7 @@ 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,
|
||||
|
|
|
@ -65,7 +65,7 @@ fun HomeBioScreen(
|
|||
|
||||
Column(
|
||||
modifier = modifier
|
||||
){
|
||||
) {
|
||||
BioCardList(bioList = items, onBioClick = onBioClick)
|
||||
FloatingActionButton(
|
||||
onClick = onAddClick
|
||||
|
@ -87,12 +87,11 @@ fun HomeTopAppBar(
|
|||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
) {
|
||||
}
|
||||
},
|
||||
modifier = modifier.statusBarsPadding(),
|
||||
actions = {},
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package com.menagerie.ophelia.view
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
|
@ -12,7 +10,6 @@ import androidx.navigation.navArgument
|
|||
import com.menagerie.ophelia.view.biographies.AddBiography
|
||||
import com.menagerie.ophelia.view.biographies.BioDetailsScreen
|
||||
|
||||
|
||||
@Composable
|
||||
fun PolyculeApp() {
|
||||
val navController = rememberNavController()
|
||||
|
@ -25,8 +22,6 @@ fun PolyculeApp() {
|
|||
fun PolyculeNavHost(
|
||||
navController: NavHostController
|
||||
) {
|
||||
val activity = (LocalContext.current as Activity)
|
||||
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = "home"
|
||||
|
@ -37,7 +32,7 @@ fun PolyculeNavHost(
|
|||
navController.navigate("bioDetail/${it.id}")
|
||||
},
|
||||
onAddClick = {
|
||||
navController.navigate("addBio")
|
||||
navController.navigate("addBio")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.menagerie.ophelia.view.biographies
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
|
@ -13,18 +15,19 @@ import androidx.compose.runtime.livedata.observeAsState
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
||||
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.viewmodel.BioListViewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioListViewModel
|
||||
import com.menagerie.ophelia.view.components.InputFieldComponent
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import com.menagerie.ophelia.view.components.fab.FABComponent
|
||||
import kotlin.random.Random
|
||||
|
||||
fun insertBioInDB(bio: Bio?, mBioListViewModel: BioListViewModel) {
|
||||
bio?.let {
|
||||
|
@ -33,7 +36,6 @@ fun insertBioInDB(bio: Bio?, mBioListViewModel: BioListViewModel) {
|
|||
}
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AddBiography() {
|
||||
val inputViewModel = InputViewModel()
|
||||
|
@ -43,14 +45,14 @@ fun AddBiography() {
|
|||
)
|
||||
|
||||
Scaffold(
|
||||
floatingActionButton = {
|
||||
FABComponent(text = "${R.string.add_bio}", onClick = {
|
||||
insertBioInDB(inputViewModel.bio.value, mBioListViewModel)
|
||||
floatingActionButton = {
|
||||
FABComponent(text = "${stringResource(id = R.string.add_bio)}", onClick = {
|
||||
insertBioInDB(inputViewModel.bio.value, mBioListViewModel)
|
||||
|
||||
Toast.makeText(context, "Added Bio", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
)
|
||||
Toast.makeText(context, "Added Bio", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
)
|
||||
{
|
||||
InputFieldState(inputViewModel)
|
||||
}
|
||||
|
@ -62,9 +64,10 @@ fun InputFieldState(
|
|||
) {
|
||||
val bio: Bio by inputViewModel.bio.observeAsState(Bio())
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp)){
|
||||
InputField(bio.name){inputViewModel.onInputChange(it)}
|
||||
Spacer(modifier = Modifier.padding(10.dp))
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
InputField(bio.name) { inputViewModel.onInputChange(it) }
|
||||
Spacer(modifier = Modifier.padding(10.dp))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +78,7 @@ fun InputField(
|
|||
) {
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
if(onValChange != null) {
|
||||
if (onValChange != null) {
|
||||
InputFieldComponent(
|
||||
text = name,
|
||||
onChange = onValChange,
|
||||
|
@ -83,7 +86,7 @@ fun InputField(
|
|||
modifier = Modifier
|
||||
.padding(all = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
keyboardActions = KeyboardActions( onDone = {focusManager.clearFocus()})
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -91,11 +94,15 @@ fun InputField(
|
|||
class InputViewModel : ViewModel() {
|
||||
private val _bio: MutableLiveData<Bio> = MutableLiveData(Bio())
|
||||
val bio: LiveData<Bio> = _bio
|
||||
|
||||
fun onInputChange(name: String)
|
||||
{
|
||||
fun onInputChange(name: String) {
|
||||
var desc = LoremIpsum(Random.nextInt(5,100)).values.toList()
|
||||
var init = ""
|
||||
repeat(desc.size) {
|
||||
init += ("${desc[it]} ")
|
||||
}
|
||||
val newBio = Bio(
|
||||
name = name,
|
||||
description = init,
|
||||
)
|
||||
_bio.value = newBio
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.menagerie.ophelia.view.biographies
|
|||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
@ -36,9 +35,8 @@ 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.database.polycule.entity.Bio
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun BioCard(
|
||||
name: String,
|
||||
|
@ -48,14 +46,13 @@ fun BioCard(
|
|||
onDeleteClick: () -> Unit
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
|
||||
Card(
|
||||
onClick = onBioClick,
|
||||
modifier = Modifier
|
||||
.padding(10.dp)
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
,
|
||||
.wrapContentHeight(),
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
elevation = CardDefaults.cardElevation(
|
||||
defaultElevation = 6.dp
|
||||
|
@ -91,15 +88,15 @@ fun BioCard(
|
|||
{
|
||||
IconButton(
|
||||
onClick = { expanded = true }) {
|
||||
Icon(
|
||||
Icons.Default.MoreVert,
|
||||
contentDescription = ""
|
||||
)
|
||||
Icon(
|
||||
Icons.Default.MoreVert,
|
||||
contentDescription = ""
|
||||
)
|
||||
}
|
||||
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
|
||||
DropdownMenuItem(text = { Text(text = "Delete")}, onClick = onDeleteClick)
|
||||
DropdownMenuItem(text = { Text(text = "Delete") }, onClick = onDeleteClick)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -55,7 +55,7 @@ fun BioCardList(
|
|||
name = bio.name,
|
||||
description = bio.description,
|
||||
image = bio.pfpRes,
|
||||
onBioClick = {onBioClick(bio)},
|
||||
onBioClick = { onBioClick(bio) },
|
||||
onDeleteClick = { mBioListViewModel.delete(bio) })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
package com.menagerie.ophelia.view.biographies
|
||||
|
||||
import android.util.Log
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
|
@ -23,10 +18,10 @@ import androidx.compose.ui.platform.LocalDensity
|
|||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.menagerie.ophelia.database.polycule.entity.Bio
|
||||
import com.menagerie.ophelia.database.polycule.entity.viewmodel.BioDetailViewModel
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import com.menagerie.ophelia.view.components.utils.Dimens
|
||||
|
||||
data class BioDetailCallbacks(
|
||||
|
@ -45,7 +40,7 @@ fun BioDetailsScreen(
|
|||
|
||||
val bio = mBioDetailViewModel.bio.observeAsState().value
|
||||
|
||||
if(bio != null) {
|
||||
if (bio != null) {
|
||||
Surface {
|
||||
BioDetails(
|
||||
bio,
|
||||
|
@ -80,10 +75,10 @@ fun BioDetails(
|
|||
fun BioDetailContents(
|
||||
bio: Bio,
|
||||
imageHeight: Dp,
|
||||
){
|
||||
) {
|
||||
Column {
|
||||
ConstraintLayout {
|
||||
val(image, info) = createRefs()
|
||||
val (image, info) = createRefs()
|
||||
Image(
|
||||
painter = painterResource(id = bio.pfpRes),
|
||||
contentDescription = null,
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
package com.menagerie.ophelia.view.components
|
||||
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.modifier.modifierLocalConsumer
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun InputFieldComponent(
|
||||
text: String,
|
||||
|
|
|
@ -14,7 +14,7 @@ fun FABComponent(
|
|||
ExtendedFloatingActionButton(
|
||||
onClick = onClick,
|
||||
elevation = FloatingActionButtonDefaults.elevation(8.dp)
|
||||
){
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.modifier.modifierLocalConsumer
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
|
|
|
@ -12,7 +12,6 @@ import kotlinx.coroutines.delay
|
|||
|
||||
@SuppressLint("CustomSplashScreen")
|
||||
class SplashActivity : ComponentActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
|
@ -25,12 +24,13 @@ class SplashActivity : ComponentActivity() {
|
|||
lifecycleScope.launchWhenCreated {
|
||||
delay(1500)
|
||||
|
||||
val intent = Intent(this@SplashActivity,
|
||||
MainActivity::class.java)
|
||||
val intent = Intent(
|
||||
this@SplashActivity,
|
||||
MainActivity::class.java
|
||||
)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue