Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ android {
buildConfig = true
compose = true
}
androidResources {
noCompress += "mp4"
}
}

dependencies {
Expand Down
9 changes: 7 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,21 @@
</service>

<activity
android:name=".MainActivity"
android:name=".SplashActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.JapKor">
android:theme="@style/Theme.JapKor.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.JapKor" />
<activity
android:name="com.apptive.japkor.LoginCallbackActivity"
android:exported="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ class LoginCallbackActivity : ComponentActivity() {

val startRoute = when (userStatus) {
UserStatus.INCOMPLETE_PROFILE -> Screen.RequiredInfo.route
UserStatus.CONNECTING -> Screen.Home.route
UserStatus.PENDING_APPROVAL,
UserStatus.APPROVED,
UserStatus.CONNECTING,
UserStatus.CONNECTED,
UserStatus.BLACKLISTED -> Screen.RequiredInfoComplete.route
null -> when (needsProfileCompletion) {
Expand Down
48 changes: 48 additions & 0 deletions app/src/main/java/com/apptive/japkor/SplashActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.apptive.japkor

import android.content.Intent
import android.media.MediaPlayer
import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import com.apptive.japkor.widget.FullscreenVideoView

class SplashActivity : ComponentActivity() {
private var hasNavigated = false

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)

val videoView = findViewById<FullscreenVideoView>(R.id.splashVideo)
val videoUri = Uri.parse("android.resource://${packageName}/${R.raw.n_splash}")
videoView.setVideoURI(videoUri)
videoView.setOnPreparedListener { mediaPlayer ->
videoView.updateVideoSize(mediaPlayer.videoWidth, mediaPlayer.videoHeight)
mediaPlayer.isLooping = false
mediaPlayer.setVideoScalingMode(
MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
)
videoView.start()
}
videoView.setOnCompletionListener {
videoView.stopPlayback()
navigateToMain()
}
videoView.setOnErrorListener { _, _, _ ->
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handler for the video view returns true, which indicates the error was handled. However, the video is not properly cleaned up before navigating. Consider calling stopPlayback() before navigating to ensure resources are released properly.

Suggested change
videoView.setOnErrorListener { _, _, _ ->
videoView.setOnErrorListener { _, _, _ ->
videoView.stopPlayback()

Copilot uses AI. Check for mistakes.
navigateToMain()
true
}
}

private fun navigateToMain() {
if (hasNavigated) return
hasNavigated = true
val intent = Intent(this, MainActivity::class.java)
intent.putExtras(this.intent)
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Intent.putExtras with this.intent could propagate any extras from the original intent. If the SplashActivity is launched with specific extras, they will be passed to MainActivity. Consider explicitly handling which extras should be forwarded or document this behavior.

Suggested change
intent.putExtras(this.intent)

Copilot uses AI. Check for mistakes.
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
startActivity(intent)
overridePendingTransition(0, 0)
finish()
Comment on lines +38 to +46
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The navigateToMain() function can be called from multiple sources (completion listener and error listener) without proper synchronization. Although hasNavigated flag is checked, this is not thread-safe and could lead to race conditions if both callbacks are triggered simultaneously.

Copilot uses AI. Check for mistakes.
}
}
15 changes: 15 additions & 0 deletions app/src/main/java/com/apptive/japkor/data/api/MatchingService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.apptive.japkor.data.api

import com.apptive.japkor.data.model.MatchingResponse
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path

interface MatchingService {
@GET("members/matchings/female")
fun getFemaleMatchings(): Call<List<MatchingResponse>>

@POST("members/matchings/{matchingId}/select")
fun selectMatching(@Path("matchingId") matchingId: Long): Call<Void>
Comment on lines +4 to +14
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API service methods return Call objects but are being used with awaitResponse(). This is mixing Retrofit's callback-based API with Kotlin coroutines. Consider changing the interface to use suspend functions that return Response directly for cleaner and more idiomatic coroutine usage.

Suggested change
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
interface MatchingService {
@GET("members/matchings/female")
fun getFemaleMatchings(): Call<List<MatchingResponse>>
@POST("members/matchings/{matchingId}/select")
fun selectMatching(@Path("matchingId") matchingId: Long): Call<Void>
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
interface MatchingService {
@GET("members/matchings/female")
suspend fun getFemaleMatchings(): Response<List<MatchingResponse>>
@POST("members/matchings/{matchingId}/select")
suspend fun selectMatching(@Path("matchingId") matchingId: Long): Response<Void>

Copilot uses AI. Check for mistakes.
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ object ServiceFactory {
val requiredInfoApiService: RequiredInfoApiService by lazy {
ApiClient.retrofit.create(RequiredInfoApiService::class.java)
}
}

val matchingService: MatchingService by lazy {
ApiClient.retrofit.create(MatchingService::class.java)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ class DataStoreManager(private val context: Context) {
}
}

suspend fun clearUserInfo() {
context.dataStore.edit { prefs ->
prefs.remove(KEY_MEMBER_ID)
prefs.remove(KEY_NAME)
prefs.remove(KEY_TOKEN)
prefs.remove(KEY_STATUS)
}
}
Comment on lines +90 to +97
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clearUserInfo() method removes specific user-related keys but leaves other potential keys in the DataStore. This could lead to incomplete logout if other user-specific data exists. Consider using the existing clear() method or documenting why selective removal is necessary.

Copilot uses AI. Check for mistakes.

suspend fun clear() {
context.dataStore.edit { it.clear() }
}
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/com/apptive/japkor/data/model/Matching.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.apptive.japkor.data.model

data class MatchingResponse(
val matchingId: Long,
val maleMemberId: Long,
val maleName: String,
val maleEmail: String,
val height: Int?,
val weight: Int?,
val residenceArea: String?,
val matchingOrder: Int,
val status: String
)
6 changes: 6 additions & 0 deletions app/src/main/java/com/apptive/japkor/navigation/AppNavHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.apptive.japkor.ui.main.MainRouteScreen
import com.apptive.japkor.ui.language.LanguageScreen
import com.apptive.japkor.ui.login.LoginScreen
import com.apptive.japkor.ui.requiredinfo.RequiredInfoCompleteScreen
Expand All @@ -15,6 +16,8 @@ sealed class Screen(val route: String) {

object Language : Screen("language")

object Home : Screen("home")

object RequiredInfo : Screen("requiredinfo")

object RequiredInfoComplete : Screen("requiredinfo_complete")
Expand All @@ -38,6 +41,9 @@ fun AppNavHost(
composable(Screen.Login.route) {
LoginScreen(navController)
}
composable(Screen.Home.route) {
MainRouteScreen(navController)
}
composable(Screen.RequiredInfo.route) {
RequiredInfoScreen(navController)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ object AppLocalizer {
"로그인 성공! 환영합니다." to "ログイン成功!ようこそ。",
"로그인 실패! 이메일과 비밀번호를 확인해주세요." to "ログイン失敗。メールアドレスとパスワードを確認してください。",
"로그인" to "ログイン",
"로그아웃" to "ログアウト",
"정말 로그아웃 하시겠어요?" to "本当にログアウトしますか?",
"취소" to "キャンセル",
"아이디 찾기" to "IDを探す",
"비밀번호 찾기" to "パスワードを探す",
"회원가입" to "会員登録",
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/apptive/japkor/ui/login/LoginScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,11 @@ fun LoginScreen(navController: NavController,viewModel: LoginScreenViewModel = v
UserStatus.INCOMPLETE_PROFILE -> {
navController.navigate(Screen.RequiredInfo.route)
}
UserStatus.CONNECTING -> {
navController.navigate(Screen.Home.route)
}
UserStatus.PENDING_APPROVAL,
UserStatus.APPROVED,
UserStatus.CONNECTING,
UserStatus.CONNECTED,
UserStatus.BLACKLISTED -> {
navController.navigate(Screen.RequiredInfoComplete.route)
Expand Down
Loading
Loading