Skip to content

Commit 122d2c3

Browse files
committed
feat: Asset download api추가
1 parent 5d064e6 commit 122d2c3

11 files changed

Lines changed: 169 additions & 18 deletions

File tree

skills/add-pet-emotion-animation.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ emotion이 base 펫과 동일한 위치에 나타나도록 `emotionYOffsets` 값
227227
- 디버깅 시 `minGap``maxGap``1.0`으로 설정하면 1초마다 emotion이 나타나서 위치 확인이 쉬움
228228
- standing 포즈와 sitting 포즈는 보정값이 다를 수 있음 (DESSERT_FOX 기준: standing `5.0`, sitting `2.5`)
229229

230+
### 6. PersonaEmotionType 구현하기
231+
org.gitanimals.render.app.PersonaEmotionAssets에 PersonaEmotionAssets.dessertFox를 참고하여 새롭게 추가한 emotion의 PersonaEmotionAssets을 추가하세요.
232+
230233
## buildEmotionAnimation 파라미터
231234

232235
| 파라미터 | 타입 | 설명 |

src/main/kotlin/org/gitanimals/core/PersonaEmotionType.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/main/kotlin/org/gitanimals/core/PersonaType.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.gitanimals.core
22

3-
import org.gitanimals.core.PersonaEmotionType.*
43
import java.text.DecimalFormat
54
import kotlin.math.atan2
65
import kotlin.math.max
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.gitanimals.core
2+
3+
import org.springframework.beans.factory.annotation.Value
4+
import org.springframework.stereotype.Component
5+
6+
object ProfileIdentifier {
7+
8+
private lateinit var holder: Holder
9+
const val LOCAL = "local"
10+
const val LIVE = "live"
11+
12+
fun getProfile(): String = holder.profile
13+
14+
fun isLocal(): Boolean = holder.profile == LOCAL
15+
16+
17+
@Component
18+
class Holder(
19+
@Value("\${spring.profiles.active}") val profile: String,
20+
) {
21+
init {
22+
holder = this
23+
}
24+
}
25+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.gitanimals.render.app
2+
3+
import com.github.benmanes.caffeine.cache.Cache
4+
import com.github.benmanes.caffeine.cache.Caffeine
5+
import org.gitanimals.core.PersonaType
6+
import org.gitanimals.core.ProfileIdentifier
7+
import org.gitanimals.render.app.response.AssetsResponse
8+
import org.gitanimals.render.domain.UserService
9+
import org.springframework.stereotype.Component
10+
11+
@Component
12+
class AssetsFacade(
13+
private val userService: UserService,
14+
private val identityApi: IdentityApi,
15+
) {
16+
17+
private val cache: Cache<PersonaType, AssetsResponse> = Caffeine.newBuilder()
18+
.maximumSize(100)
19+
.build()
20+
21+
fun findAllAssets(
22+
token: String,
23+
personaType: PersonaType,
24+
): AssetsResponse {
25+
if (ProfileIdentifier.isLocal()) {
26+
return AssetsResponse.createSvg(PersonaEmotionAssets.from(personaType))
27+
}
28+
29+
val identityUser = identityApi.getUserByToken(token)
30+
val renderUser = userService.getUserByName(name = identityUser.username)
31+
32+
require(renderUser.havePersona(personaType)) {
33+
"personaType에 해당하는 Persona가 존재하지 않습니다."
34+
}
35+
36+
return cache.get(personaType) {
37+
AssetsResponse.createSvg(PersonaEmotionAssets.from(personaType))
38+
}
39+
}
40+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.gitanimals.render.app
2+
3+
import org.gitanimals.core.*
4+
5+
sealed interface PersonaEmotionAssets {
6+
val personaType: PersonaType
7+
val error: String
8+
val happy: String
9+
val idleFollow: String
10+
val notification: String
11+
val thinking: String
12+
val typing: String
13+
14+
data object DessertFox : PersonaEmotionAssets {
15+
override val personaType: PersonaType = PersonaType.DESSERT_FOX
16+
override val error: String = dessertFoxErrorEmotionSvg
17+
override val happy: String = dessertFoxHappyEmotionSvg
18+
override val idleFollow: String = dessertFoxIdleFollowEmotionSvg
19+
override val notification: String = dessertFoxNotificationEmotionSvg
20+
override val typing: String = dessertFoxTypingEmotionSvg
21+
override val thinking: String = dessertFoxThinkingEmotionSvg
22+
}
23+
24+
companion object {
25+
fun from(personaType: PersonaType): PersonaEmotionAssets {
26+
return PersonaEmotionAssets::class.sealedSubclasses
27+
.mapNotNull { it.objectInstance }
28+
.find { it.personaType == personaType }
29+
?: throw IllegalArgumentException("Cannot find PersonaEmotionAssets for personaType: $personaType")
30+
}
31+
}
32+
}

src/main/kotlin/org/gitanimals/render/app/UserFacade.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.gitanimals.render.app
22

3-
import org.gitanimals.render.app.request.MergePersonaRequest
43
import org.gitanimals.core.FieldType
4+
import org.gitanimals.render.app.request.MergePersonaRequest
55
import org.gitanimals.render.app.request.MergePersonaV2Request
66
import org.gitanimals.render.domain.UserService
77
import org.gitanimals.render.domain.request.PersonaChangeRequest
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.gitanimals.render.app.response
2+
3+
import org.gitanimals.render.app.PersonaEmotionAssets
4+
5+
data class AssetsResponse(
6+
val animationAssets: PersonaEmotionAssets,
7+
val mimeType: String,
8+
) {
9+
10+
11+
companion object {
12+
private const val MIME_TYPE_SVG_IMAGE = "image/svg+xml"
13+
14+
fun createSvg(
15+
animationAssets: PersonaEmotionAssets,
16+
): AssetsResponse {
17+
return AssetsResponse(
18+
animationAssets = animationAssets,
19+
mimeType = MIME_TYPE_SVG_IMAGE,
20+
)
21+
}
22+
}
23+
}

src/main/kotlin/org/gitanimals/render/controller/AnimationController.kt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@ package org.gitanimals.render.controller
22

33
import jakarta.servlet.http.HttpServletResponse
44
import org.gitanimals.core.Mode
5+
import org.gitanimals.core.PersonaType
56
import org.gitanimals.core.extension.HttpResponseExtension.cacheControl
67
import org.gitanimals.core.extension.StringExtension.deleteBrackets
78
import org.gitanimals.core.extension.StringExtension.trimNotDigitCharacters
89
import org.gitanimals.render.app.AnimationFacade
9-
import org.springframework.web.bind.annotation.GetMapping
10-
import org.springframework.web.bind.annotation.PathVariable
11-
import org.springframework.web.bind.annotation.RequestParam
12-
import org.springframework.web.bind.annotation.RestController
10+
import org.gitanimals.render.app.AssetsFacade
11+
import org.gitanimals.render.app.response.AssetsResponse
12+
import org.springframework.http.HttpHeaders
13+
import org.springframework.web.bind.annotation.*
1314

1415
@RestController
1516
class AnimationController(
1617
private val animationFacade: AnimationFacade,
18+
private val assetsFacade: AssetsFacade,
1719
) {
1820

1921
@GetMapping(value = ["/farms/{username}"], produces = ["image/svg+xml"])
@@ -45,4 +47,12 @@ class AnimationController(
4547
mode = mode,
4648
)
4749
}
50+
51+
@GetMapping(value = ["/assets"])
52+
fun downloadAssetsByPersonaType(
53+
@RequestHeader(HttpHeaders.AUTHORIZATION) token: String,
54+
@RequestParam("personaType") personaType: PersonaType,
55+
): AssetsResponse {
56+
return assetsFacade.findAllAssets(token, personaType)
57+
}
4858
}

src/main/kotlin/org/gitanimals/render/domain/User.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ class User(
376376
return persona.isEvolutionable()
377377
}
378378

379+
fun havePersona(personaType: PersonaType): Boolean {
380+
return personas.any { it.getType() == personaType }
381+
}
382+
379383
companion object {
380384
private const val MAX_PERSONA_COUNT = 30L
381385
private const val MAX_INIT_PERSONA_COUNT = 10L

0 commit comments

Comments
 (0)