diff --git a/.gitignore b/.gitignore index afda0220c..98f4581a5 100644 --- a/.gitignore +++ b/.gitignore @@ -79,7 +79,7 @@ captures/ *.keystore # Google Services (e.g. APIs or Firebase) -# google-services.json +google-services.json # Android Patch gen-external-apklibs @@ -164,7 +164,7 @@ crashlytics-build.properties fabric.properties # Uncomment the following line in case you need and you don't have the release build type files in your app - release/ +release/ ### AndroidStudio Patch ### diff --git a/app/build.gradle b/app/build.gradle index 2d7140880..c9b32b095 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,6 +8,10 @@ plugins { id 'kotlin-android-extensions' } +Properties properties = new Properties() +properties.load(project.rootProject.file('local.properties').newDataInputStream()) +def kakao_native_app_key = properties.get('KAKAO_NATIVE_APP_KEY_NO_QUEOTS') + android { compileSdk 31 @@ -15,10 +19,30 @@ android { applicationId "org.sopt.havit" minSdk 23 targetSdk 31 - versionCode 100 + versionCode 101 versionName "1.0.0" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + buildConfigField("String", "HAVIT_BASE_URL_DEV", properties["HAVIT_BASE_URL_DEV"]) + buildConfigField("String", "HAVIT_BASE_URL_PROD", properties["HAVIT_BASE_URL_PROD"]) + buildConfigField("String", "KAKAO_NATIVE_APP_KEY", properties['KAKAO_NATIVE_APP_KEY']) + manifestPlaceholders = [KAKAO_NATIVE_APP_KEY: kakao_native_app_key] + } + + flavorDimensions "server" + productFlavors { + prod { + dimension "server" + manifestPlaceholders = [appLabel: "HAVIT"] + buildConfigField 'boolean', 'IS_PROD', "true" + buildConfigField 'boolean', 'IS_DEV', "false" + } + dev { + dimension "server" + applicationIdSuffix ".dev" + manifestPlaceholders = [appLabel: "(Dev)HAVIT"] + buildConfigField 'boolean', 'IS_PROD', "false" + buildConfigField 'boolean', 'IS_DEV', "true" + } } buildTypes { @@ -47,7 +71,7 @@ android { dataBinding true } - androidExtensions{ + androidExtensions { experimental = true } } diff --git a/app/google-services.json b/app/google-services.json deleted file mode 100644 index 6944d2589..000000000 --- a/app/google-services.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "project_info": { - "project_number": "123299355425", - "project_id": "havit-wesopt29", - "storage_bucket": "havit-wesopt29.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:123299355425:android:ad6471d89ad5fdff3afc60", - "android_client_info": { - "package_name": "org.sopt.havit" - } - }, - "oauth_client": [ - { - "client_id": "123299355425-8dio4tfb3p806q6h4dk6doe8ik1045ue.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyDgFlN3zqPpRFWI9V0GHUN5HONXvxCZzT0" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "123299355425-8dio4tfb3p806q6h4dk6doe8ik1045ue.apps.googleusercontent.com", - "client_type": 3 - } - ] - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json deleted file mode 100644 index 4815ea09b..000000000 --- a/app/release/output-metadata.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": 3, - "artifactType": { - "type": "APK", - "kind": "Directory" - }, - "applicationId": "org.sopt.havit", - "variantName": "release", - "elements": [ - { - "type": "SINGLE", - "filters": [], - "attributes": [], - "versionCode": 1, - "versionName": "1.0", - "outputFile": "app-release.apk" - } - ], - "elementType": "File" -} \ No newline at end of file diff --git a/app/src/dev/ic_launcher_havit-playstore.png b/app/src/dev/ic_launcher_havit-playstore.png new file mode 100644 index 000000000..3b6131e03 Binary files /dev/null and b/app/src/dev/ic_launcher_havit-playstore.png differ diff --git a/app/src/dev/res/mipmap-anydpi-v26/ic_launcher_havit.xml b/app/src/dev/res/mipmap-anydpi-v26/ic_launcher_havit.xml new file mode 100644 index 000000000..bdba3dc24 --- /dev/null +++ b/app/src/dev/res/mipmap-anydpi-v26/ic_launcher_havit.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/dev/res/mipmap-anydpi-v26/ic_launcher_havit_round.xml b/app/src/dev/res/mipmap-anydpi-v26/ic_launcher_havit_round.xml new file mode 100644 index 000000000..bdba3dc24 --- /dev/null +++ b/app/src/dev/res/mipmap-anydpi-v26/ic_launcher_havit_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/dev/res/mipmap-hdpi/ic_launcher_havit.png b/app/src/dev/res/mipmap-hdpi/ic_launcher_havit.png new file mode 100644 index 000000000..b352481fb Binary files /dev/null and b/app/src/dev/res/mipmap-hdpi/ic_launcher_havit.png differ diff --git a/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_background.png b/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_background.png new file mode 100644 index 000000000..3613d0aea Binary files /dev/null and b/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_background.png differ diff --git a/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_foreground.png b/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_foreground.png new file mode 100644 index 000000000..6f348c85f Binary files /dev/null and b/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_foreground.png differ diff --git a/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_round.png b/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_round.png new file mode 100644 index 000000000..5651e7b98 Binary files /dev/null and b/app/src/dev/res/mipmap-hdpi/ic_launcher_havit_round.png differ diff --git a/app/src/dev/res/mipmap-mdpi/ic_launcher_havit.png b/app/src/dev/res/mipmap-mdpi/ic_launcher_havit.png new file mode 100644 index 000000000..474105b61 Binary files /dev/null and b/app/src/dev/res/mipmap-mdpi/ic_launcher_havit.png differ diff --git a/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_background.png b/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_background.png new file mode 100644 index 000000000..bb3484ecf Binary files /dev/null and b/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_background.png differ diff --git a/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_foreground.png b/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_foreground.png new file mode 100644 index 000000000..106e828a7 Binary files /dev/null and b/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_foreground.png differ diff --git a/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_round.png b/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_round.png new file mode 100644 index 000000000..9e9c41470 Binary files /dev/null and b/app/src/dev/res/mipmap-mdpi/ic_launcher_havit_round.png differ diff --git a/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit.png b/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit.png new file mode 100644 index 000000000..813b6f913 Binary files /dev/null and b/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit.png differ diff --git a/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_background.png b/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_background.png new file mode 100644 index 000000000..3645d35a2 Binary files /dev/null and b/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_background.png differ diff --git a/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_foreground.png b/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_foreground.png new file mode 100644 index 000000000..b74971bf8 Binary files /dev/null and b/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_foreground.png differ diff --git a/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_round.png b/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_round.png new file mode 100644 index 000000000..f1e064947 Binary files /dev/null and b/app/src/dev/res/mipmap-xhdpi/ic_launcher_havit_round.png differ diff --git a/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit.png b/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit.png new file mode 100644 index 000000000..85088af12 Binary files /dev/null and b/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit.png differ diff --git a/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_background.png b/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_background.png new file mode 100644 index 000000000..2e0ac47fe Binary files /dev/null and b/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_background.png differ diff --git a/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_foreground.png b/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_foreground.png new file mode 100644 index 000000000..9235e8429 Binary files /dev/null and b/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_foreground.png differ diff --git a/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_round.png b/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_round.png new file mode 100644 index 000000000..2bf7adcda Binary files /dev/null and b/app/src/dev/res/mipmap-xxhdpi/ic_launcher_havit_round.png differ diff --git a/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit.png b/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit.png new file mode 100644 index 000000000..2fd219f24 Binary files /dev/null and b/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit.png differ diff --git a/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_background.png b/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_background.png new file mode 100644 index 000000000..c70ee951c Binary files /dev/null and b/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_background.png differ diff --git a/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_foreground.png b/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_foreground.png new file mode 100644 index 000000000..a94e1bf04 Binary files /dev/null and b/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_foreground.png differ diff --git a/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_round.png b/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_round.png new file mode 100644 index 000000000..0d0c5def9 Binary files /dev/null and b/app/src/dev/res/mipmap-xxxhdpi/ic_launcher_havit_round.png differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d190c5e5e..927a09a2e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,7 +19,7 @@ android:name=".MainApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher_havit" - android:label="@string/app_name" + android:label="${appLabel}" android:roundIcon="@mipmap/ic_launcher_havit_round" android:supportsRtl="true" android:theme="@style/Theme.Havit" @@ -164,7 +164,7 @@ + android:scheme="kakao${KAKAO_NATIVE_APP_KEY}" /> - generateNotification(title, description, bitmapImage, url) + generateNotification(title, description, isSeen, contentId, bitmapImage, url) } } @@ -64,19 +66,24 @@ class HavitFirebaseMessagingService : FirebaseMessagingService() { private fun generateNotification( title: String?, message: String?, + isSeen: Boolean? = null, + contentId: Int? = null, image: Bitmap? = null, url: String? = null ) { - Log.d("MyFirebaseMessagingService", "$title, $message") val requestCode = System.currentTimeMillis().toInt() val intent = Intent(this, WebActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.putExtra("url", url) - val pendingIntent = - PendingIntent.getActivity( - this, requestCode, intent, PendingIntent.FLAG_IMMUTABLE - ) + intent.apply { + putExtra("url", url) + putExtra("isSeen", isSeen) + putExtra("contentsId", contentId) + } + val pendingIntent = PendingIntent.getActivity( + this, requestCode, intent, PendingIntent.FLAG_IMMUTABLE + ) val builder = NotificationCompat.Builder(this, channelID) .setPriority(NotificationCompat.PRIORITY_HIGH) diff --git a/app/src/main/java/org/sopt/havit/MainApplication.kt b/app/src/main/java/org/sopt/havit/MainApplication.kt index 2f9014c51..97b24e6a8 100644 --- a/app/src/main/java/org/sopt/havit/MainApplication.kt +++ b/app/src/main/java/org/sopt/havit/MainApplication.kt @@ -9,6 +9,6 @@ class MainApplication : Application() { override fun onCreate() { super.onCreate() - KakaoSdk.init(this, getString(R.string.kakao_app_key)) + KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY) } } diff --git a/app/src/main/java/org/sopt/havit/data/RetrofitObject.kt b/app/src/main/java/org/sopt/havit/data/RetrofitObject.kt index 4355e70ba..6e8c6d6e4 100644 --- a/app/src/main/java/org/sopt/havit/data/RetrofitObject.kt +++ b/app/src/main/java/org/sopt/havit/data/RetrofitObject.kt @@ -3,6 +3,7 @@ package org.sopt.havit.data import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor +import org.sopt.havit.BuildConfig.* import org.sopt.havit.data.api.HavitApi import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory @@ -10,10 +11,8 @@ import java.util.concurrent.TimeUnit object RetrofitObject { - private const val baseUrl = "https://asia-northeast3-havit-wesopt29.cloudfunctions.net/api/" - private fun getRetrofitBuild(jwt: String) = Retrofit.Builder() - .baseUrl(baseUrl) + .baseUrl(if (IS_DEV) HAVIT_BASE_URL_DEV else HAVIT_BASE_URL_PROD) .client(getOkhttpClient(jwt)) .addConverterFactory(GsonConverterFactory.create()) .build() diff --git a/app/src/main/java/org/sopt/havit/data/api/HavitApi.kt b/app/src/main/java/org/sopt/havit/data/api/HavitApi.kt index 0dd493813..f9bf02972 100644 --- a/app/src/main/java/org/sopt/havit/data/api/HavitApi.kt +++ b/app/src/main/java/org/sopt/havit/data/api/HavitApi.kt @@ -9,12 +9,12 @@ import retrofit2.http.* interface HavitApi { - @GET("content/search/?keyword=") + @GET("content/search?") suspend fun getSearchContents( @Query("keyword") keyword: String ): ContentsSearchResponse - @GET("content/search?categoryId=&keyword=") + @GET("content/search?") suspend fun getSearchCategory( @Query("categoryId") categoryId: String, @Query("keyword") keyword: String @@ -46,7 +46,7 @@ interface HavitApi { @Body body: CreateContentsRequest ): CreateContentsResponse - @GET("category/{categoryId}?option=&filter=") + @GET("category/{categoryId}?") suspend fun getCategoryContents( @Path("categoryId") categoryId: Int, @Query("option") option: String, @@ -78,7 +78,7 @@ interface HavitApi { @Body body: UpdateCategoryInfoRequest ): BasicResponse - @GET("content?option=&filter=") + @GET("content?") suspend fun getAllContents( @Query("option") option: String, @Query("filter") filter: String @@ -113,7 +113,7 @@ interface HavitApi { @Body body: SignUpRequest ): SignUpResponse - @GET("content/notification?option=") + @GET("content/notification?") suspend fun getNotification( @Query("option") option: String, ): NotificationResponse diff --git a/app/src/main/java/org/sopt/havit/data/remote/ContentsSimpleResponse.kt b/app/src/main/java/org/sopt/havit/data/remote/ContentsSimpleResponse.kt index ff27941ed..a32ced51e 100644 --- a/app/src/main/java/org/sopt/havit/data/remote/ContentsSimpleResponse.kt +++ b/app/src/main/java/org/sopt/havit/data/remote/ContentsSimpleResponse.kt @@ -7,7 +7,7 @@ data class ContentsSimpleResponse( val success: Boolean ) { data class ContentsSimpleData( - var createdAt: String, + val createdAt: String, var description: String?, val id: Int, val image: String, diff --git a/app/src/main/java/org/sopt/havit/data/remote/NotificationResponse.kt b/app/src/main/java/org/sopt/havit/data/remote/NotificationResponse.kt index 8ea2b0d9e..66fed211a 100644 --- a/app/src/main/java/org/sopt/havit/data/remote/NotificationResponse.kt +++ b/app/src/main/java/org/sopt/havit/data/remote/NotificationResponse.kt @@ -14,6 +14,6 @@ data class NotificationResponse( val image: String, val url: String, var isSeen: Boolean, - var createdAt: String + val createdAt: String ) } diff --git a/app/src/main/java/org/sopt/havit/di/RetrofitModule.kt b/app/src/main/java/org/sopt/havit/di/RetrofitModule.kt index b696f4cc2..c231fd3ee 100644 --- a/app/src/main/java/org/sopt/havit/di/RetrofitModule.kt +++ b/app/src/main/java/org/sopt/havit/di/RetrofitModule.kt @@ -9,6 +9,7 @@ import dagger.hilt.components.SingletonComponent import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor +import org.sopt.havit.BuildConfig.* import org.sopt.havit.data.source.local.AuthLocalDataSourceImpl import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory @@ -58,10 +59,8 @@ object RetrofitModule { client: OkHttpClient, gson: Gson ): Retrofit = Retrofit.Builder() - .baseUrl(baseUrl) + .baseUrl(if (IS_DEV) HAVIT_BASE_URL_DEV else HAVIT_BASE_URL_PROD) .client(client) .addConverterFactory(GsonConverterFactory.create(gson)) .build() - - private const val baseUrl = "https://asia-northeast3-havit-wesopt29.cloudfunctions.net/api/" } diff --git a/app/src/main/java/org/sopt/havit/domain/entity/Contents.kt b/app/src/main/java/org/sopt/havit/domain/entity/Contents.kt index 5403d4897..0e062be2a 100644 --- a/app/src/main/java/org/sopt/havit/domain/entity/Contents.kt +++ b/app/src/main/java/org/sopt/havit/domain/entity/Contents.kt @@ -1,7 +1,7 @@ package org.sopt.havit.domain.entity data class Contents( - var createdAt: String, + val createdAt: String, val description: String, val id: Int, val image: String, diff --git a/app/src/main/java/org/sopt/havit/ui/contents_simple/ContentsSimpleViewModel.kt b/app/src/main/java/org/sopt/havit/ui/contents_simple/ContentsSimpleViewModel.kt index d797aa0ae..82ab1bc05 100644 --- a/app/src/main/java/org/sopt/havit/ui/contents_simple/ContentsSimpleViewModel.kt +++ b/app/src/main/java/org/sopt/havit/ui/contents_simple/ContentsSimpleViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.sopt.havit.data.RetrofitObject @@ -13,6 +14,7 @@ import org.sopt.havit.domain.entity.NetworkState import org.sopt.havit.util.HavitSharedPreference import javax.inject.Inject +@HiltViewModel class ContentsSimpleViewModel @Inject constructor( preference: HavitSharedPreference ) : ViewModel() { diff --git a/app/src/main/java/org/sopt/havit/ui/home/HomeCategoryVpAdapter.kt b/app/src/main/java/org/sopt/havit/ui/home/HomeCategoryVpAdapter.kt index 8ece4c7dc..bf9d19771 100644 --- a/app/src/main/java/org/sopt/havit/ui/home/HomeCategoryVpAdapter.kt +++ b/app/src/main/java/org/sopt/havit/ui/home/HomeCategoryVpAdapter.kt @@ -59,8 +59,7 @@ class HomeCategoryVpAdapter : RecyclerView.Adapter(R.layout.fragment_ disableRvSmoothScroll() setVpSensitivity() - return binding.root - } - - override fun onStart() { - super.onStart() categoryDataObserve() // 카테고리 초기화 recentContentsDataObserve() // 최근저장 콘텐츠 초기화 notificationDataObserve() // 알림 아이콘 초기화 initReachRate() // 도달률 관련 데이터 초기화 + addSourceOnIsReadyToSetCategory() + + return binding.root } override fun onResume() { @@ -72,6 +70,15 @@ class HomeFragment : BaseBindingFragment(R.layout.fragment_ setData() } + override fun onDestroyView() { + homeViewModel.removeSourceOnIsReadyToSetCategory() + super.onDestroyView() + } + + private fun addSourceOnIsReadyToSetCategory() { + homeViewModel.addSourceOnIsReadyToSetCategory() + } + private fun disableRvSmoothScroll() { binding.svMain.isSmoothScrollingEnabled = false } @@ -171,13 +178,11 @@ class HomeFragment : BaseBindingFragment(R.layout.fragment_ private fun categoryDataObserve() { with(homeViewModel) { - userData.observe(viewLifecycleOwner) { userData -> - categoryData.observe(viewLifecycleOwner) { data -> - if (data.isNotEmpty()) { - val list = setList(data, userData.totalContentNumber) - categoryVpAdapter.updateList(list) - binding.layoutCategory.indicatorCategory.attachTo(binding.layoutCategory.vpCategory) - } + isReadyToSetCategory.observe(viewLifecycleOwner) { isServerLoadComplete -> + if (isServerLoadComplete) { + val list = setList() + categoryVpAdapter.updateList(list) + binding.layoutCategory.indicatorCategory.attachTo(binding.layoutCategory.vpCategory) } } } diff --git a/app/src/main/java/org/sopt/havit/ui/home/HomeRecentContentsRvAdapter.kt b/app/src/main/java/org/sopt/havit/ui/home/HomeRecentContentsRvAdapter.kt index 967a4bbc1..e617af5b7 100644 --- a/app/src/main/java/org/sopt/havit/ui/home/HomeRecentContentsRvAdapter.kt +++ b/app/src/main/java/org/sopt/havit/ui/home/HomeRecentContentsRvAdapter.kt @@ -17,20 +17,12 @@ class HomeRecentContentsRvAdapter : inner class HomeContentsViewHolder(private val binding: ItemHomeRecentContentsListBinding) : RecyclerView.ViewHolder(binding.root) { fun onBind(data: ContentsSimpleResponse.ContentsSimpleData) { - if (data.createdAt.length == 16) { - changeTimeFormat(data) // 시간 형식 변경 - } binding.homeRecentData = data.apply { this.description = this.description?.replace(" ", "\u00a0") ?: "" // tvHeader 단어 자동줄바꿈 막는 코드 } binding.homeRecentData = data } - - private fun changeTimeFormat(data: ContentsSimpleResponse.ContentsSimpleData) { - data.createdAt = data.createdAt.substring(0 until 10) - .replace("-", ". ") - } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeContentsViewHolder { diff --git a/app/src/main/java/org/sopt/havit/ui/home/HomeViewModel.kt b/app/src/main/java/org/sopt/havit/ui/home/HomeViewModel.kt index 8089766db..a9be26d7f 100644 --- a/app/src/main/java/org/sopt/havit/ui/home/HomeViewModel.kt +++ b/app/src/main/java/org/sopt/havit/ui/home/HomeViewModel.kt @@ -1,9 +1,6 @@ package org.sopt.havit.ui.home -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope +import androidx.lifecycle.* import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -77,39 +74,31 @@ class HomeViewModel @Inject constructor( } // category 전체 데이터를 6개씩 잘라 List로 묶는 함수 - fun setList( - data: - List, - totalNum: Int - ): MutableList> { + fun setList(): MutableList> { + val categoryData = requireNotNull(categoryData.value) + val totalContentsNum = requireNotNull(userData.value?.totalContentNumber) + val list = mutableListOf(listOf()) var count = 0 - val firstData = Category( - totalNum, - -1, - -1, - "", - -1, - "모든 콘텐츠" - ) + val firstData = Category(totalContentsNum, -1, -1, "", -1, "모든 콘텐츠") list.clear() - while (data.size > count) { + while (categoryData.size > count) { if (count == 0) { val firstPage = mutableListOf() firstPage.clear() firstPage.add(firstData) - val min = if (data.size < 5) (data.size - 1) else 4 + val min = if (categoryData.size < 5) (categoryData.size - 1) else 4 for (i in 0..min) { - firstPage.add(data[i]) + firstPage.add(categoryData[i]) } list.add(firstPage) count += 5 } else { - if (data.size - count >= 6) { - list.add(data.subList(count, count + 6)) + if (categoryData.size - count >= 6) { + list.add(categoryData.subList(count, count + 6)) count += 6 } else { - list.add(data.subList(count, data.size)) + list.add(categoryData.subList(count, categoryData.size)) break } } @@ -198,4 +187,30 @@ class HomeViewModel @Inject constructor( ) _loadState.postValue(NetworkState.SUCCESS) } + + // userdata(totalContents), CategoryData 두개가 모두 로드되어야만 카테고리 뷰 작업 가능 + private val _isReadyToSetCategory = MediatorLiveData() + val isReadyToSetCategory: LiveData = _isReadyToSetCategory + + fun addSourceOnIsReadyToSetCategory() { + _isReadyToSetCategory.addSource(userData) { + setIsReadyToSetCategory(userData, categoryData) + } + _isReadyToSetCategory.addSource(categoryData) { + setIsReadyToSetCategory(userData, categoryData) + } + } + + fun removeSourceOnIsReadyToSetCategory() { + _isReadyToSetCategory.removeSource(userData) + _isReadyToSetCategory.removeSource(categoryData) + } + + private fun setIsReadyToSetCategory( + userData: LiveData, + categoryData: LiveData> + ) { + _isReadyToSetCategory.value = userData.value != null && categoryData.value != null + } + } diff --git a/app/src/main/java/org/sopt/havit/ui/share/ShareViewModel.kt b/app/src/main/java/org/sopt/havit/ui/share/ShareViewModel.kt index bbc2bf4a1..b738e8cdc 100644 --- a/app/src/main/java/org/sopt/havit/ui/share/ShareViewModel.kt +++ b/app/src/main/java/org/sopt/havit/ui/share/ShareViewModel.kt @@ -1,7 +1,5 @@ package org.sopt.havit.ui.share -import android.content.ContentValues.TAG -import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -11,7 +9,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.jsoup.Jsoup import org.jsoup.nodes.Document -import org.jsoup.select.Elements import org.sopt.havit.data.RetrofitObject import org.sopt.havit.data.mapper.CategoryMapper import org.sopt.havit.data.remote.ContentsSummeryData @@ -193,50 +190,40 @@ class ShareViewModel @Inject constructor( fun setCrawlingContents() { viewModelScope.launch { getOgData() - setModifyTitle() setDefaultIfTitleDataNotExist() } } - private fun setModifyTitle() { - if (preference.getTitle().isNotEmpty()) - ogData.value?.ogTitle = preference.getTitle() - } - private fun setDefaultIfTitleDataNotExist() { - if (ogData.value?.ogTitle == "") + if (ogData.value?.ogTitle.isNullOrBlank()) _ogData.value?.ogTitle = NO_TITLE_CONTENTS } private suspend fun getOgData() { viewModelScope.launch(Dispatchers.IO) { kotlin.runCatching { - val doc: Document = Jsoup.connect(url.value).get() - doc.select("meta[property^=og:]") + Jsoup.connect(url.value).get() }.onSuccess { - throwExceptionIfDataUnavailable(it.size) val contentsSummeryData = getDataByOgTags(it) _ogData.postValue(contentsSummeryData) }.onFailure { - Log.d(TAG, "crawling fail / $it ") + _ogData.postValue(ContentsSummeryData(ogUrl = url.value.toString())) } }.join() } - private fun throwExceptionIfDataUnavailable(dataSize: Int) { - if (dataSize == 0) throw IllegalStateException() - } - - private fun getDataByOgTags(it: Elements): ContentsSummeryData { + private fun getDataByOgTags(it: Document): ContentsSummeryData { + val doc = it.select("meta[property^=og:]") return ContentsSummeryData(ogUrl = url.value.toString()).apply { - it.forEachIndexed { index, _ -> - val tag = it[index] - when (it[index].attr("property")) { + doc.forEachIndexed { index, _ -> + val tag = doc[index] + when (doc[index].attr("property")) { "og:image" -> ogImage = tag.attr("content") "og:description" -> ogDescription = tag.attr("content") "og:title" -> ogTitle = tag.attr("content") } } + if (this.ogTitle == "") this.ogTitle = it.title() } } diff --git a/app/src/main/java/org/sopt/havit/ui/share/edit_title/EditTitleFragment.kt b/app/src/main/java/org/sopt/havit/ui/share/edit_title/EditTitleFragment.kt index 2aaf5ed11..de618b8c4 100644 --- a/app/src/main/java/org/sopt/havit/ui/share/edit_title/EditTitleFragment.kt +++ b/app/src/main/java/org/sopt/havit/ui/share/edit_title/EditTitleFragment.kt @@ -5,19 +5,20 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import dagger.hilt.android.AndroidEntryPoint import org.sopt.havit.databinding.FragmentEditTitleBinding -import org.sopt.havit.util.* -import javax.inject.Inject +import org.sopt.havit.ui.share.ShareViewModel +import org.sopt.havit.util.AutoClearedValue +import org.sopt.havit.util.DialogUtil +import org.sopt.havit.util.KeyBoardUtil +import org.sopt.havit.util.OnBackPressedHandler @AndroidEntryPoint class EditTitleFragment : Fragment(), OnBackPressedHandler { - - @Inject - lateinit var preference: HavitSharedPreference - + private val viewModel: ShareViewModel by activityViewModels() private var binding: FragmentEditTitleBinding by AutoClearedValue() private val args by navArgs() @@ -44,7 +45,9 @@ class EditTitleFragment : Fragment(), OnBackPressedHandler { } } - private fun setOriginTitle() = binding.etTitle.setText(args.contentsOriginTitle) + private fun setOriginTitle() = binding.etTitle.setText( + viewModel.ogData.value?.ogTitle ?: throw IllegalStateException("Og Data Not Initialized") + ) private fun setKeyBoardUp() = KeyBoardUtil.openKeyBoard(requireContext(), binding.etTitle) @@ -54,7 +57,7 @@ class EditTitleFragment : Fragment(), OnBackPressedHandler { private fun initClickListener() { binding.icBack.setOnClickListener { onBackClicked() } binding.tvComplete.setOnClickListener { - preference.setTitle(binding.etTitle.text.toString()) + viewModel.ogData.value?.ogTitle = binding.etTitle.text.toString() goBack() } } diff --git a/app/src/main/java/org/sopt/havit/ui/web/WebActivity.kt b/app/src/main/java/org/sopt/havit/ui/web/WebActivity.kt index 4682cdc49..ed45c81f8 100644 --- a/app/src/main/java/org/sopt/havit/ui/web/WebActivity.kt +++ b/app/src/main/java/org/sopt/havit/ui/web/WebActivity.kt @@ -74,16 +74,6 @@ class WebActivity : BaseBindingActivity(R.layout.activity_we } return false } - - - override fun onReceivedError( - view: WebView?, - request: WebResourceRequest?, - error: WebResourceError? - ) { - super.onReceivedError(view, request, error) - webViewModel.isServerNetwork.value = NetworkState.FAIL - } } settings.javaScriptEnabled = true settings.domStorageEnabled = true diff --git a/app/src/main/java/org/sopt/havit/util/BindingAdapter.kt b/app/src/main/java/org/sopt/havit/util/BindingAdapter.kt index eeabd847f..855555b95 100644 --- a/app/src/main/java/org/sopt/havit/util/BindingAdapter.kt +++ b/app/src/main/java/org/sopt/havit/util/BindingAdapter.kt @@ -17,6 +17,7 @@ import org.sopt.havit.domain.model.NetworkStatus import org.sopt.havit.util.CalenderUtil.setDateFormat import org.sopt.havit.util.CalenderUtil.setDateFormatOnCategoryView import org.sopt.havit.util.CalenderUtil.setDateFormatOnRadioBtn +import org.sopt.havit.util.CalenderUtil.setDotsDateFormat import org.sopt.havit.util.DpToPxUtil.px // item_category @@ -99,7 +100,6 @@ fun ImageView.defaultImageLinearMax(url: String?) { fun ImageView.setOgImage(url: String?) { Glide.with(context) .load(url) - .transform(CenterCrop(), RoundedCorners(px(6))) .placeholder(R.drawable.img_contents_dummy_3) .into(this) } @@ -144,6 +144,11 @@ fun TextView.setAlarmText(string: String?) { this.text = if (string == null) "알림 설정" else setDateFormat(string) } +@BindingAdapter("setDotsDateFormat") +fun TextView.setSaveText(string: String) { + this.text = setDotsDateFormat(string) +} + @BindingAdapter("notificationTimeOnContentsView") fun TextView.setNotificationText(string: String?) { if (string?.isEmpty() == true) this.text = "" diff --git a/app/src/main/java/org/sopt/havit/util/CalenderUtil.kt b/app/src/main/java/org/sopt/havit/util/CalenderUtil.kt index 64588045c..5770de52f 100644 --- a/app/src/main/java/org/sopt/havit/util/CalenderUtil.kt +++ b/app/src/main/java/org/sopt/havit/util/CalenderUtil.kt @@ -24,9 +24,6 @@ object CalenderUtil { val dateAndTimeWithDotFormatMD: DateFormat get() = SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault()) - val calWithHavitFormat_YMD_HM: DateFormat - get() = SimpleDateFormat("yyyy-MM-dd hh:mm", Locale.getDefault()) - fun setTimePickerInterval(timePicker: TimePicker) { val minutePicker = timePicker.findViewById( Resources.getSystem().getIdentifier("minute", "id", "android") @@ -80,4 +77,8 @@ object CalenderUtil { val time = setDateFormatOnRadioBtn(originTime) return "$time 알림 예정" } + + fun setDotsDateFormat(originTime: String): String { + return originTime.substring(0, 10).replace("-", ". ") + } } diff --git a/app/src/main/res/drawable-hdpi/img_policy.png b/app/src/main/res/drawable-hdpi/img_policy.png index 8d257f531..683a42ba6 100644 Binary files a/app/src/main/res/drawable-hdpi/img_policy.png and b/app/src/main/res/drawable-hdpi/img_policy.png differ diff --git a/app/src/main/res/drawable-mdpi/img_policy.png b/app/src/main/res/drawable-mdpi/img_policy.png index 5d4488062..9dd78c33d 100644 Binary files a/app/src/main/res/drawable-mdpi/img_policy.png and b/app/src/main/res/drawable-mdpi/img_policy.png differ diff --git a/app/src/main/res/drawable-xhdpi/img_policy.png b/app/src/main/res/drawable-xhdpi/img_policy.png index 517a3f326..bacb82c1d 100644 Binary files a/app/src/main/res/drawable-xhdpi/img_policy.png and b/app/src/main/res/drawable-xhdpi/img_policy.png differ diff --git a/app/src/main/res/drawable-xxhdpi/img_policy.png b/app/src/main/res/drawable-xxhdpi/img_policy.png index a0b75d23c..f53b06d3f 100644 Binary files a/app/src/main/res/drawable-xxhdpi/img_policy.png and b/app/src/main/res/drawable-xxhdpi/img_policy.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/img_policy.png b/app/src/main/res/drawable-xxxhdpi/img_policy.png index 810e109f0..4906ddbeb 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/img_policy.png and b/app/src/main/res/drawable-xxxhdpi/img_policy.png differ diff --git a/app/src/main/res/layout/fragment_contents_more.xml b/app/src/main/res/layout/fragment_contents_more.xml index 0712cf780..0e1be6307 100644 --- a/app/src/main/res/layout/fragment_contents_more.xml +++ b/app/src/main/res/layout/fragment_contents_more.xml @@ -76,10 +76,10 @@ - -