Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…2020_App into feature/issue/droidknights#103

� Conflicts:
�	androidapp/app/src/main/java/com/droidknights/app2020/binding/ViewBinding.kt
�	androidapp/app/src/main/java/com/droidknights/app2020/data/Session.kt
�	androidapp/app/src/main/res/layout/item_session.xml
  • Loading branch information
takedawon committed Sep 3, 2020
2 parents 50a4bf5 + 6126878 commit e3ee830
Show file tree
Hide file tree
Showing 101 changed files with 1,925 additions and 638 deletions.
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,23 @@ AAC 기반의 MVVM 구조
### Libraries

- Jetpack
- [Support Libraries](https://developer.android.com/topic/libraries/support-library/)
- [AndroidX](https://developer.android.com/jetpack/androidx)
- [Appcompat](https://developer.android.com/jetpack/androidx/releases/appcompat)
- [Browser](https://developer.android.com/guide/webapps)
- [ConstraintLayout](https://developer.android.com/training/constraint-layout)
- [Databinding](https://developer.android.com/topic/libraries/data-binding/)
- [ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel)
- [Lifecycle](https://developer.android.com/topic/libraries/architecture/lifecycle)
- [LiveData](https://developer.android.com/topic/libraries/architecture/livedata)
- [Navigation](https://developer.android.com/topic/libraries/architecture/navigation/)
- [Swiperefreshlayout](https://developer.android.com/training/swipe)
- [ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel)


- DI
- [Hilt](https://developer.android.com/training/dependency-injection/hilt-android)

- Coroutine
- Kotlin
- [Stdlib](https://github.com/JetBrains/kotlin)
- [Coroutine](https://github.com/Kotlin/kotlinx.coroutines)
- [flow](https://kotlinlang.org/docs/reference/coroutines/flow.html)

Expand All @@ -51,6 +57,14 @@ AAC 기반의 MVVM 구조
- UI
- [Glide](https://github.com/bumptech/glide)
- [DarkTheme](https://developer.android.com/guide/topics/ui/look-and-feel/darktheme)
- [Material Design](https://github.com/material-components/material-components-android)

- Test
- [Unit Test](https://developer.android.com/training/testing/unit-testing/local-unit-tests.html?hl=ko)

- Firebase
- [Analytics](https://firebase.google.com/products/analytics)
- [Firestore](https://firebase.google.com/products/firestore)

- Serialization/Deserialization
- [Gson](https://github.com/google/gson)
7 changes: 7 additions & 0 deletions androidapp/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ dependencies {
// firebase
implementation deps.firebase.analytics
implementation deps.firebase.firestore
implementation deps.firebase.messaging

// Dagger
implementation deps.hilt.android
Expand All @@ -74,6 +75,11 @@ dependencies {
kapt deps.hilt.view_model_compiler

implementation deps.google.gson
implementation deps.google.flexbox

// Glide
implementation deps.glide.glide
kapt deps.glide.compiler

// debugging
implementation deps.debugging.timber
Expand All @@ -83,5 +89,6 @@ dependencies {
androidTestImplementation deps.atsl.ext_junit
androidTestImplementation deps.atsl.espresso_core
testImplementation deps.kotlin.coroutines.test

}
apply plugin: 'com.google.gms.google-services'
19 changes: 19 additions & 0 deletions androidapp/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_alarm" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/color_session_date" />

<service
android:name=".push.MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>

<activity android:name=".ui.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
298 changes: 296 additions & 2 deletions androidapp/app/src/main/assets/sessions.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.droidknights.app2020.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
Expand All @@ -15,28 +13,21 @@ import com.droidknights.app2020.BR
abstract class BaseFragment<VM : ViewModel, B : ViewDataBinding>(
@LayoutRes private val layoutResId: Int,
private val viewModelClass: Class<VM>
) : Fragment() {
) : Fragment(layoutResId) {

protected lateinit var viewModel: VM
protected val viewModel: VM by lazy {
ViewModelProvider(this).get(viewModelClass)
}

protected lateinit var binding: B
private lateinit var _binding: B

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(viewModelClass)
}
protected val binding: B get() = _binding

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, layoutResId, container, false)
return binding.root
}
private fun <T : ViewDataBinding> bind(view: View): T = DataBindingUtil.bind(view)!!

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = bind(view)
with(binding) {
setVariable(BR.vm, viewModel)
lifecycleOwner = viewLifecycleOwner
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
package com.droidknights.app2020.binding

import android.view.View
import android.webkit.WebView
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.droidknights.app2020.R
import com.droidknights.app2020.data.Speaker
import com.droidknights.app2020.data.Sponsor
import com.droidknights.app2020.data.Tag
import com.droidknights.app2020.ui.home.HomeAdapter
import com.droidknights.app2020.ui.home.HomeViewModel
import com.droidknights.app2020.ui.home.SponsorAdapter
import com.droidknights.app2020.ui.home.SponsorItemDecoration
import com.droidknights.app2020.ui.model.UiHomeModel
import com.droidknights.app2020.ui.schedule.TagAdapter
import com.droidknights.app2020.ui.schedule.detail.DetailTagAdapter
import com.droidknights.app2020.util.clearItemDecoration
import com.droidknights.app2020.widget.SessionChip
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager

@BindingAdapter(value = ["bindImgRes"])
fun ImageView.bindSetImage(resId: Int) = setImageResource(resId)
Expand All @@ -21,6 +45,93 @@ fun SwipeRefreshLayout.bindRefreshListener(onRefreshListener: SwipeRefreshLayout
@BindingAdapter("webUrl")
fun WebView.bindUrl(value: String?) = value?.let(::loadUrl)

@BindingAdapter("setColor")
fun SessionChip.setColor(@ColorInt color: Int) {
this.chipTextColor = color
this.strokeColor = color
this.chipBackgroundColor = when (color) {
ContextCompat.getColor(context, R.color.color_sessionChipText) -> ContextCompat.getColor(context, R.color.color_sessionChipText_white)
ContextCompat.getColor(context, R.color.color_sessionChipText_white) -> ContextCompat.getColor(context, R.color.color_sessionChipText)
else -> lighten(color, 30)
}
}

@BindingAdapter("setData")
fun RecyclerView.setData(items: List<Tag>?) {
FlexboxLayoutManager(context).apply {
flexWrap = FlexWrap.WRAP
flexDirection = FlexDirection.ROW
}.let {
this.layoutManager = it
}
this.adapter = TagAdapter()
(this.adapter as TagAdapter).run {
submitList(items)
}
}

@BindingAdapter("speakerName")
fun TextView.bindSpeakerName(value: Speaker?) {
text = value?.name
}

@BindingAdapter("speakerImage")
fun ImageView.bindProfile(speaker: Speaker?) {
Glide.with(this)
.load(speaker?.profileImage)
.apply(
RequestOptions()
.placeholder(R.drawable.img_droid_space)
.circleCrop()
).into(this)
}

@BindingAdapter("sessionTags")
fun RecyclerView.bindSessionTags(tags: List<String>?) {
if (tags?.isNotEmpty() == true) {
isVisible = true
adapter = (adapter as? DetailTagAdapter ?: DetailTagAdapter()).apply {
this.tags = tags
}
} else {
isGone = true
}
}

@BindingAdapter("homeVm", "homeItems")
fun RecyclerView.bindHome(vm: HomeViewModel, items: List<UiHomeModel>?) {
if (items?.isNotEmpty() == true) {
isVisible = true
adapter = HomeAdapter(vm, items)
} else {
isGone = true
}
}

@BindingAdapter("sponsors")
fun RecyclerView.bindSponsors(items: List<Sponsor>?) {
if (items?.isNotEmpty() == true) {
isVisible = true
adapter = SponsorAdapter(items)
clearItemDecoration()
addItemDecoration(SponsorItemDecoration())
} else {
isGone = true
}
}

@BindingAdapter("sponsorLogo")
fun ImageView.bindSponsorLogo(@DrawableRes imageResId: Int?) {
Glide.with(this)
.load(imageResId)
.into(this)
}

@BindingAdapter("isActiveEvent")
fun ImageView.isActiveEvent(_isActivated: Boolean?) {
this.isActivated = _isActivated ?: false
}

@BindingAdapter(value = ["onAir"])
fun setOnAir(imageView: ImageView, onAir: Boolean) {
if (onAir) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.droidknights.app2020.common

import android.content.Context
import com.google.gson.Gson
import timber.log.Timber


inline fun <reified ENTITY> Context.loadJson(gson: Gson, fileName: String): ENTITY {
val result = assets.open(fileName)
.bufferedReader()
.use { it.readText() }

return gson.fromJson(result, ENTITY::class.java)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModel
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter

abstract class DataBindingAdapter<T>(diffCallback: DiffUtil.ItemCallback<T>) :
abstract class DataBindingAdapter<T>(diffCallback: DiffUtil.ItemCallback<T>, private val viewModel: ViewModel) :
ListAdapter<T, DataBindingViewHolder<T>>(diffCallback) {

interface ItemClickListener {
fun onClickItem(sessionId: String)
}

abstract var itemClickListener : ItemClickListener?

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBindingViewHolder<T> {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = DataBindingUtil.inflate<ViewDataBinding>(layoutInflater, viewType, parent, false)
return DataBindingViewHolder(binding)
return DataBindingViewHolder(binding, viewModel)
}

override fun onBindViewHolder(holder: DataBindingViewHolder<T>, position: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package com.droidknights.app2020.common

import androidx.databinding.ViewDataBinding
import androidx.databinding.library.baseAdapters.BR
import androidx.lifecycle.ViewModel
import androidx.recyclerview.widget.RecyclerView

class DataBindingViewHolder<T>(private val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {
class DataBindingViewHolder<T>(val binding: ViewDataBinding, private val viewModel: ViewModel) : RecyclerView.ViewHolder(binding.root) {

fun bind(item: T) {
binding.setVariable(BR.item, item)
binding.setVariable(BR.viewModel, viewModel)
binding.executePendingBindings()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.droidknights.app2020.data

data class EventHistory(
val year: Int,
val date: String,
val url: String,
val isActive: Boolean = false
)
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package com.droidknights.app2020.data

data class Session(
var id: String = "",
var track: Int = 0,
var title: String = "",
var tag: List<String>? = emptyList(),
var time: String = "",
var contents: String? = "",
var speakerName: String? = "",
var speakerDesc: String? = "",
var speakerProfile: String? = "",
val id: String = "",
val track: Int = 0,
val title: String = "",
val tag: List<String>? = emptyList(),
val time: String = "",
val contents: String? = "",
val speakerName: String? = "",
val videoLink: String? = "",
val qnaLink: String? = "",
val speaker: List<Speaker>? = null,
var isLive:Boolean = false
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.droidknights.app2020.data

data class Speaker(
val id: String,
val name: String,
val profileUrl: String,
val description: String
val profileImage: String,
val introduce: String,
val belong: String?
)
Loading

0 comments on commit e3ee830

Please sign in to comment.