Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
import java.util.Properties
val localProperties = Properties()
val localPropertiesFile = rootProject.file("local.properties")

if (localPropertiesFile.exists()) {
localProperties.load(localPropertiesFile.inputStream())
}

val serverUrl =
localProperties.getProperty(
"SERVER_URL",
"http://10.0.2.2:8080",
)

plugins {
id("com.android.application")
alias(libs.plugins.kotlin.compose)
Expand Down Expand Up @@ -102,11 +116,17 @@ android {
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
buildConfigField(
"String",
"SERVER_URL",
"\"$serverUrl\"",
)
}

buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
Expand All @@ -119,6 +139,7 @@ android {
}
buildFeatures {
compose = true
buildConfig = true
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package com.codenames.frontend.data.repository

import com.codenames.frontend.data.model.ChatDomainModel
import com.codenames.frontend.network.dto.ChatMessageDto
import com.codenames.frontend.network.websocket.GameWebSocketHandler
import com.codenames.frontend.network.websocket.GameWebSocketController
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import javax.inject.Inject

class ChatRepository
@Inject
constructor(
private val webSocketHandler: GameWebSocketHandler,
private val webSocketHandler: GameWebSocketController,
) {
fun observeChat(
topic: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
package com.codenames.frontend.data.repository

import com.codenames.frontend.data.model.enums.Team
import com.codenames.frontend.network.dto.ClueMessageDto
import com.codenames.frontend.network.dto.StartGameMessage
import com.codenames.frontend.network.websocket.GameWebSocketHandler
import com.codenames.frontend.network.websocket.GameWebSocketController
import javax.inject.Inject

class GameRepository
@Inject
constructor(
private val webSocketHandler: GameWebSocketHandler,
private val webSocketHandler: GameWebSocketController,
) {
suspend fun startGame(lobbyCode: String) {
val msg = StartGameMessage(lobbyCode)
webSocketHandler.startGame(msg)
}

suspend fun submitClue(
lobbyCode: String,
word: String,
count: Int,
currentTurn: Team,
) {
val msg =
ClueMessageDto(
lobbyCode = lobbyCode,
word = word,
guessAmount = count,
currentTurn = currentTurn,
)
webSocketHandler.sendClue(msg)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.codenames.frontend.network.provider

import com.codenames.frontend.BuildConfig

fun getHttpUrl() = "http://" + BuildConfig.SERVER_URL

fun getWsUrl() = "ws://" + BuildConfig.SERVER_URL + "ws-fallback"
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import retrofit2.Retrofit

const val BASE_URL = "http://localhost:8080/"

@Module
@InstallIn(SingletonComponent::class)
object RetrofitProvider {
Expand All @@ -25,7 +23,7 @@ object RetrofitProvider {
fun provideRetrofit(json: Json): Retrofit =
Retrofit
.Builder()
.baseUrl(BASE_URL)
.baseUrl(getHttpUrl())
.addConverterFactory(
json.asConverterFactory("application/json".toMediaType()),
).build()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.codenames.frontend.network.websocket

import com.codenames.frontend.network.dto.ChatMessageDto
import com.codenames.frontend.network.dto.ClueMessageDto
import com.codenames.frontend.network.dto.GameMessage
import com.codenames.frontend.network.dto.GuessMessage
import com.codenames.frontend.network.dto.StartGameMessage
import com.codenames.frontend.network.dto.WebSocketJoinMessage
import kotlinx.coroutines.flow.Flow
import org.hildan.krossbow.stomp.conversions.kxserialization.convertAndSend
import org.hildan.krossbow.stomp.conversions.kxserialization.subscribe
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class GameWebSocketController
@Inject
constructor(
private val webSocketSessionManager: WebSocketSessionManager,
) {
suspend fun connectStomp() {
webSocketSessionManager.connectStomp()
}

suspend fun startGame(msg: StartGameMessage) {
webSocketSessionManager.getSession().convertAndSend("/app/start-game", msg, StartGameMessage.serializer())
}

@Suppress("kotlin:S6309")
suspend fun subscribeToLobby(lobbyCode: String): Flow<GameMessage> =
webSocketSessionManager.getSession().subscribe("/topic/game/$lobbyCode", GameMessage.serializer())

suspend fun sendReconnectMessage(msg: WebSocketJoinMessage) {
webSocketSessionManager.getSession().convertAndSend("/app/join", msg, WebSocketJoinMessage.serializer())
}

@Suppress("kotlin:S6309")
suspend fun subscribeToChat(topicPath: String): Flow<ChatMessageDto> =
webSocketSessionManager.getSession().subscribe(topicPath, ChatMessageDto.serializer())

suspend fun sendChatMessage(
destination: String,
msg: ChatMessageDto,
) {
webSocketSessionManager.getSession().convertAndSend(destination, msg, ChatMessageDto.serializer())
}

suspend fun sendClue(msg: ClueMessageDto) {
webSocketSessionManager.getSession().convertAndSend("/app/submit-clue", msg, ClueMessageDto.serializer())
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.codenames.frontend.network.websocket

import android.util.Log
import com.codenames.frontend.network.provider.getWsUrl
import jakarta.inject.Inject
import jakarta.inject.Singleton
import org.hildan.krossbow.stomp.StompClient
import org.hildan.krossbow.stomp.conversions.kxserialization.StompSessionWithKxSerialization
import org.hildan.krossbow.stomp.conversions.kxserialization.json.withJsonConversions

@Singleton
class WebSocketSessionManager
@Inject
constructor(
val client: StompClient,
) {
private var session: StompSessionWithKxSerialization? = null

suspend fun connectStomp() {
if (isConnected()) return
try {
session = client.connect(getWsUrl()).withJsonConversions()
} catch (e: Exception) {
Log.e("WebSocket", "Failed to connect to Websocket", e)
return
}
Log.d("WebSocket", "Connected to Websocket, session: $session")
}

fun isConnected(): Boolean = session != null

fun getSession(): StompSessionWithKxSerialization =
requireNotNull(session) {
"WebSocket is not connected"
}

suspend fun disconnect() {
session?.disconnect()
session = null
}
}
Loading
Loading