Skip to content

Commit

Permalink
Merge branch 'feature/11-handle-screenshots-types' into 'master'
Browse files Browse the repository at this point in the history
Resolve "Handle screenshots types"

Closes #85, #84, #83, #82, and #11

See merge request halcyonmobile/android-technical/multiplatform-playground!62
  • Loading branch information
Róbert Nagy committed Jan 12, 2021
2 parents aa0716c + 932a17c commit 9be3696
Show file tree
Hide file tree
Showing 38 changed files with 494 additions and 649 deletions.
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: java -jar ./backend/build/libs/Backend.jar
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.halcyonmobile.multiplatformplayground.ui

import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.Image
import androidx.compose.foundation.ScrollableColumn
import androidx.compose.foundation.layout.*
Expand All @@ -14,8 +15,12 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.AmbientContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.net.toUri
import com.halcyonmobile.multiplatformplayground.R
import com.halcyonmobile.multiplatformplayground.shared.util.toImageFile
import com.halcyonmobile.multiplatformplayground.ui.shared.Screenshots
import com.halcyonmobile.multiplatformplayground.ui.theme.AppTheme
import com.halcyonmobile.multiplatformplayground.util.composables.BackBar
import com.halcyonmobile.multiplatformplayground.viewmodel.ApplicationDetailViewModel
Expand All @@ -28,6 +33,7 @@ fun ApplicationDetail(applicationId: Long, upPress: () -> Unit) {
remember(applicationId) { ApplicationDetailViewModel(applicationId) }
val applicationWithDetail by viewModel.applicationDetailUiModel.collectAsState()
val state by viewModel.state.collectAsState()
val contentResolver = (AmbientContext.current as AppCompatActivity).contentResolver

Scaffold(
topBar = { BackBar(upPress = upPress) },
Expand Down Expand Up @@ -72,7 +78,9 @@ fun ApplicationDetail(applicationId: Long, upPress: () -> Unit) {
)
}
Description(it.description)
// TODO add screenshots
Screenshots(screenshots = it.screenshots.map { screenshot ->
screenshot.image.toUri().toImageFile(contentResolver)
})
}
}
ApplicationDetailViewModel.State.ERROR -> Column(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,8 @@
package com.halcyonmobile.multiplatformplayground.ui

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.FloatingActionButton
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.ScrollableTabRow
import androidx.compose.material.Snackbar
import androidx.compose.material.Surface
import androidx.compose.material.Tab
import androidx.compose.material.TabConstants
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.TabConstants.defaultTabIndicatorOffset
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,16 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.preferredSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyRowFor
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.AmbientContext
import androidx.compose.ui.res.stringResource
Expand All @@ -44,6 +37,7 @@ import com.halcyonmobile.multiplatformplayground.model.ui.UploadApplicationUiMod
import com.halcyonmobile.multiplatformplayground.model.ui.UploadApplicationUiModelChangeListener
import com.halcyonmobile.multiplatformplayground.shared.util.ImageFile
import com.halcyonmobile.multiplatformplayground.shared.util.toImageFile
import com.halcyonmobile.multiplatformplayground.ui.shared.Screenshots
import com.halcyonmobile.multiplatformplayground.ui.theme.AppTheme
import com.halcyonmobile.multiplatformplayground.util.composables.BackBar
import com.halcyonmobile.multiplatformplayground.util.registerForActivityResult
Expand All @@ -59,40 +53,62 @@ fun UploadApplication(initialCategoryId: Long, upPress: () -> Unit) {
val uploadApplicationUiModel by viewModel.uploadApplicationUiModel.collectAsState(
UploadApplicationUiModel(categoryId = initialCategoryId)
)
val state by viewModel.state.collectAsState()
val event by viewModel.event.collectAsState(null)

if (event == UploadApplicationViewModel.Event.SUCCESSFUL_UPLOAD) {
upPress()
}

val getIcon = registerForGalleryResult(viewModel::onIconChanged)
val getScreenshot = registerForGalleryResult(viewModel::onAddScreenshot)

Scaffold(
topBar = { BackBar(upPress = upPress) },
bodyContent = {
ScrollableColumn(contentPadding = PaddingValues(16.dp)) {
Card(
modifier = Modifier.preferredSize(88.dp).align(Alignment.CenterHorizontally),
shape = CircleShape,
backgroundColor = AppTheme.colors.cardButton
when (state) {
UploadApplicationViewModel.State.LOADING -> Box(
Modifier.wrapContentSize(align = Alignment.Center).padding(16.dp)
) {
Box(Modifier.clickable { getIcon.launchAsImageResult() }) {
if (uploadApplicationUiModel.icon == null) {
Image(
imageVector = vectorResource(id = R.drawable.ic_add_image),
colorFilter = ColorFilter.tint(AppTheme.colors.secondary),
modifier = Modifier.wrapContentSize().align(Alignment.Center)
)
} else {
CoilImage(
data = uploadApplicationUiModel.icon!!.uri,
modifier = Modifier.matchParentSize(),
contentScale = ContentScale.Crop
)
CircularProgressIndicator()
}
UploadApplicationViewModel.State.NORMAL -> ScrollableColumn(
contentPadding = PaddingValues(16.dp)
) {
Card(
modifier = Modifier.preferredSize(88.dp)
.align(Alignment.CenterHorizontally),
shape = CircleShape,
backgroundColor = AppTheme.colors.cardButton
) {
Box(Modifier.clickable { getIcon.launchAsImageResult() }) {
if (uploadApplicationUiModel.icon == null) {
Image(
imageVector = vectorResource(id = R.drawable.ic_add_image),
colorFilter = ColorFilter.tint(AppTheme.colors.secondary),
modifier = Modifier.wrapContentSize().align(Alignment.Center)
)
} else {
CoilImage(
data = uploadApplicationUiModel.icon!!.uri,
modifier = Modifier.matchParentSize(),
contentScale = ContentScale.Crop
)
}
}
}
Screenshots(
screenshots = uploadApplicationUiModel.screenshots,
onAddScreenshot = { getScreenshot.launchAsImageResult() },
showAdd = true
)
ApplicationDetails(uploadApplicationUiModel, viewModel)
ExtendedFloatingActionButton(
text = { Text(stringResource(R.string.submit)) },
onClick = viewModel::submit,
modifier = Modifier.fillMaxWidth().padding(16.dp)
)
}
Screenshots(
screenshots = uploadApplicationUiModel.screenshots,
onAddScreenshot = { getScreenshot.launchAsImageResult() }
)
ApplicationDetails(uploadApplicationUiModel, viewModel)
}
}
)
Expand All @@ -108,41 +124,6 @@ private fun registerForGalleryResult(callback: (ImageFile) -> Unit) =
}
}

@Composable
private fun Screenshots(screenshots: List<ImageFile>, onAddScreenshot: () -> Unit) {
Column {
Text(
text = stringResource(id = R.string.screenshots),
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(16.dp)
)
LazyRowFor(items = screenshots + null, modifier = Modifier.padding(8.dp)) {
if (it != null) {
CoilImage(
data = it.uri,
modifier = Modifier.preferredSize(88.dp).padding(8.dp),
contentScale = ContentScale.Crop
)
} else {
Card(
modifier = Modifier.preferredSize(88.dp).padding(8.dp),
shape = RectangleShape,
backgroundColor = AppTheme.colors.cardButton
) {
Box(Modifier.clickable(onClick = onAddScreenshot)) {
Image(
imageVector = vectorResource(id = R.drawable.ic_add_image),
colorFilter = ColorFilter.tint(AppTheme.colors.secondary),
modifier = Modifier.wrapContentSize().align(Alignment.Center)
)
}

}
}
}
}
}

@Composable
private fun ApplicationDetails(
uploadApplicationUiModel: UploadApplicationUiModel,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.halcyonmobile.multiplatformplayground.ui.shared

import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyRowFor
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import com.halcyonmobile.multiplatformplayground.R
import com.halcyonmobile.multiplatformplayground.shared.util.ImageFile
import com.halcyonmobile.multiplatformplayground.ui.theme.AppTheme
import dev.chrisbanes.accompanist.coil.CoilImage

@Composable
fun Screenshots(screenshots: List<ImageFile>, onAddScreenshot: () -> Unit = {}, showAdd: Boolean = false) {
Column {
val items = if(showAdd) screenshots + null else screenshots
Text(
text = stringResource(id = R.string.screenshots),
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(16.dp)
)
LazyRowFor(items = items, modifier = Modifier.padding(8.dp)) {
if (it != null) {
CoilImage(
data = it.uri,
modifier = Modifier.preferredSize(88.dp).padding(8.dp),
contentScale = ContentScale.Crop
)
} else {
Card(
modifier = Modifier.preferredSize(88.dp).padding(8.dp),
shape = RectangleShape,
backgroundColor = AppTheme.colors.cardButton
) {
Box(Modifier.clickable(onClick = onAddScreenshot)) {
Image(
imageVector = vectorResource(id = R.drawable.ic_add_image),
colorFilter = ColorFilter.tint(AppTheme.colors.secondary),
modifier = Modifier.wrapContentSize().align(Alignment.Center)
)
}

}
}
}
}
}
1 change: 0 additions & 1 deletion backend/Procfile

This file was deleted.

4 changes: 2 additions & 2 deletions backend/app.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Start on Heroku: AppPortfolio backend",
"description": "A barebones Kotlin app, which can easily be deployed to Heroku.",
"name": "Start on Heroku: Multiplatform backend",
"description": "Kotlin multiplatform backend",
"image": "heroku/java",
"addons": [ "heroku-postgresql" ]
}
32 changes: 28 additions & 4 deletions backend/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

buildscript {
repositories {
jcenter()
}
dependencies {
classpath(Versions.Jvm.SHADOW_GRADLE_PLUGIN)
}
}

application {
// TODO to solve deprecation checkout https://github.com/johnrengelman/shadow/issues/336
mainClassName = "com.halcyonmobile.multiplatformplayground.ServerKt"
}

plugins {
kotlin("jvm")
kotlin("plugin.serialization") version Versions.KOTLIN_VERSION
application
id("com.github.johnrengelman.shadow") version Versions.Jvm.SHADOW_JAR_VERSION
}

application {
mainClass.set("com.halcyonmobile.multiplatformplayground.ServerKt")
}

dependencies {
implementation(project(":commonModel"))
implementation(Versions.Jvm.STANDARD_LIBRARY)
implementation(Versions.Jvm.KTOR_CLIENT_APACHE)
implementation(Versions.Jvm.KTOR_SERIALIZATION)

Expand All @@ -24,8 +39,17 @@ dependencies {
implementation(Versions.Jvm.JETBRAINS_EXPOSED_CORE)
implementation(Versions.Jvm.JETBRAINS_EXPOSED_DAO)
implementation(Versions.Jvm.JETBRAINS_EXPOSED_JDBC)
implementation(Versions.Jvm.H2_DATABASE)
implementation(Versions.Jvm.POSTGRESQL)
implementation(Versions.Jvm.HIKARI_CONNECTION_POOL)

implementation(Versions.Jvm.LOGBACK)

implementation(Versions.Jvm.AWS_JAVA_SDK)
}

tasks.withType<ShadowJar> {
archiveBaseName.set("Backend")
archiveClassifier.set("")
archiveVersion.set("")
isZip64 = true
}
Loading

0 comments on commit 9be3696

Please sign in to comment.