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
16 changes: 15 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import java.util.Properties

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.serialization)
}

val properties = Properties().apply {
load(project.rootProject.file("local.properties").inputStream())
}

android {
Expand All @@ -16,6 +23,8 @@ android {
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("String", "BASE_URL", properties["base.url"].toString())
}

buildTypes {
Expand All @@ -36,6 +45,7 @@ android {
}
buildFeatures {
compose = true
buildConfig = true
}
}

Expand All @@ -59,5 +69,9 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)

implementation(libs.kotlinx.serialization.json)
implementation(libs.retrofit.core)
implementation(libs.retrofit.kotlin.serialization)
implementation(libs.okhttp.logging)
implementation(libs.accompanist.pager)
}
6 changes: 5 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.sopt.at">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ATSOPTANDROID">
android:theme="@style/Theme.ATSOPTANDROID"
android:usesCleartextTraffic="true"
>

<activity
android:name=".MainActivity"
Expand Down
10 changes: 1 addition & 9 deletions app/src/main/java/org/sopt/at/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ package org.sopt.at
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import org.sopt.at.ui.TvingApp
import org.sopt.at.ui.theme.TvingTheme

Expand All @@ -15,11 +11,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
TvingTheme {
Surface(
modifier = Modifier.fillMaxSize()
) {
TvingApp()
}
TvingApp()
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions app/src/main/java/org/sopt/at/data/local/UserLocalDataSource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.sopt.at.data.local

import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit

class UserLocalDataSource(context: Context) {

private val sharedPreferences: SharedPreferences =
context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE)

var userId: Long
get() = sharedPreferences.getLong(KEY_USER_ID, DEFAULT_USER_ID)
set(value) {
sharedPreferences.edit() { putLong(KEY_USER_ID, value) }
}

fun clear() {
sharedPreferences.edit() { clear() }
}

companion object {
private const val PREFERENCES_NAME = "user_data"
private const val KEY_USER_ID = "user_id"
private const val DEFAULT_USER_ID = -1L
}
}
18 changes: 18 additions & 0 deletions app/src/main/java/org/sopt/at/data/network/ApiConstraints.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.at.data.network


object ApiConstraints {
// API
const val API = "api"

// VERSION
const val VERSION = "v1"

// Auth
const val AUTH = "auth"

// User
const val USERS = "users"


}
37 changes: 37 additions & 0 deletions app/src/main/java/org/sopt/at/data/network/ApiFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.sopt.at.data.network

import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import okhttp3.MediaType.Companion.toMediaType
import org.sopt.at.BuildConfig

object ApiFactory {
private const val BASE_URL: String = BuildConfig.BASE_URL

private val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}

private val client = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()

val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
}

inline fun <reified T> create(): T = retrofit.create(T::class.java)
}

object ServicePool {
val userService: AuthService by lazy {
ApiFactory.create<AuthService>()
}
}
31 changes: 31 additions & 0 deletions app/src/main/java/org/sopt/at/data/network/AuthService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.sopt.at.data.network

import org.sopt.at.data.network.ApiConstraints.API
import org.sopt.at.data.network.ApiConstraints.AUTH
import org.sopt.at.data.network.ApiConstraints.USERS
import org.sopt.at.data.network.ApiConstraints.VERSION
import org.sopt.at.data.network.dto.RequestSignInDto
import org.sopt.at.data.network.dto.RequestSignUpDto
import org.sopt.at.data.network.dto.ResponseMyNicknameDto
import org.sopt.at.data.network.dto.ResponseSignInDto
import org.sopt.at.data.network.dto.ResponseSignUpDto
import retrofit2.Response
import retrofit2.Call
import retrofit2.http.*

interface AuthService {
@POST("$API/$VERSION/$AUTH/signup")
suspend fun signUp(
@Body request: RequestSignUpDto,
): Response<ResponseSignUpDto>

@POST("$API/$VERSION/$AUTH/signin")
suspend fun signIn (
@Body request: RequestSignInDto,
): Response<ResponseSignInDto>

@GET("$API/$VERSION/$USERS/me")
suspend fun getMyNickname(
@Header("userId") userId: Long
): Response<ResponseMyNicknameDto>
}
12 changes: 12 additions & 0 deletions app/src/main/java/org/sopt/at/data/network/dto/RequestSignInDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.sopt.at.data.network.dto

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RequestSignInDto(
@SerialName("loginId")
val loginId: String,
@SerialName("password")
val password: String,
)
14 changes: 14 additions & 0 deletions app/src/main/java/org/sopt/at/data/network/dto/RequestSignUpDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.at.data.network.dto

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RequestSignUpDto(
@SerialName("loginId")
val loginId: String,
@SerialName("password")
val password: String,
@SerialName("nickname")
val nickname: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.at.data.network.dto

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseMyNicknameDto(
@SerialName("success")
val success: Boolean,
@SerialName("code")
val code: String,
@SerialName("message")
val message: String,
@SerialName("data")
val data: MyInfoData? = null
)

@Serializable
data class MyInfoData(
@SerialName("nickname")
val nickname: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.sopt.at.data.network.dto
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseSignInDto(
@SerialName("success")
val success: Boolean,
@SerialName("code")
val code: String,
@SerialName("message")
val message: String,
@SerialName("data")
val data: SignInDataDto? = null
)

@Serializable
data class SignInDataDto(
@SerialName("userId")
val userId: Long
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.sopt.at.data.network.dto

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseSignUpDto(
@SerialName("success")
val success: Boolean,
@SerialName("code")
val code: String,
@SerialName("message")
val message: String,
@SerialName("data")
val data: SignUpData? = null
)

@Serializable
data class SignUpData(
@SerialName("userId")
val userId: Long,
@SerialName("nickname")
val nickname: String
)
7 changes: 7 additions & 0 deletions app/src/main/java/org/sopt/at/domain/model/NetworkModels.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.at.domain.model

data class SignupRequest(val id: String, val password: String, val nickname: String)
data class SignupResponse(val isSuccess: Boolean, val message: String)
data class LoginRequest(val id: String, val password: String)
data class LoginResponse(val userId: Int)
data class NicknameResponse(val nickname: String)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.at.model
package org.sopt.at.domain.model

data class User(
val userId: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
package org.sopt.at.repository
package org.sopt.at.domain.repository

import android.content.Context
import androidx.compose.ui.platform.LocalContext
import kotlinx.coroutines.flow.MutableStateFlow
import org.sopt.at.model.User
import org.sopt.at.data.local.UserLocalDataSource
import org.sopt.at.domain.model.User


class UserRepository {
class UserRepository(context: Context) {
private val _registeredUsers = MutableStateFlow<List<User>>(emptyList())
private val userLocalDataSource = UserLocalDataSource(context =context)

fun isLoggedIn():Boolean{
return (userLocalDataSource.userId != DEFAULT_USER_ID)
}

fun getLocalUserId():Long{
return userLocalDataSource.userId
}

fun setLocalUserId(userId:Long){
userLocalDataSource.userId = userId
}

fun clearLocalUserId(){
userLocalDataSource.userId = DEFAULT_USER_ID
}

fun registerUser(user: User) {
val currentUsers = _registeredUsers.value.toMutableList()
Expand Down Expand Up @@ -33,4 +53,8 @@ class UserRepository {

return result
}

companion object {
private const val DEFAULT_USER_ID = -1L
}
}
Loading