Skip to content

Commit

Permalink
feat: implement image content entity
Browse files Browse the repository at this point in the history
  • Loading branch information
d1snin committed Sep 6, 2023
1 parent 209e6e8 commit 631a528
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public data object ButtonLinkContentEntityTypeDefinition : CommonContentEntityTy

val text: ContentEntityParameterDefinition = parameter("text", required = true, translatable = true)

val url: ContentEntityParameterDefinition = urlParameter(required = true, translatable = true)
val url: ContentEntityParameterDefinition = urlParameter(required = true)

val style: ContentEntityParameterDefinition = parameter("style")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ public abstract class CommonContentEntityTypeDefinition(name: String) : ContentE

protected fun urlParameter(
required: Boolean = false,
translatable: Boolean = false
translatable: Boolean = true
): ContentEntityParameterDefinition = parameter("url", required, translatable)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ private val definitions = listOf(
VoidContentEntityTypeDefinition,
TextContentEntityTypeDefinition,
ButtonLinkContentEntityTypeDefinition,
SpaceContentEntityTypeDefinition
SpaceContentEntityTypeDefinition,
ImageContentEntityTypeDefinition
)

public fun definition(name: ContentEntityTypeName): ContentEntityTypeDefinition? =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2023 Mikhail Titov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.d1s.beam.commons.contententity

public data object ImageContentEntityTypeDefinition : CommonContentEntityTypeDefinition(name = "image") {

val url: ContentEntityParameterDefinition = urlParameter(required = true)

val description: ContentEntityParameterDefinition = parameter("description", translatable = true)

val width: ContentEntityParameterDefinition = widthParameter()

val height: ContentEntityParameterDefinition = heightParameter()
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public data object TextContentEntityTypeDefinition : CommonContentEntityTypeDefi

val secondary: ContentEntityParameterDefinition = parameter("secondary")

val url: ContentEntityParameterDefinition = urlParameter(translatable = true)
val url: ContentEntityParameterDefinition = urlParameter()

public enum class Heading(public val key: String) {
H1("h1"), H2("h2"), H3("h3");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ internal abstract class ContentEntityValidator<in D : ContentEntityTypeDefinitio
VoidContentEntityValidator,
TextContentEntityValidator,
ButtonLinkContentEntityValidator,
SpaceContentEntityValidator
SpaceContentEntityValidator,
ImageContentEntityValidator
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2023 Mikhail Titov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.d1s.beam.commons.validation

import dev.d1s.beam.commons.contententity.ContentEntity
import dev.d1s.beam.commons.contententity.ImageContentEntityTypeDefinition
import io.konform.validation.ValidationBuilder

internal object ImageContentEntityValidator :
ContentEntityValidator<ImageContentEntityTypeDefinition>(ImageContentEntityTypeDefinition) {

override fun ValidationBuilder<ContentEntity>.validate() {
val validator = this@ImageContentEntityValidator

requireCorrectUrl(validator, definition.url)
requireNotBlankText(validator, definition.description)
requireCorrectWidth(validator, definition.width)
requireCorrectHeight(validator, definition.height)
}
}
5 changes: 5 additions & 0 deletions beam-ui/src/jsMain/kotlin/dev/d1s/beam/ui/Module.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ object Qualifier {
val TextContentEntityRenderer = named("text-content-entity-renderer")
val ButtonLinkContentEntityRenderer = named("button-link-content-entity-renderer")
val SpaceContentEntityRenderer = named("space-content-entity-renderer")
val ImageContentEntityRenderer = named("image-content-entity-renderer")

val NotFoundSpaceFailureCardContent = named("not-found-space-failure-card-content")
val EmptySpaceFailureCardContent = named("empty-space-failure-card-content")
Expand Down Expand Up @@ -172,6 +173,10 @@ private fun Module.contentEntityRenderers() {
singleOf<ContentEntityRenderer>(::SpaceContentEntityRenderer) {
qualifier = Qualifier.SpaceContentEntityRenderer
}

singleOf<ContentEntityRenderer>(::ImageContentEntityRenderer) {
qualifier = Qualifier.ImageContentEntityRenderer
}
}

private fun Module.spaceFailureCardContents() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2023 Mikhail Titov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.d1s.beam.ui.contententity

import dev.d1s.beam.commons.Block
import dev.d1s.beam.commons.contententity.ContentEntities
import dev.d1s.beam.commons.contententity.ContentEntity
import dev.d1s.beam.commons.contententity.ImageContentEntityTypeDefinition
import dev.d1s.beam.commons.contententity.get
import io.kvision.html.div
import io.kvision.html.image
import io.kvision.panel.SimplePanel
import io.kvision.utils.perc
import io.kvision.utils.px
import org.koin.core.component.KoinComponent

class ImageContentEntityRenderer : ContentEntityRenderer, KoinComponent {

override val definition = ImageContentEntityTypeDefinition

override fun SimplePanel.render(sequence: ContentEntities, block: Block) {
renderImageRow {
renderImages(sequence)
}
}

private fun SimplePanel.renderImageRow(block: SimplePanel.() -> Unit) {
div(className = "row row-cols-auto g-3") {
block()
}
}

private fun SimplePanel.renderImages(sequence: ContentEntities) {
sequence.forEach { entity ->
renderImage(entity)
}
}

private fun SimplePanel.renderImage(entity: ContentEntity) {
val parameters = entity.parameters

val src = parameters[definition.url]
requireNotNull(src)

val description = parameters[definition.description]

val width = parameters[definition.width]?.toInt()
val height = parameters[definition.height]?.toInt()

image(src, description, responsive = true) {
width?.let {
this.width = it.perc
}

height?.let {
this.height = it.px
}
}
}
}

0 comments on commit 631a528

Please sign in to comment.