()
24 |
25 | for (user: User in userListModel.items) {
26 | itemPresentationList.add(toPresentation(user))
27 | }
28 |
29 | return UserListModelPresentation(itemPresentationList)
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mapper/base/PresentationLayerMapper.java:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mapper.base;
2 |
3 |
4 | import info.sanaebadi.domain.model.base.BaseDomainModel;
5 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel;
6 |
7 | public interface PresentationLayerMapper {
8 |
9 | D toDomain(P p);
10 |
11 | P toPresentation(D d);
12 |
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/base/AdapterConstants.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.base
2 |
3 | object AdapterConstants {
4 | const val USER_DETAILS = 1
5 | const val HEADING = 2
6 | const val QUESTION = 3
7 | const val ANSWER = 4
8 | const val LOADING = 5
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/base/PresentationModel.java:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.base;
2 |
3 | public interface PresentationModel {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/AnswerListPresentation.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel
4 |
5 | class AnswerListPresentation(val items: List) : PresentationModel
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/AnswerPresentation.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel
4 |
5 | data class AnswerPresentation(
6 | var answerId: Long,
7 | var questionId: Long,
8 | var score: Long,
9 | var accepted: Boolean,
10 | var ownerEntity: OwnerPresentation
11 | ) : PresentationModel {
12 |
13 | constructor() : this(-1, -1, 0, false, OwnerPresentation())
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/FavoriteByUserPresentation.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel
4 |
5 | data class FavoriteByUserPresentation(
6 | var userId: Long,
7 | var questionIds: List
8 | ): PresentationModel {
9 |
10 | constructor() : this(-1, emptyList())
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/Heading.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import info.sanaebadi.domain.model.base.ViewType
4 | import info.sanaebadi.stackoverflowproject.model.base.AdapterConstants
5 |
6 | data class Heading(val title: String) : ViewType {
7 | override fun getViewType() = AdapterConstants.HEADING
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/OwnerPresentation.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel
4 |
5 |
6 | data class OwnerPresentation(var userId: Long) : PresentationModel {
7 |
8 | constructor() : this(-1)
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/QuestionListPresentation.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel
4 |
5 | class QuestionListPresentation(val items: List) : PresentationModel
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/QuestionPresentation.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel
4 |
5 |
6 | data class QuestionPresentation(
7 | var viewCount: Long,
8 | var score: Long,
9 | var title: String,
10 | var link: String,
11 | var questionId: Long,
12 | var ownerEntity: OwnerPresentation
13 | ) : PresentationModel {
14 |
15 |
16 | constructor() : this(0, 0, "", "", -1, OwnerPresentation())
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/UserListModelPresentation.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel
4 |
5 |
6 | class UserListModelPresentation(val items: MutableList) : PresentationModel
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/model/user/UserPresentation.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.model.user
2 |
3 | import android.os.Parcel
4 | import android.os.Parcelable
5 | import info.sanaebadi.domain.model.base.ViewType
6 | import info.sanaebadi.stackoverflowproject.model.base.AdapterConstants
7 | import info.sanaebadi.stackoverflowproject.model.base.PresentationModel
8 |
9 |
10 | data class UserPresentation(
11 | var userId: Long,
12 | var displayName: String,
13 | var reputation: Long,
14 | var profileImage: String
15 | ) : PresentationModel , Parcelable , ViewType {
16 |
17 | constructor(parcel: Parcel) : this(
18 | parcel.readLong(),
19 | parcel.readString()!!,
20 | parcel.readLong(),
21 | parcel.readString()!!
22 | ) {
23 | }
24 |
25 | constructor() : this(-1, "", 0, "")
26 |
27 | override fun writeToParcel(parcel: Parcel, flags: Int) {
28 | parcel.writeLong(userId)
29 | parcel.writeString(displayName)
30 | parcel.writeLong(reputation)
31 | parcel.writeString(profileImage)
32 | }
33 |
34 | override fun describeContents(): Int {
35 | return 0
36 | }
37 |
38 | companion object CREATOR : Parcelable.Creator {
39 | override fun createFromParcel(parcel: Parcel): UserPresentation {
40 | return UserPresentation(parcel)
41 | }
42 |
43 | override fun newArray(size: Int): Array {
44 | return arrayOfNulls(size)
45 | }
46 | }
47 |
48 | override fun getViewType(): Int = AdapterConstants.USER_DETAILS
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/adapter/DetailsAdapter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.adapter
2 |
3 | import android.view.ViewGroup
4 | import androidx.collection.SparseArrayCompat
5 | import androidx.recyclerview.widget.RecyclerView
6 | import info.sanaebadi.domain.model.base.ViewType
7 | import info.sanaebadi.stackoverflowproject.model.base.AdapterConstants
8 | import info.sanaebadi.stackoverflowproject.model.user.Heading
9 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate.*
10 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate.base.ViewTypeDelegateAdapter
11 |
12 | class DetailsAdapter(listener: (String) -> Unit) : RecyclerView.Adapter() {
13 |
14 | private var items: MutableList = ArrayList()
15 | private var delegateAdapters = SparseArrayCompat()
16 |
17 | private val loadingItem = object : ViewType {
18 | override fun getViewType() = AdapterConstants.LOADING
19 | }
20 |
21 | init {
22 | delegateAdapters.put(AdapterConstants.USER_DETAILS, UserDetailsDelegateAdapter())
23 | delegateAdapters.put(AdapterConstants.HEADING, HeadingDelegateAdapter())
24 | delegateAdapters.put(AdapterConstants.QUESTION, QuestionDelegateAdapter(listener))
25 | delegateAdapters.put(AdapterConstants.ANSWER, AnswerDelegateAdapter(listener))
26 | delegateAdapters.put(AdapterConstants.LOADING, LoadingDelegateAdapter())
27 | }
28 |
29 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
30 | delegateAdapters[viewType]!!.onCreateViewHolder(parent)
31 |
32 | override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =
33 | delegateAdapters[getItemViewType(position)]!!.onBindViewHolder(holder, items[position])
34 |
35 | override fun getItemCount(): Int = items.size
36 |
37 | override fun getItemViewType(position: Int): Int {
38 | return items[position].getViewType()
39 | }
40 |
41 | private fun addItems(newItems: List) {
42 | items.addAll(newItems)
43 | }
44 |
45 | fun addItem(item: ViewType) {
46 | items.add(item)
47 | }
48 |
49 | fun addLoadingItem() {
50 | items.add(loadingItem)
51 | }
52 |
53 | fun removeLoadingItem() {
54 | items.remove(loadingItem)
55 | }
56 |
57 | fun removeNonUserItems() {
58 | items.removeAll { it.getViewType() != AdapterConstants.USER_DETAILS }
59 | }
60 |
61 | fun addItemsWithHeading(items: List, headingTitle: String) {
62 | if (!items.isEmpty()) {
63 | addItem(Heading(headingTitle))
64 | addItems(items)
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/adapter/UserListAdapter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.adapter
2 |
3 | import android.annotation.SuppressLint
4 | import android.view.LayoutInflater
5 | import android.view.ViewGroup
6 | import androidx.recyclerview.widget.RecyclerView
7 | import info.sanaebadi.stackoverflowproject.databinding.ListItemUserBinding
8 | import info.sanaebadi.stackoverflowproject.model.user.UserPresentation
9 | import info.sanaebadi.stackoverflowproject.util.isLollipopOrAbove
10 | import info.sanaebadi.stackoverflowproject.util.loadUrl
11 | import info.sanaebadi.stackoverflowproject.util.mOnItemClickListener
12 |
13 | class UserListAdapter(
14 | val listener: mOnItemClickListener,
15 | private val users: MutableList
16 | ) : RecyclerView.Adapter() {
17 |
18 |
19 | override fun getItemCount() = users.size
20 |
21 | override fun onBindViewHolder(holder: UserViewHolder, position: Int) =
22 | holder.bind(users[position])
23 |
24 |
25 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
26 | val binding =
27 | ListItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
28 | return UserViewHolder(binding)
29 |
30 | }
31 |
32 | fun addUsers(newUsers: List) {
33 | users.addAll(newUsers)
34 | notifyDataSetChanged()
35 | }
36 |
37 | fun clearUsers() {
38 | users.clear()
39 | }
40 |
41 | inner class UserViewHolder(private val binding: ListItemUserBinding) :
42 | RecyclerView.ViewHolder(binding.root) {
43 | @SuppressLint("NewApi", "SetTextI18n")
44 | fun bind(user: UserPresentation) =
45 | with(itemView) {
46 |
47 | binding.textUserName.text = user.displayName
48 | binding.textUserReputation.text = "${user.reputation} points"
49 | binding.imageUserAvatar.loadUrl(user.profileImage)
50 |
51 | setOnClickListener {
52 | listener.onItemClick(user, binding.imageUserAvatar)
53 | }
54 |
55 | isLollipopOrAbove {
56 | binding.imageUserAvatar.transitionName = "transition${user.userId}"
57 | }
58 |
59 | }
60 |
61 | }
62 |
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/delegate/AnswerDelegateAdapter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import info.sanaebadi.domain.model.base.ViewType
7 | import info.sanaebadi.domain.model.details.AnswerViewModel
8 | import info.sanaebadi.stackoverflowproject.databinding.ListItemAnswerBinding
9 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate.base.ViewTypeDelegateAdapter
10 |
11 | class AnswerDelegateAdapter(private val listener: (String) -> Unit) : ViewTypeDelegateAdapter {
12 | override fun onCreateViewHolder(parent: ViewGroup) =
13 | AnswerViewHolder(
14 | ListItemAnswerBinding.inflate(
15 | LayoutInflater.from(parent.context),
16 | parent,
17 | false
18 | )
19 | )
20 |
21 | override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) {
22 | holder as AnswerViewHolder
23 | holder.bind(item as AnswerViewModel, listener)
24 | }
25 |
26 | class AnswerViewHolder(private val binding: ListItemAnswerBinding) :
27 | RecyclerView.ViewHolder(binding.root) {
28 | fun bind(answer: AnswerViewModel, listener: (String) -> Unit) = with(itemView) {
29 | binding.score.text = "${answer.score} points"
30 | binding.questionTitle.text = answer.questionTitle
31 |
32 | setOnClickListener { listener("https://stackoverflow.com/a/${answer.answerId}") }
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/delegate/HeadingDelegateAdapter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import info.sanaebadi.domain.model.base.ViewType
7 | import info.sanaebadi.stackoverflowproject.databinding.ListItemHeadingBinding
8 | import info.sanaebadi.stackoverflowproject.model.user.Heading
9 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate.base.ViewTypeDelegateAdapter
10 |
11 | class HeadingDelegateAdapter : ViewTypeDelegateAdapter {
12 | override fun onCreateViewHolder(parent: ViewGroup) =
13 | HeadingViewHolder(
14 | ListItemHeadingBinding.inflate(
15 | LayoutInflater.from(parent.context),
16 | parent,
17 | false
18 | )
19 | )
20 |
21 | override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) {
22 | holder as HeadingViewHolder
23 | holder.bind(item as Heading)
24 | }
25 |
26 | class HeadingViewHolder(private val binding: ListItemHeadingBinding) :
27 | RecyclerView.ViewHolder(binding.root) {
28 | fun bind(heading: Heading) = with(itemView) {
29 | binding.title.text = heading.title
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/delegate/LoadingDelegateAdapter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import info.sanaebadi.domain.model.base.ViewType
7 | import info.sanaebadi.stackoverflowproject.databinding.ListItemLoadingBinding
8 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate.base.ViewTypeDelegateAdapter
9 |
10 | class LoadingDelegateAdapter : ViewTypeDelegateAdapter {
11 | override fun onCreateViewHolder(parent: ViewGroup) =
12 | LoadingViewHolder(
13 | ListItemLoadingBinding.inflate(
14 | LayoutInflater.from(parent.context),
15 | parent,
16 | false
17 | )
18 | )
19 |
20 | override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) {
21 | }
22 |
23 | class LoadingViewHolder(private val binding: ListItemLoadingBinding) :
24 | RecyclerView.ViewHolder(binding.root)
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/delegate/QuestionDelegateAdapter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate
2 |
3 | import android.annotation.SuppressLint
4 | import android.view.LayoutInflater
5 | import android.view.ViewGroup
6 | import androidx.recyclerview.widget.RecyclerView
7 | import info.sanaebadi.domain.model.base.ViewType
8 | import info.sanaebadi.domain.model.details.QuestionViewModel
9 | import info.sanaebadi.stackoverflowproject.databinding.ListItemQuestionBinding
10 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate.base.ViewTypeDelegateAdapter
11 |
12 | class QuestionDelegateAdapter(private val listener: (String) -> Unit) : ViewTypeDelegateAdapter {
13 | override fun onCreateViewHolder(parent: ViewGroup) =
14 | QuestionViewHolder(
15 | ListItemQuestionBinding.inflate(
16 | LayoutInflater.from(parent.context),
17 | parent,
18 | false
19 | )
20 | )
21 |
22 | override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) {
23 | holder as QuestionViewHolder
24 | holder.bind(item as QuestionViewModel, listener)
25 | }
26 |
27 | class QuestionViewHolder(private val binding: ListItemQuestionBinding) :
28 | RecyclerView.ViewHolder(binding.root) {
29 | @SuppressLint("SetTextI18n")
30 | fun bind(question: QuestionViewModel, listener: (String) -> Unit) = with(itemView) {
31 | binding.title.text = question.title
32 | binding.score.text = "${question.score} points"
33 | binding.viewCount.text = "Viewed: ${question.viewCount}"
34 |
35 | setOnClickListener { listener(question.link) }
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/delegate/UserDetailsDelegateAdapter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate
2 |
3 | import android.annotation.SuppressLint
4 | import android.view.LayoutInflater
5 | import android.view.ViewGroup
6 | import androidx.recyclerview.widget.RecyclerView
7 | import info.sanaebadi.domain.model.base.ViewType
8 | import info.sanaebadi.domain.model.user.User
9 | import info.sanaebadi.stackoverflowproject.databinding.ListItemUserDetailsBinding
10 | import info.sanaebadi.stackoverflowproject.model.user.UserPresentation
11 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate.base.ViewTypeDelegateAdapter
12 | import info.sanaebadi.stackoverflowproject.util.isLollipopOrAbove
13 | import info.sanaebadi.stackoverflowproject.util.loadCircleImage
14 |
15 | class UserDetailsDelegateAdapter : ViewTypeDelegateAdapter {
16 |
17 | override fun onCreateViewHolder(parent: ViewGroup) =
18 | UserDetailsViewHolder(
19 | ListItemUserDetailsBinding.inflate(
20 | LayoutInflater.from(parent.context),
21 | parent,
22 | false
23 | )
24 | )
25 |
26 | override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) {
27 | holder as UserDetailsViewHolder
28 | holder.bind(item as UserPresentation)
29 | }
30 |
31 | class UserDetailsViewHolder(private val binding: ListItemUserDetailsBinding) :
32 | RecyclerView.ViewHolder(binding.root) {
33 | @SuppressLint("NewApi", "SetTextI18n")
34 | fun bind(user: UserPresentation) = with(itemView) {
35 | binding.profileImage.loadCircleImage(user.profileImage)
36 | binding.textName.text = user.displayName
37 | binding.textReputation.text = "${user.reputation} points"
38 |
39 | isLollipopOrAbove { binding.profileImage.transitionName = "transition${user.userId}" }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/delegate/base/ViewTypeDelegateAdapter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.delegate.base
2 |
3 | import android.view.ViewGroup
4 | import androidx.recyclerview.widget.RecyclerView
5 | import info.sanaebadi.domain.model.base.ViewType
6 |
7 | interface ViewTypeDelegateAdapter {
8 | fun onCreateViewHolder(parent: ViewGroup): RecyclerView.ViewHolder
9 | fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType)
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/viewModel/DetailsViewModel.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel
2 |
3 | import android.annotation.SuppressLint
4 | import info.sanaebadi.domain.interactor.user.DetailsUseCase
5 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel.base.BasePresenter
6 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel.base.DetailView
7 | import info.sanaebadi.stackoverflowproject.util.SchedulerProvider
8 | import javax.inject.Inject
9 |
10 | class DetailsViewModel @Inject constructor(
11 | private val detailsUseCase: DetailsUseCase,
12 | private val schedulerProvider: SchedulerProvider
13 | ) : BasePresenter() {
14 |
15 | @SuppressLint("CheckResult")
16 | fun getDetails(id: Long) {
17 | view?.showLoading()
18 | detailsUseCase.execute(id)
19 | .subscribeOn(schedulerProvider.ioScheduler())
20 | .observeOn(schedulerProvider.uiScheduler())
21 | .subscribe({ details ->
22 | view?.hideLoading()
23 | view?.showDetails(details)
24 | },
25 | { error ->
26 | view?.hideLoading()
27 | view?.showError(error.localizedMessage!!)
28 | })
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/viewModel/UserViewModel.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import info.sanaebadi.domain.interactor.base.BaseSingleObserver
6 | import info.sanaebadi.domain.interactor.user.UserUseCase
7 | import info.sanaebadi.domain.model.user.UserListModel
8 | import info.sanaebadi.stackoverflowproject.mapper.UserMapperPresentation
9 | import info.sanaebadi.stackoverflowproject.model.user.UserListModelPresentation
10 | import info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel.base.MutableViewModel
11 | import javax.inject.Inject
12 |
13 | private const val INFINITE_LOADING_OFFSET = 5
14 |
15 | class UserViewModel @Inject constructor(
16 | private val userUseCase: UserUseCase,
17 | private val mapper: UserMapperPresentation
18 | ) : ViewModel() {
19 |
20 | var userList = MutableLiveData>()
21 |
22 | fun getUserList(page: Int = 1) {
23 | val value = MutableViewModel()
24 | value.setLoading(true)
25 | userList.postValue(value)
26 |
27 | userUseCase.execute(object : BaseSingleObserver() {
28 | override fun onSuccess(t: UserListModel) {
29 | super.onSuccess(t)
30 | value.setLoading(false)
31 | value.setThrowable(null)
32 | value.setData(mapper.toPresentation(t))
33 | userList.postValue(value)
34 |
35 | }
36 |
37 | override fun onError(e: Throwable) {
38 | super.onError(e)
39 | value.setLoading(false)
40 | value.setThrowable(e)
41 | value.setData(null)
42 | userList.postValue(value)
43 |
44 | }
45 |
46 | }, page)
47 | }
48 |
49 | fun onScrollChanged(lastVisibleItemPosition: Int, totalItemCount: Int) {
50 | if (lastVisibleItemPosition >= totalItemCount - INFINITE_LOADING_OFFSET) {
51 | getUserList()
52 | }
53 |
54 | }
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/viewModel/base/BasePresenter.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel.base
2 |
3 | abstract class BasePresenter {
4 |
5 | var view: T? = null
6 | private set
7 |
8 | fun attachView(view: T) {
9 | this.view = view
10 | }
11 |
12 | fun detachView() {
13 | this.view = null
14 | }
15 |
16 | val isViewAttached: Boolean
17 | get() = view != null
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/viewModel/base/DetailView.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel.base
2 |
3 | import info.sanaebadi.domain.model.UserDetailsModel
4 |
5 |
6 | interface DetailView {
7 | fun showDetails(details: UserDetailsModel)
8 | fun showError(error: String)
9 | fun showLoading()
10 | fun hideLoading()
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/viewModel/base/MutableViewModel.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel.base
2 |
3 |
4 | open class MutableViewModel {
5 | private var loading = true
6 | private var data: T? = null
7 | private set
8 | private var throwable: Throwable? = null
9 |
10 | constructor(loading: Boolean, data: T?, throwable: Throwable?) {
11 | this.loading = loading
12 | this.data = data
13 | this.throwable = throwable
14 | }
15 |
16 | constructor() {}
17 |
18 | open fun isLoading(): Boolean {
19 | return loading
20 | }
21 |
22 | open fun setLoading(loading: Boolean) {
23 | this.loading = loading
24 | }
25 |
26 | fun setData(data: T?) {
27 | this.data = data
28 | }
29 |
30 | fun getData(): T? {
31 | return data
32 | }
33 |
34 | open fun getThrowable(): Throwable? {
35 | return throwable
36 | }
37 |
38 | open fun setThrowable(throwable: Throwable?) {
39 | this.throwable = throwable
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/viewModel/base/UserListView.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel.base
2 |
3 | import info.sanaebadi.stackoverflowproject.model.user.UserPresentation
4 |
5 | interface UserListView {
6 | fun showLoading()
7 | fun hideLoading()
8 | fun addUsersToList(users: List)
9 | fun showEmptyListError()
10 | fun hideEmptyListError()
11 | fun showToastError()
12 | fun clearList()
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/mvvm/feature/view/viewModel/base/ViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.mvvm.feature.view.viewModel.base
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import javax.inject.Inject
6 | import javax.inject.Provider
7 | import javax.inject.Singleton
8 |
9 | @Singleton
10 | class ViewModelFactory @Inject constructor(private val creators: MutableMap, @JvmSuppressWildcards Provider>) :
11 | ViewModelProvider.Factory {
12 | override fun create(modelClass: Class): T {
13 | var creator: Provider? = creators[modelClass]
14 | if (creator == null) {
15 | for ((key, value) in creators) {
16 | if (modelClass.isAssignableFrom(key)) {
17 | creator = value
18 | break
19 | }
20 | }
21 | }
22 | requireNotNull(creator) { "unknown model class $modelClass" }
23 | return try {
24 | creator.get() as T
25 | } catch (e: Exception) {
26 | throw RuntimeException(e)
27 | }
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/util/AppSchedulerProvider.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.util
2 |
3 | import io.reactivex.Scheduler
4 | import io.reactivex.android.schedulers.AndroidSchedulers
5 | import io.reactivex.schedulers.Schedulers
6 |
7 | class AppSchedulerProvider : SchedulerProvider {
8 | override fun ioScheduler() = Schedulers.io()
9 |
10 | override fun uiScheduler(): Scheduler = AndroidSchedulers.mainThread()
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/util/Constants.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.util
2 |
3 | object Constants {
4 | const val PLACE_APP_SHARED_PREF = "place_app_shared_pref"
5 | const val ADAPTER_POSITION = "adapter_position"
6 | const val ADAPTER_VIEW = "adapter_view"
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/util/Extensions.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.util
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Context.CONNECTIVITY_SERVICE
6 | import android.net.ConnectivityManager
7 | import android.os.Build
8 | import android.view.LayoutInflater
9 | import android.view.View
10 | import android.view.ViewGroup
11 | import android.widget.ImageView
12 | import androidx.fragment.app.Fragment
13 | import com.bumptech.glide.Glide
14 | import com.bumptech.glide.request.RequestOptions
15 | import info.sanaebadi.stackoverflowproject.R
16 | import info.sanaebadi.stackoverflowproject.global.StackApplication
17 |
18 | fun ViewGroup.inflate(layoutRes: Int): View {
19 | return LayoutInflater.from(context).inflate(layoutRes, this, false)
20 | }
21 |
22 | fun ImageView.loadUrl(url: String) {
23 | Glide.with(context).load(url).apply(RequestOptions().error(R.mipmap.ic_launcher)).into(this)
24 | }
25 |
26 | fun ImageView.loadCircleImage(url: String) {
27 | Glide.with(context).load(url).apply(
28 | RequestOptions.circleCropTransform()
29 | .error(R.mipmap.ic_launcher_round)
30 | ).into(this)
31 | }
32 |
33 | fun isLollipopOrAbove(func: () -> Unit) {
34 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
35 | func()
36 | }
37 | }
38 |
39 | val Activity.placeApplication: StackApplication
40 | get() = application as StackApplication
41 |
42 | val Fragment.placeApplication: StackApplication
43 | get() = activity?.application as StackApplication
44 |
45 | fun Context.isOnline() = (getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager?)
46 | ?.activeNetworkInfo?.isConnectedOrConnecting ?: false
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/util/PreferencesHelper.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.util
2 |
3 | import android.content.Context
4 | import info.sanaebadi.stackoverflowproject.util.Constants
5 |
6 | class PreferencesHelper(private val context: Context) {
7 |
8 | fun saveInt(key: String, value: Int) {
9 | val preferences =
10 | context.getSharedPreferences(Constants.PLACE_APP_SHARED_PREF, Context.MODE_PRIVATE)
11 | val editor = preferences.edit()
12 | editor.putInt(key, value)
13 | editor.apply()
14 | }
15 |
16 | fun loadInt(key: String): Int? {
17 | val preferences =
18 | context.getSharedPreferences(Constants.PLACE_APP_SHARED_PREF, Context.MODE_PRIVATE)
19 | return preferences.getInt(key, 0)
20 | }
21 |
22 | fun saveString(key: String, value: String) {
23 | val preferences =
24 | context.getSharedPreferences(Constants.PLACE_APP_SHARED_PREF, Context.MODE_PRIVATE)
25 | val editor = preferences.edit()
26 | editor.putString(key, value)
27 | editor.apply()
28 | }
29 |
30 | fun loadString(key: String): String? {
31 | val preferences =
32 | context.getSharedPreferences(Constants.PLACE_APP_SHARED_PREF, Context.MODE_PRIVATE)
33 | return preferences.getString(key, null)
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/util/SchedulerProvider.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.util
2 |
3 | import io.reactivex.Scheduler
4 |
5 | interface SchedulerProvider {
6 | fun uiScheduler(): Scheduler
7 | fun ioScheduler(): Scheduler
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/util/TransitionListener.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.util
2 |
3 | import android.annotation.SuppressLint
4 | import android.transition.Transition
5 |
6 | @SuppressLint("NewApi")
7 | open class TransitionListener : Transition.TransitionListener {
8 | override fun onTransitionEnd(p0: Transition?) {
9 | }
10 |
11 | override fun onTransitionResume(p0: Transition?) {
12 | }
13 |
14 | override fun onTransitionPause(p0: Transition?) {
15 | }
16 |
17 | override fun onTransitionCancel(p0: Transition?) {
18 | }
19 |
20 | override fun onTransitionStart(p0: Transition?) {
21 | }
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/info/sanaebadi/stackoverflowproject/util/mOnItemClickListener.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject.util
2 |
3 | import android.view.View
4 | import info.sanaebadi.stackoverflowproject.model.user.UserPresentation
5 |
6 | interface mOnItemClickListener {
7 | fun onItemClick(userViewModel: UserPresentation, view: View)
8 | }
--------------------------------------------------------------------------------
/app/src/main/res/StackOverFlowProject.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/StackOverFlowProject.zip
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_error.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/font/font_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/font/font_bold.ttf
--------------------------------------------------------------------------------
/app/src/main/res/font/font_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/font/font_regular.ttf
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_user_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
17 |
18 |
23 |
24 |
25 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_answer.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
22 |
23 |
35 |
36 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_heading.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_question.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
22 |
23 |
36 |
37 |
50 |
51 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
33 |
34 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_user_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
33 |
34 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/navigation/nav_graph.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
16 |
17 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/transition/shared_element_transition.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #455a64
4 | #718792
5 | #1c313a
6 | #bf360c
7 | #f9683a
8 | #870000
9 | #ffffff
10 | #ECEAEA
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2dp
5 | 4dp
6 | 8dp
7 | 12dp
8 | 16dp
9 | 20dp
10 | 24dp
11 | 32dp
12 | 48dp
13 | 64dp
14 |
15 |
16 | 8sp
17 | 10sp
18 | 12sp
19 | 14sp
20 | 16sp
21 | 18sp
22 | 20sp
23 | 20sp
24 | 24sp
25 | 28sp
26 | 64dp
27 | 128dp
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Stack Over Flow
3 |
4 | Hello blank fragment
5 |
6 | Failed to load data. Refresh to try again
7 | Error loading data
8 |
9 | Error to Connect to the Server ! Please check your Network
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/test/java/info/sanaebadi/stackoverflowproject/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.stackoverflowproject
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath (BuildPlugins.androidGradlePlugin)
11 | classpath (BuildPlugins.kotlinGradlePlugin)
12 | classpath (BuildPlugins.safeArgsPlugin)
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 |
23 | }
24 | }
25 |
26 | tasks.register("clean").configure {
27 | delete("build")
28 | }
--------------------------------------------------------------------------------
/buildSrc/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2 |
3 | repositories {
4 | jcenter()
5 | }
6 |
7 | plugins {
8 | `kotlin-dsl`
9 | kotlin("jvm") version "1.4.10"
10 | }
11 |
12 | kotlinDslPluginOptions {
13 | experimentalWarning.set(false)
14 | }
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/AndroidSdk.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/AndroidSdk.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/BuildPlugins$Versions.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/BuildPlugins$Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/BuildPlugins.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/BuildPlugins.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/DaggerLib$Versions.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/DaggerLib$Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/DaggerLib.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/DaggerLib.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Dependencies_Kt.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/Dependencies_Kt.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/JetPackLibraries$Versions.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/JetPackLibraries$Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/JetPackLibraries.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/JetPackLibraries.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Libraries$Versions.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/Libraries$Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Libraries.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/Libraries.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/META-INF/buildSrc.kotlin_module:
--------------------------------------------------------------------------------
1 |
2 |
3 | Dependencies_Kt" *
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Networking$Versions.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/Networking$Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Networking.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/Networking.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/RXLibraries$Versions.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/RXLibraries$Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/RXLibraries.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/RXLibraries.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/TestLibraries$Versions.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/TestLibraries$Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/TestLibraries.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/classes/kotlin/main/TestLibraries.class
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/buildSrcjar-classes.txt:
--------------------------------------------------------------------------------
1 | /home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/AndroidSdk.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/BuildPlugins$Versions.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/BuildPlugins.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/DaggerLib$Versions.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/DaggerLib.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/Dependencies_Kt.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/JetPackLibraries$Versions.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/JetPackLibraries.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/Libraries$Versions.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/Libraries.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/Networking$Versions.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/Networking.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/RXLibraries$Versions.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/RXLibraries.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/TestLibraries$Versions.class:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main/TestLibraries.class
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/build-history.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/build-history.bin
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.keystream:
--------------------------------------------------------------------------------
1 | j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.keystream.len:
--------------------------------------------------------------------------------
1 | k
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.values.at:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.values.at
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream:
--------------------------------------------------------------------------------
1 | BuildPluginsBuildPlugins.Versions
2 | AndroidSdk LibrariesLibraries.VersionsJetPackLibrariesJetPackLibraries.Versions
TestLibrariesTestLibraries.Versions
3 | NetworkingNetworking.VersionsRXLibrariesRXLibraries.Versions DaggerLibDaggerLib.Versions
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStoragek j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.keystream:
--------------------------------------------------------------------------------
1 | BuildPluginsBuildPlugins$Versions
2 | AndroidSdk LibrariesLibraries$VersionsJetPackLibrariesJetPackLibraries$Versions
TestLibrariesTestLibraries$Versions
3 | NetworkingNetworking$VersionsRXLibrariesRXLibraries$Versions DaggerLibDaggerLib$VersionsDependencies_Kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.keystream.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.values.at:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.values.at
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStoragek j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab.keystream:
--------------------------------------------------------------------------------
1 | Dependencies_Kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorage
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/package-parts.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.keystream:
--------------------------------------------------------------------------------
1 | BuildPluginsBuildPlugins$Versions
2 | AndroidSdk LibrariesLibraries$VersionsJetPackLibrariesJetPackLibraries$Versions
TestLibrariesTestLibraries$Versions
3 | NetworkingNetworking$VersionsRXLibrariesRXLibraries$Versions DaggerLibDaggerLib$VersionsDependencies_Kt.kotlin_module
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.keystream.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.values.at:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.values.at
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream:
--------------------------------------------------------------------------------
1 | j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len:
--------------------------------------------------------------------------------
1 | k
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/counters.tab:
--------------------------------------------------------------------------------
1 | 2
2 | 1
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.keystream:
--------------------------------------------------------------------------------
1 | j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.keystream.len:
--------------------------------------------------------------------------------
1 | k
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorage
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.keystream:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.keystream.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStoragek j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..ktk j/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/src/main/java/Dependencies..kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.keystream:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.keystream
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.keystream.len:
--------------------------------------------------------------------------------
1 | (
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorage
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/last-build.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/kotlin/compileKotlin/last-build.bin
--------------------------------------------------------------------------------
/buildSrc/build/libs/buildSrc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/libs/buildSrc.jar
--------------------------------------------------------------------------------
/buildSrc/build/pluginUnderTestMetadata/plugin-under-test-metadata.properties:
--------------------------------------------------------------------------------
1 | implementation-classpath=/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/java/main\:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/groovy/main\:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/classes/kotlin/main\:/home/sanaebadi/Pasport/and_dev/workplace/Github/StackOverFlowApii/buildSrc/build/resources/main
2 |
--------------------------------------------------------------------------------
/buildSrc/build/reports/plugin-development/validation-report.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/buildSrc/build/reports/plugin-development/validation-report.txt
--------------------------------------------------------------------------------
/buildSrc/build/tmp/jar/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 |
3 |
--------------------------------------------------------------------------------
/data/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/data/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id(BuildPlugins.androidLibrary)
3 | id(BuildPlugins.kotlinAndroid)
4 | id(BuildPlugins.kotlinAndroidExtensions)
5 | id(BuildPlugins.kaptPlugin)
6 |
7 | }
8 | android {
9 | compileSdkVersion(AndroidSdk.compileSdk)
10 | defaultConfig {
11 | minSdkVersion(AndroidSdk.minSdk)
12 | targetSdkVersion(AndroidSdk.targetSdk)
13 | versionCode = 1
14 | versionName = "1.0"
15 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
16 | consumerProguardFiles("consumer-rules.pro")
17 | }
18 |
19 | buildTypes {
20 | getByName("release") {
21 | isMinifyEnabled = false
22 | proguardFiles(
23 | getDefaultProguardFile("proguard-android-optimize.txt"),
24 | "proguard-rules.pro"
25 | )
26 | }
27 | }
28 |
29 | flavorDimensions("PlaceApp")
30 | productFlavors {
31 | create("tapsi") {
32 | setDimension("PlaceApp")
33 | buildConfigField("String", "API_BASE_URL", "\"https://api.stackexchange.com/2.2/\"")
34 | }
35 |
36 | }
37 |
38 | compileOptions {
39 | sourceCompatibility = JavaVersion.VERSION_1_8
40 | targetCompatibility = JavaVersion.VERSION_1_8
41 | }
42 | // For Kotlin projects
43 | kotlinOptions {
44 | jvmTarget = "1.8"
45 | }
46 |
47 | }
48 |
49 |
50 | dependencies {
51 | implementation(project(mapOf("path" to ":domain")))
52 |
53 | implementation(Libraries.kotlinStdLib)
54 | implementation(Libraries.ktxCore)
55 |
56 | implementation(DaggerLib.dagger)
57 | implementation(DaggerLib.daggerSupport)
58 | kapt(DaggerLib.daggerCompiler)
59 | kapt(DaggerLib.daggerProcessor)
60 |
61 | implementation(Networking.retrofit)
62 | implementation(Networking.rxRetrofitAdapter)
63 | implementation(Networking.converterScalars)
64 | implementation(Networking.converterMoshi)
65 | api(Networking.moshi)
66 | kapt(Networking.moshiKotlin)
67 |
68 | implementation(RXLibraries.rxAndroid)
69 | implementation(RXLibraries.rxJava)
70 |
71 | testImplementation(TestLibraries.junit4)
72 | androidTestImplementation(TestLibraries.testRunner)
73 | androidTestImplementation(TestLibraries.espresso)
74 | testImplementation(TestLibraries.mockitoKotlin)
75 |
76 | implementation("com.squareup.okhttp3:logging-interceptor:4.8.1")
77 |
78 | }
--------------------------------------------------------------------------------
/data/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/data/consumer-rules.pro
--------------------------------------------------------------------------------
/data/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/data/src/androidTest/java/info/sanaebadi/data/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.data
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("info.sanaebadi.data.test", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/data/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/cache/base/BaseCache.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.cache.base
2 |
3 | import io.reactivex.Completable
4 | import io.reactivex.Maybe
5 |
6 | interface BaseCache {
7 |
8 | fun saveData(item: T)
9 | fun getData(key: String): Maybe
10 | fun isCached(key: String): Boolean
11 | fun deleteCache(): Completable
12 |
13 |
14 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/base/BaseEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.data.entity.base
2 |
3 | interface BaseEntity
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/base/ListBaseEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.base
2 |
3 | import info.sanaebadi.data.entity.base.BaseEntity
4 |
5 |
6 | abstract class ListBaseEntity : BaseEntity {
7 |
8 | open var list: List = emptyList()
9 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/base/Table.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.base
2 |
3 | interface Table
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/user/AnswerEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.user
2 |
3 | import com.squareup.moshi.Json
4 | import com.squareup.moshi.JsonClass
5 | import info.sanaebadi.data.entity.base.BaseEntity
6 |
7 | @JsonClass(generateAdapter = true)
8 | data class AnswerEntity(
9 | @field:Json(name = "answer_id") var answerId: Long,
10 | @field:Json(name = "question_id") var questionId: Long,
11 | @field:Json(name = "score") var score: Long,
12 | @field:Json(name = "is_accepted") var accepted: Boolean,
13 | @field:Json(name = "owner") var ownerEntity: OwnerEntity
14 | ) :BaseEntity{
15 |
16 | constructor() : this(-1, -1, 0, false, OwnerEntity())
17 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/user/AnswerListEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.user
2 |
3 | import com.squareup.moshi.JsonClass
4 |
5 |
6 | @JsonClass(generateAdapter = true)
7 | class AnswerListEntity(val items: List)
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/user/FavoritedByUserEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.user
2 |
3 | import com.squareup.moshi.JsonClass
4 | import info.sanaebadi.data.entity.base.BaseEntity
5 |
6 | @JsonClass(generateAdapter = true)
7 | data class FavoritedByUserEntity(
8 | var userId: Long,
9 | var questionIds: List
10 | ): BaseEntity {
11 |
12 | constructor() : this(-1, emptyList())
13 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/user/OwnerEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.user
2 |
3 | import com.squareup.moshi.Json
4 | import com.squareup.moshi.JsonClass
5 | import info.sanaebadi.data.entity.base.BaseEntity
6 |
7 | @JsonClass(generateAdapter = true)
8 | data class OwnerEntity(@field:Json(name ="user_id") var userId: Long) : BaseEntity {
9 |
10 | constructor() : this(-1)
11 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/user/QuestionEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.user
2 |
3 | import com.squareup.moshi.Json
4 | import com.squareup.moshi.JsonClass
5 | import info.sanaebadi.data.entity.base.BaseEntity
6 |
7 | @JsonClass(generateAdapter = true)
8 | data class QuestionEntity(
9 | @field:Json(name ="view_count") var viewCount: Long,
10 | @field:Json(name ="score") var score: Long,
11 | @field:Json(name ="title") var title: String,
12 | @field:Json(name ="link") var link: String,
13 | @field:Json(name ="question_id") var questionId: Long,
14 | @field:Json(name ="owner") var ownerEntity: OwnerEntity
15 | ): BaseEntity {
16 |
17 | constructor() : this(0, 0, "", "", -1, OwnerEntity())
18 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/user/QuestionListEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.user
2 |
3 | import com.squareup.moshi.JsonClass
4 | import info.sanaebadi.data.entity.base.BaseEntity
5 |
6 | @JsonClass(generateAdapter = true)
7 | class QuestionListEntity(val items: List): BaseEntity
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/user/UserEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.user
2 |
3 | import com.squareup.moshi.Json
4 | import com.squareup.moshi.JsonClass
5 | import info.sanaebadi.data.entity.base.BaseEntity
6 |
7 | @JsonClass(generateAdapter = true)
8 | data class UserEntity(
9 | @field:Json(name ="user_id") var userId: Long,
10 | @field:Json(name ="display_name") var displayName: String,
11 | @field:Json(name ="reputation") var reputation: Long,
12 | @field:Json(name ="profile_image") var profileImage: String
13 | ):BaseEntity {
14 |
15 | constructor() : this(-1, "", 0, "")
16 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/entity/user/UserListModelEntity.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.entity.user
2 |
3 | import com.squareup.moshi.JsonClass
4 | import info.sanaebadi.data.entity.base.BaseEntity
5 |
6 | @JsonClass(generateAdapter = true)
7 | class UserListModelEntity(val items: List) : BaseEntity
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/exception/DataException.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.exception
2 |
3 | class DataException(val code: String, override val message: String) : Exception()
4 |
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/exception/NoDataException.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.exception
2 |
3 | class NoDataException : Exception()
4 |
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/executor/JobExecutor.kt:
--------------------------------------------------------------------------------
1 |
2 | package info.sanaebadi.executor
3 |
4 |
5 | import info.sanaebadi.domain.executor.ThreadExecutor
6 | import javax.inject.Inject
7 | import javax.inject.Singleton
8 | import java.util.concurrent.LinkedBlockingQueue
9 | import java.util.concurrent.ThreadFactory
10 | import java.util.concurrent.ThreadPoolExecutor
11 | import java.util.concurrent.TimeUnit
12 |
13 |
14 | /**
15 | * Decorated [ThreadPoolExecutor]
16 | */
17 | @Singleton
18 | class JobExecutor @Inject
19 | constructor() : ThreadExecutor {
20 |
21 | private val threadPoolExecutor: ThreadPoolExecutor
22 |
23 | init {
24 | this.threadPoolExecutor = ThreadPoolExecutor(
25 | 5, 15, 15, TimeUnit.SECONDS,
26 | LinkedBlockingQueue(), JobThreadFactory()
27 | )
28 |
29 |
30 | }
31 |
32 | override fun execute(runnable: Runnable) {
33 | this.threadPoolExecutor.execute(runnable)
34 | }
35 |
36 | private inner class JobThreadFactory : ThreadFactory {
37 | private var counter = 0
38 |
39 | override fun newThread(runnable: Runnable): Thread {
40 | return Thread(runnable, "android_" + counter++)
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/mapper/base/DataLayerMapper.java:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.mapper.base;
2 |
3 |
4 | import info.sanaebadi.data.entity.base.BaseEntity;
5 | import info.sanaebadi.domain.model.base.BaseDomainModel;
6 |
7 | public interface DataLayerMapper {
8 |
9 | D toDomain(E e);
10 |
11 | E toEntity(D d);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/mapper/details/AnswersByUserMapper.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.mapper.details
2 |
3 | import info.sanaebadi.domain.model.user.Answer
4 | import info.sanaebadi.domain.model.user.AnswerList
5 | import info.sanaebadi.domain.model.user.Owner
6 | import info.sanaebadi.entity.user.AnswerEntity
7 | import info.sanaebadi.entity.user.AnswerListEntity
8 | import info.sanaebadi.mapper.base.DataLayerMapper
9 | import java.util.*
10 | import javax.inject.Inject
11 | import javax.inject.Singleton
12 |
13 | @Singleton
14 | class AnswersByUserMapper @Inject constructor() : DataLayerMapper {
15 |
16 | fun toDomain(answerListEntity: AnswerListEntity): List? {
17 | val answerList: MutableList = ArrayList()
18 |
19 | for (answer: AnswerEntity in answerListEntity.items) {
20 | answerList.add(toDomain(answer))
21 | }
22 | return answerList
23 | }
24 |
25 | override fun toDomain(e: AnswerEntity?): Answer {
26 |
27 | val owner = e?.ownerEntity?.userId?.let { Owner(it) }
28 |
29 | return Answer(e?.answerId!!, e.questionId, e.score, e.accepted, owner!!)
30 | }
31 |
32 | override fun toEntity(d: Answer?): AnswerEntity? {
33 | return null
34 | }
35 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/mapper/details/FavoritesByUserMapper.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.mapper.details
2 |
3 | import info.sanaebadi.domain.model.user.Owner
4 | import info.sanaebadi.domain.model.user.Question
5 | import info.sanaebadi.entity.user.QuestionEntity
6 | import info.sanaebadi.entity.user.QuestionListEntity
7 | import info.sanaebadi.mapper.base.DataLayerMapper
8 | import java.util.*
9 | import javax.inject.Inject
10 | import javax.inject.Singleton
11 |
12 | @Singleton
13 | class FavoritesByUserMapper @Inject constructor() : DataLayerMapper {
14 |
15 | fun toDomain(questionListEntity: QuestionListEntity): List {
16 | val quesList: MutableList = ArrayList()
17 |
18 | for (question: QuestionEntity in questionListEntity.items) {
19 | quesList.add(toDomain(question))
20 | }
21 | return quesList
22 | }
23 |
24 | override fun toDomain(e: QuestionEntity?): Question {
25 |
26 | val owner = e?.ownerEntity?.userId?.let { Owner(it) }
27 |
28 | return Question(
29 | e?.viewCount!!,
30 | e.score,
31 | e.title,
32 | e.link,
33 | e.questionId,
34 | owner!!
35 | )
36 | }
37 |
38 | override fun toEntity(d: Question?): QuestionEntity? {
39 | return null
40 | }
41 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/mapper/details/QuestionByIdMapper.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.mapper.details
2 |
3 | import info.sanaebadi.domain.model.user.Owner
4 | import info.sanaebadi.domain.model.user.Question
5 | import info.sanaebadi.domain.model.user.QuestionList
6 | import info.sanaebadi.entity.user.QuestionEntity
7 | import info.sanaebadi.entity.user.QuestionListEntity
8 | import info.sanaebadi.mapper.base.DataLayerMapper
9 | import java.util.*
10 | import javax.inject.Inject
11 | import javax.inject.Singleton
12 |
13 | @Singleton
14 | class QuestionByIdMapper @Inject constructor() : DataLayerMapper {
15 |
16 | fun toDomain(questionListEntity: QuestionListEntity): List? {
17 | val quesList: MutableList = ArrayList()
18 |
19 | for (question: QuestionEntity in questionListEntity.items) {
20 | quesList.add(toDomain(question))
21 | }
22 | return quesList
23 | }
24 |
25 | override fun toDomain(e: QuestionEntity?): Question {
26 |
27 | val owner = e?.ownerEntity?.userId?.let { Owner(it) }
28 |
29 | return Question(
30 | e?.viewCount!!,
31 | e.score,
32 | e.title,
33 | e.link,
34 | e.questionId,
35 | owner!!
36 | )
37 | }
38 |
39 | override fun toEntity(d: Question?): QuestionEntity? {
40 | return null
41 | }
42 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/mapper/details/QuestionsByUserMapper.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.mapper.details
2 |
3 | import info.sanaebadi.domain.model.user.Owner
4 | import info.sanaebadi.domain.model.user.Question
5 | import info.sanaebadi.entity.user.QuestionEntity
6 | import info.sanaebadi.entity.user.QuestionListEntity
7 | import info.sanaebadi.mapper.base.DataLayerMapper
8 | import java.util.*
9 | import javax.inject.Inject
10 | import javax.inject.Singleton
11 |
12 | @Singleton
13 | class QuestionsByUserMapper @Inject constructor() : DataLayerMapper {
14 |
15 | fun toDomain(questionListEntity: QuestionListEntity): List? {
16 | val quesList: MutableList = ArrayList()
17 |
18 | for (question: QuestionEntity in questionListEntity.items) {
19 | quesList.add(toDomain(question))
20 | }
21 | return quesList
22 | }
23 |
24 | override fun toDomain(e: QuestionEntity?): Question {
25 | val owner = e?.ownerEntity?.userId?.let { Owner(it) }
26 |
27 | return Question(
28 | e?.viewCount!!,
29 | e.score,
30 | e.title,
31 | e.link,
32 | e.questionId,
33 | owner!!
34 |
35 | )
36 | }
37 |
38 | override fun toEntity(d: Question?): QuestionEntity? {
39 | return null
40 | }
41 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/mapper/user/UserMapper.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.mapper.user
2 |
3 | import info.sanaebadi.domain.model.user.User
4 | import info.sanaebadi.domain.model.user.UserListModel
5 | import info.sanaebadi.entity.user.UserEntity
6 | import info.sanaebadi.entity.user.UserListModelEntity
7 | import info.sanaebadi.mapper.base.DataLayerMapper
8 | import java.util.*
9 | import javax.inject.Inject
10 | import javax.inject.Singleton
11 |
12 | @Singleton
13 | class UserMapper @Inject constructor() : DataLayerMapper {
14 |
15 | fun toDomain(userListModelEntity: UserListModelEntity): UserListModel? {
16 | val userList: MutableList = ArrayList()
17 |
18 | for (user: UserEntity in userListModelEntity.items) {
19 | userList.add(toDomain(user)!!)
20 | }
21 | return UserListModel(userList)
22 | }
23 |
24 |
25 | override fun toDomain(e: UserEntity?): User? {
26 | return User(e?.userId!!, e.displayName, e.reputation, e.profileImage)
27 |
28 | }
29 |
30 | override fun toEntity(d: User?): UserEntity? {
31 | return null
32 | }
33 |
34 |
35 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/networking/base/AbstractService.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.networking.base
2 |
3 | import info.sanaebadi.data.BuildConfig
4 | import io.reactivex.schedulers.Schedulers
5 | import okhttp3.OkHttpClient
6 | import okhttp3.logging.HttpLoggingInterceptor
7 | import retrofit2.Retrofit
8 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
9 | import retrofit2.converter.moshi.MoshiConverterFactory
10 | import retrofit2.converter.scalars.ScalarsConverterFactory
11 | import java.util.concurrent.TimeUnit
12 |
13 | abstract class AbstractService(
14 | serviceType: Class
15 | ) {
16 | internal var service: S
17 | private var serviceType: Class? = serviceType
18 |
19 | init {
20 | service = createService(BuildConfig.API_BASE_URL)
21 | }
22 |
23 |
24 | fun setBaseUrl(baseUrl: String) {
25 | service = createService(baseUrl)
26 | }
27 |
28 |
29 | private fun createService(baseUrl: String): S {
30 | val interceptor = HttpLoggingInterceptor()
31 | interceptor.level = HttpLoggingInterceptor.Level.BODY
32 |
33 |
34 | val client = OkHttpClient.Builder()
35 | .connectTimeout(TIME_OUT_MIL_SECS, TimeUnit.SECONDS)
36 | .addInterceptor(interceptor)
37 | .build()
38 |
39 | val retrofitBuilder = Retrofit.Builder().baseUrl(baseUrl)
40 | .addConverterFactory(ScalarsConverterFactory.create())
41 | .addConverterFactory(MoshiConverterFactory.create())
42 | .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
43 | return retrofitBuilder.client(client).build().create(serviceType!!)
44 | }
45 |
46 |
47 | companion object {
48 | private const val TIME_OUT_MIL_SECS = 60L
49 | }
50 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/networking/retrofit/UserApiRetrofitService.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.networking.retrofit
2 |
3 | import info.sanaebadi.entity.user.AnswerListEntity
4 | import info.sanaebadi.entity.user.QuestionListEntity
5 | import info.sanaebadi.entity.user.UserListModelEntity
6 | import io.reactivex.Single
7 | import retrofit2.http.GET
8 | import retrofit2.http.Path
9 | import retrofit2.http.Query
10 |
11 | interface UserApiRetrofitService {
12 | @GET("users?order=desc&sort=reputation&site=stackoverflow")
13 | fun getUsers(@Query("page") page: Int = 1): Single
14 |
15 | @GET("users/{userId}/questions?order=desc&sort=votes&site=stackoverflow")
16 | fun getQuestionsByUser(@Path("userId") userId: Long): Single
17 |
18 | @GET("users/{userId}/favorites?order=desc&sort=votes&site=stackoverflow")
19 | fun getFavoritesByUser(@Path("userId") userId: Long): Single
20 |
21 | @GET("users/{userId}/answers?order=desc&sort=votes&site=stackoverflow")
22 | fun getAnswersByUser(@Path("userId") userId: Long): Single
23 |
24 | @GET("questions/{questionIds}?order=desc&sort=activity&site=stackoverflow")
25 | fun getQuestionsById(@Path("questionIds") questionId: String): Single
26 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSource/base/BaseDataSourceFactory.java:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSource.base;
2 |
3 | import info.sanaebadi.domain.repository.CacheStrategy;
4 | import io.reactivex.Completable;
5 |
6 | public interface BaseDataSourceFactory {
7 | T create(CacheStrategy cacheStrategy, String... params);
8 |
9 | Completable deleteCache();
10 | }
11 |
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSource/details/DetailsDataRepository.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSource.details
2 |
3 | import info.sanaebadi.domain.model.user.Answer
4 | import info.sanaebadi.domain.model.user.AnswerList
5 | import info.sanaebadi.domain.model.user.Question
6 | import info.sanaebadi.domain.model.user.QuestionList
7 | import info.sanaebadi.domain.repository.CacheStrategy
8 | import info.sanaebadi.domain.repository.DetailsRepository
9 | import info.sanaebadi.mapper.details.AnswersByUserMapper
10 | import info.sanaebadi.mapper.details.FavoritesByUserMapper
11 | import info.sanaebadi.mapper.details.QuestionByIdMapper
12 | import info.sanaebadi.mapper.details.QuestionsByUserMapper
13 | import io.reactivex.Single
14 | import javax.inject.Inject
15 |
16 | class DetailsDataRepository @Inject constructor(
17 | private val detailsDataSourceFactory: DetailsDataSourceFactory,
18 | private val answersByUserMapper: AnswersByUserMapper,
19 | private val favoritesByUserMapper: FavoritesByUserMapper,
20 | private val questionsByUserMapper: QuestionsByUserMapper,
21 | private val questionByIdMapper: QuestionByIdMapper
22 |
23 | ) : DetailsRepository {
24 | override fun getQuestionsByUser(userId: Long): Single> {
25 | return detailsDataSourceFactory.create(CacheStrategy.ONLINE_FIRST)
26 | .getQuestionsByUser(userId)
27 | .map { data -> questionsByUserMapper.toDomain(data) }
28 | }
29 |
30 | override fun getAnswersByUser(userId: Long): Single> {
31 | return detailsDataSourceFactory.create(CacheStrategy.ONLINE_FIRST)
32 | .getAnswersByUser(userId)
33 | .map { data -> answersByUserMapper.toDomain(data) }
34 | }
35 |
36 | override fun getFavoritesByUser(userId: Long): Single> {
37 | return detailsDataSourceFactory.create(CacheStrategy.ONLINE_FIRST)
38 | .getFavoritesByUser(userId)
39 | .map { data -> favoritesByUserMapper.toDomain(data) }
40 | }
41 |
42 | override fun getQuestionsById(ids: List, userId: Long): Single> {
43 | return detailsDataSourceFactory.create(CacheStrategy.ONLINE_FIRST)
44 | .getQuestionsById(ids, userId)
45 | .map { data -> questionByIdMapper.toDomain(data) }
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSource/details/DetailsDataSource.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSource.details
2 |
3 | import info.sanaebadi.entity.user.AnswerListEntity
4 | import info.sanaebadi.entity.user.QuestionListEntity
5 | import io.reactivex.Single
6 |
7 |
8 | interface DetailsDataSource {
9 | fun getQuestionsByUser(userId: Long): Single
10 | fun getAnswersByUser(userId: Long): Single
11 | fun getFavoritesByUser(userId: Long): Single
12 | fun getQuestionsById(ids: List, userId: Long): Single
13 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSource/details/DetailsDataSourceFactory.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSource.details
2 |
3 | import info.sanaebadi.domain.repository.CacheStrategy
4 | import info.sanaebadi.repository.dataSource.base.BaseDataSourceFactory
5 | import info.sanaebadi.repository.dataSourceImpl.DetailsOnlineDataSource
6 | import io.reactivex.Completable
7 | import javax.inject.Inject
8 |
9 | class DetailsDataSourceFactory @Inject constructor() : BaseDataSourceFactory {
10 | override fun create(cacheStrategy: CacheStrategy?, vararg params: String?): DetailsDataSource {
11 | return DetailsOnlineDataSource()
12 | }
13 |
14 | override fun deleteCache(): Completable? {
15 | return null
16 | }
17 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSource/user/UserDataRepository.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSource.user
2 |
3 | import info.sanaebadi.domain.model.user.UserListModel
4 | import info.sanaebadi.domain.repository.CacheStrategy
5 | import info.sanaebadi.domain.repository.UserRepository
6 | import info.sanaebadi.mapper.user.UserMapper
7 | import io.reactivex.Single
8 | import javax.inject.Inject
9 | import javax.inject.Singleton
10 |
11 | @Singleton
12 | class UserDataRepository @Inject constructor(
13 | private val userDataSourceFactory: UserDataSourceFactory,
14 | private val userMapper: UserMapper
15 | ) : UserRepository {
16 |
17 | override fun getUsers(page: Int): Single {
18 | return userDataSourceFactory.create(CacheStrategy.ONLINE_FIRST).getUsers(page)
19 | .map { data -> userMapper.toDomain(data) }
20 | }
21 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSource/user/UserDataSource.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSource.user
2 |
3 | import info.sanaebadi.entity.user.UserListModelEntity
4 | import io.reactivex.Single
5 |
6 | interface UserDataSource {
7 | fun getUsers(page: Int): Single
8 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSource/user/UserDataSourceFactory.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSource.user
2 |
3 | import info.sanaebadi.domain.repository.CacheStrategy
4 | import info.sanaebadi.repository.dataSource.base.BaseDataSourceFactory
5 | import info.sanaebadi.repository.dataSourceImpl.UserOnlineDataSource
6 | import io.reactivex.Completable
7 | import javax.inject.Inject
8 |
9 | class UserDataSourceFactory @Inject constructor() : BaseDataSourceFactory {
10 | override fun create(cacheStrategy: CacheStrategy?, vararg params: String?): UserDataSource {
11 | return UserOnlineDataSource()
12 | }
13 |
14 | override fun deleteCache(): Completable? {
15 | return null
16 | }
17 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSourceImpl/DetailsOnlineDataSource.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSourceImpl
2 |
3 | import info.sanaebadi.entity.user.AnswerListEntity
4 | import info.sanaebadi.entity.user.QuestionListEntity
5 | import info.sanaebadi.networking.base.AbstractService
6 | import info.sanaebadi.networking.retrofit.UserApiRetrofitService
7 | import info.sanaebadi.repository.dataSource.details.DetailsDataSource
8 | import io.reactivex.Single
9 |
10 | class DetailsOnlineDataSource :
11 | AbstractService(UserApiRetrofitService::class.java), DetailsDataSource {
12 |
13 | override fun getQuestionsByUser(userId: Long): Single {
14 | return service.getQuestionsByUser(userId)
15 | }
16 |
17 | override fun getAnswersByUser(userId: Long): Single {
18 | return service.getAnswersByUser(userId)
19 | }
20 |
21 | override fun getFavoritesByUser(userId: Long): Single {
22 | return service.getFavoritesByUser(userId)
23 | }
24 |
25 | override fun getQuestionsById(ids: List, userId: Long): Single {
26 | return service.getQuestionsById(ids.joinToString(separator = ";"))
27 | }
28 |
29 |
30 | }
--------------------------------------------------------------------------------
/data/src/main/java/info/sanaebadi/repository/dataSourceImpl/UserOnlineDataSource.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.repository.dataSourceImpl
2 |
3 | import info.sanaebadi.entity.user.UserListModelEntity
4 | import info.sanaebadi.networking.base.AbstractService
5 | import info.sanaebadi.networking.retrofit.UserApiRetrofitService
6 | import info.sanaebadi.repository.dataSource.user.UserDataSource
7 | import io.reactivex.Single
8 |
9 | class UserOnlineDataSource :
10 | AbstractService(UserApiRetrofitService::class.java), UserDataSource {
11 |
12 | override fun getUsers(page: Int): Single {
13 | return service.getUsers(page)
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/data/src/test/java/info/sanaebadi/data/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.data
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/domain/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/domain/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2 |
3 | plugins {
4 | id(BuildPlugins.javaLibraryPlugin)
5 | id(BuildPlugins.kotlinPlugin)
6 | id(BuildPlugins.kaptPlugin)
7 | }
8 |
9 |
10 | dependencies {
11 | implementation(Libraries.kotlinStdLib)
12 | implementation(RXLibraries.rxAndroid)
13 | implementation(RXLibraries.rxJava)
14 | implementation(Libraries.arrow)
15 |
16 | implementation(DaggerLib.dagger)
17 | implementation(DaggerLib.daggerSupport)
18 | kapt(DaggerLib.daggerCompiler)
19 | kapt(DaggerLib.daggerProcessor)
20 |
21 | implementation(RXLibraries.rxAndroid)
22 | implementation(RXLibraries.rxJava)
23 | implementation(RXLibraries.rxKotlin)
24 |
25 | testImplementation(TestLibraries.junit4)
26 | testImplementation(TestLibraries.mockitoKotlin)
27 | }
28 |
29 |
30 | // compile bytecode to java 8 (default is java 6)
31 | tasks.withType {
32 | kotlinOptions.jvmTarget = "1.8"
33 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/executor/PostExecutionThread.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.executor
2 |
3 | import io.reactivex.Scheduler
4 |
5 | /**
6 | * Thread abstraction created to change the execution context from any thread to any other thread.
7 | * Useful to encapsulate a UI Thread for example, since some job will be done in background, an
8 | * implementation of this interface will change context and update the UI.
9 | */
10 | interface PostExecutionThread {
11 | val scheduler: Scheduler
12 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/executor/ThreadExecutor.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.executor
2 |
3 |
4 | import java.util.concurrent.Executor
5 |
6 | /**
7 | * Executor implementation can be based on different frameworks or techniques of asynchronous
8 | * execution, but every implementation will execute the [UseCase] out of the UI thread.
9 | */
10 | interface ThreadExecutor : Executor
11 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/BaseCompeletableObserver.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 | import io.reactivex.observers.DisposableCompletableObserver
4 |
5 | open class BaseCompeletableObserver : DisposableCompletableObserver(), IObserver {
6 |
7 | override fun onComplete() {
8 |
9 | }
10 |
11 | override fun onError(e: Throwable) {
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/BaseMaybeObserver.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 | import io.reactivex.observers.DisposableMaybeObserver
4 |
5 | open class BaseMaybeObserver : DisposableMaybeObserver(), IObserver {
6 |
7 | override fun onSuccess(t: T) {
8 |
9 | }
10 |
11 | override fun onError(e: Throwable) {
12 |
13 | }
14 |
15 | override fun onComplete() {
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/BaseObserver.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Fernando Cejas Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package info.sanaebadi.domain.interactor.base
17 |
18 | import io.reactivex.observers.DisposableObserver
19 |
20 | /**
21 | * Default [DisposableObserver] base class to be used whenever you want default error handling.
22 | */
23 | open class BaseObserver : DisposableObserver(), IObserver {
24 | override fun onNext(data: T) {
25 | // no-op by default.
26 | }
27 |
28 | override fun onComplete() {
29 | // no-op by default.
30 | }
31 |
32 | override fun onError(exception: Throwable) {
33 | // no-op by default.
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/BaseSingleObserver.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 | import io.reactivex.observers.DisposableSingleObserver
4 |
5 | open class BaseSingleObserver : DisposableSingleObserver(), IObserver {
6 |
7 | override fun onSuccess(t: T) {
8 | }
9 |
10 | override fun onError(e: Throwable) {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/CompletableUseCase.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 | import com.fernandocejas.arrow.checks.Preconditions
4 | import info.sanaebadi.domain.executor.PostExecutionThread
5 | import info.sanaebadi.domain.executor.ThreadExecutor
6 | import io.reactivex.Completable
7 | import io.reactivex.disposables.CompositeDisposable
8 | import io.reactivex.disposables.Disposable
9 | import io.reactivex.observers.DisposableCompletableObserver
10 | import io.reactivex.schedulers.Schedulers
11 |
12 | abstract class CompletableUseCase(
13 | private val threadExecutor: ThreadExecutor,
14 | private val postExecutionThread: PostExecutionThread
15 | ) : IUseCase {
16 | private val disposables: CompositeDisposable = CompositeDisposable()
17 |
18 | override fun execute(observer: DisposableCompletableObserver, params: Params) {
19 | Preconditions.checkNotNull(observer)
20 | val completable = this.buildUseCaseCompletable(params)
21 | .subscribeOn(Schedulers.from(threadExecutor))
22 | .observeOn(postExecutionThread.scheduler)
23 | addDisposable(completable.subscribeWith(observer))
24 | }
25 |
26 |
27 | fun dispose() {
28 | if (!disposables.isDisposed) {
29 | disposables.dispose()
30 | }
31 | }
32 |
33 | abstract fun buildUseCaseCompletable(params: Params): Completable
34 |
35 |
36 | private fun addDisposable(disposable: Disposable) {
37 | Preconditions.checkNotNull(disposable)
38 | Preconditions.checkNotNull(disposables)
39 | disposables.add(disposable)
40 | }
41 | }
42 |
43 |
44 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/IObserver.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 | interface IObserver
4 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/IUseCase.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 | interface IUseCase {
4 | fun execute(observer: T, params: Params)
5 | }
6 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/MaybeUseCase.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 | import com.fernandocejas.arrow.checks.Preconditions
4 | import info.sanaebadi.domain.executor.PostExecutionThread
5 | import info.sanaebadi.domain.executor.ThreadExecutor
6 | import io.reactivex.Maybe
7 | import io.reactivex.disposables.CompositeDisposable
8 | import io.reactivex.disposables.Disposable
9 | import io.reactivex.observers.DisposableMaybeObserver
10 | import io.reactivex.schedulers.Schedulers
11 |
12 | abstract class MaybeUseCase(
13 | private val threadExecutor: ThreadExecutor,
14 | private val postExecutionThread: PostExecutionThread
15 | ) :
16 | IUseCase, Params> {
17 | private val disposables: CompositeDisposable = CompositeDisposable()
18 |
19 | override fun execute(observer: DisposableMaybeObserver, params: Params) {
20 | val maybe = this.buildUseCaseMaybe(params)
21 | .subscribeOn(Schedulers.from(threadExecutor))
22 | .observeOn(postExecutionThread.scheduler)
23 | addDisposable(maybe.subscribeWith(observer) as Disposable)
24 | }
25 |
26 |
27 | fun dispose() {
28 | if (!disposables.isDisposed) {
29 | disposables.dispose()
30 | }
31 | }
32 |
33 | abstract fun buildUseCaseMaybe(params: Params): Maybe
34 |
35 | private fun addDisposable(disposable: Disposable) {
36 | Preconditions.checkNotNull(disposable)
37 | Preconditions.checkNotNull(disposables)
38 | disposables.add(disposable)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/SingleUseCase.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 | import com.fernandocejas.arrow.checks.Preconditions
4 | import info.sanaebadi.domain.executor.PostExecutionThread
5 | import info.sanaebadi.domain.executor.ThreadExecutor
6 | import io.reactivex.Single
7 | import io.reactivex.disposables.CompositeDisposable
8 | import io.reactivex.disposables.Disposable
9 | import io.reactivex.observers.DisposableSingleObserver
10 | import io.reactivex.schedulers.Schedulers
11 |
12 | abstract class SingleUseCase(
13 | private val threadExecutor: ThreadExecutor,
14 | private val postExecutionThread: PostExecutionThread
15 | ) : IUseCase, Params> {
16 | private val disposables: CompositeDisposable = CompositeDisposable()
17 |
18 | override fun execute(observer: DisposableSingleObserver, params: Params) {
19 | Preconditions.checkNotNull(observer)
20 | val single = this.buildUseCaseSingle(params)
21 | .subscribeOn(Schedulers.from(threadExecutor))
22 | .observeOn(postExecutionThread.scheduler)
23 | addDisposable(single.subscribeWith(observer))
24 | }
25 |
26 |
27 | fun dispose() {
28 | if (!disposables.isDisposed) {
29 | disposables.dispose()
30 | }
31 | }
32 |
33 | abstract fun buildUseCaseSingle(params: Params): Single
34 |
35 | private fun addDisposable(disposable: Disposable) {
36 | Preconditions.checkNotNull(disposable)
37 | Preconditions.checkNotNull(disposables)
38 | disposables.add(disposable)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/base/UseCase.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.base
2 |
3 |
4 | import com.fernandocejas.arrow.checks.Preconditions
5 | import info.sanaebadi.domain.executor.PostExecutionThread
6 | import info.sanaebadi.domain.executor.ThreadExecutor
7 | import io.reactivex.Observable
8 | import io.reactivex.disposables.CompositeDisposable
9 | import io.reactivex.disposables.Disposable
10 | import io.reactivex.observers.DisposableObserver
11 | import io.reactivex.schedulers.Schedulers
12 |
13 |
14 | abstract class UseCase(
15 | private val threadExecutor: ThreadExecutor,
16 | private val postExecutionThread: PostExecutionThread
17 | ) : IUseCase, Params> {
18 | private val disposables: CompositeDisposable = CompositeDisposable()
19 |
20 | abstract fun buildUseCaseObservable(params: Params): Observable
21 |
22 |
23 | override fun execute(observer: DisposableObserver, params: Params) {
24 | Preconditions.checkNotNull(observer)
25 | val observable = this.buildUseCaseObservable(params)
26 | .subscribeOn(Schedulers.from(threadExecutor))
27 | .observeOn(postExecutionThread.scheduler)
28 | addDisposable(observable.subscribeWith(observer))
29 | }
30 |
31 |
32 | fun dispose() {
33 | if (!disposables.isDisposed) {
34 | disposables.dispose()
35 | }
36 | }
37 |
38 | private fun addDisposable(disposable: Disposable) {
39 | Preconditions.checkNotNull(disposable)
40 | Preconditions.checkNotNull(disposables)
41 | disposables.add(disposable)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/user/DetailsUseCase.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.user
2 |
3 | import info.sanaebadi.domain.model.UserDetailsModel
4 | import info.sanaebadi.domain.model.details.AnswerViewModel
5 | import info.sanaebadi.domain.model.details.QuestionViewModel
6 | import info.sanaebadi.domain.model.user.Answer
7 | import info.sanaebadi.domain.model.user.Question
8 | import info.sanaebadi.domain.repository.DetailsRepository
9 | import io.reactivex.Single
10 | import javax.inject.Inject
11 |
12 | class DetailsUseCase @Inject constructor(private val detailsRepository: DetailsRepository) {
13 |
14 | fun execute(userId: Long): Single {
15 | return Single.zip(
16 | detailsRepository.getQuestionsByUser(userId),
17 | getTitlesForAnswers(userId),
18 | detailsRepository.getFavoritesByUser(userId),
19 | { questions, answers, favorites ->
20 | createDetailsModel(questions, answers, favorites)
21 | })
22 | }
23 |
24 | private fun getTitlesForAnswers(userId: Long): Single> {
25 | return detailsRepository.getAnswersByUser(userId)
26 | .flatMap { answers: List ->
27 | mapAnswersToAnswerViewModels(answers, userId)
28 | }
29 | }
30 |
31 | private fun mapAnswersToAnswerViewModels(
32 | answers: List,
33 | userId: Long
34 | ): Single> {
35 | val ids = answers
36 | .map { it.questionId }
37 |
38 | val questionsById = detailsRepository.getQuestionsById(ids, userId)
39 |
40 | return questionsById
41 | .map { questions: List ->
42 | createAnswerViewModels(answers, questions)
43 | }
44 | }
45 |
46 | private fun createAnswerViewModels(
47 | answers: List,
48 | questions: List
49 | ): List {
50 | return answers.map { (answerId, questionId, score, accepted) ->
51 | val question = questions.find { it.questionId == questionId }
52 | AnswerViewModel(answerId, score, accepted, question?.title ?: "Unknown")
53 | }
54 | }
55 |
56 | private fun createDetailsModel(
57 | questions: List,
58 | answers: List,
59 | favorites: List
60 | ): UserDetailsModel {
61 | val questionViewModels =
62 | questions.map {
63 | QuestionViewModel(
64 | it.viewCount,
65 | it.score,
66 | it.title,
67 | it.link,
68 | it.questionId
69 | )
70 | }
71 | val favoriteViewModels =
72 | favorites.map {
73 | QuestionViewModel(
74 | it.viewCount,
75 | it.score,
76 | it.title,
77 | it.link,
78 | it.questionId
79 | )
80 | }
81 |
82 | return UserDetailsModel(questionViewModels, answers, favoriteViewModels)
83 | }
84 |
85 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/interactor/user/UserUseCase.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.interactor.user
2 |
3 | import info.sanaebadi.domain.executor.PostExecutionThread
4 | import info.sanaebadi.domain.executor.ThreadExecutor
5 | import info.sanaebadi.domain.interactor.base.SingleUseCase
6 | import info.sanaebadi.domain.model.user.UserListModel
7 | import info.sanaebadi.domain.repository.UserRepository
8 | import io.reactivex.Single
9 | import javax.inject.Inject
10 |
11 | class UserUseCase @Inject constructor(
12 | private val userRepository: UserRepository,
13 | threadExecutor: ThreadExecutor,
14 | postExecutionThread: PostExecutionThread,
15 | ) :
16 | SingleUseCase(threadExecutor, postExecutionThread) {
17 |
18 | override fun buildUseCaseSingle(page: Int): Single {
19 | return userRepository.getUsers(page)
20 | }
21 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/UserDetailsModel.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model
2 |
3 | import info.sanaebadi.domain.model.base.ViewType
4 | import info.sanaebadi.domain.model.details.AnswerViewModel
5 | import info.sanaebadi.domain.model.details.QuestionViewModel
6 |
7 | data class UserDetailsModel(
8 | val questions: List,
9 | val answers: List,
10 | val favorites: List
11 | ) : ViewType {
12 | override fun getViewType(): Int {
13 | TODO("Not yet implemented")
14 | }
15 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/base/AdapterConstants.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.base
2 |
3 | object AdapterConstants {
4 | const val USER_DETAILS = 1
5 | const val HEADING = 2
6 | const val QUESTION = 3
7 | const val ANSWER = 4
8 | const val LOADING = 5
9 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/base/BaseDomainModel.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.base
2 |
3 | interface BaseDomainModel {
4 |
5 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/base/ViewType.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.base
2 |
3 | interface ViewType {
4 | fun getViewType(): Int
5 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/details/AnswerViewModel.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.details
2 |
3 | import info.sanaebadi.domain.model.base.AdapterConstants
4 | import info.sanaebadi.domain.model.base.ViewType
5 |
6 | data class AnswerViewModel(
7 | val answerId: Long,
8 | val score: Long,
9 | val accepted: Boolean,
10 | val questionTitle: String
11 | ) : ViewType {
12 |
13 | override fun getViewType() = AdapterConstants.ANSWER
14 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/details/QuestionViewModel.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.details
2 |
3 | import info.sanaebadi.domain.model.base.AdapterConstants
4 | import info.sanaebadi.domain.model.base.ViewType
5 |
6 | data class QuestionViewModel(
7 | val viewCount: Long,
8 | val score: Long,
9 | val title: String,
10 | val link: String,
11 | val questionId: Long
12 | ) : ViewType {
13 | override fun getViewType(): Int = AdapterConstants.QUESTION
14 |
15 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/user/Answer.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.user
2 |
3 | import info.sanaebadi.domain.model.base.AdapterConstants
4 | import info.sanaebadi.domain.model.base.BaseDomainModel
5 | import info.sanaebadi.domain.model.base.ViewType
6 |
7 | data class Answer(
8 | var answerId: Long,
9 | var questionId: Long,
10 | var score: Long,
11 | var accepted: Boolean,
12 | var ownerEntity: Owner
13 | ) : BaseDomainModel {
14 |
15 | constructor() : this(-1, -1, 0, false, Owner())
16 | }
17 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/user/AnswerList.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.user
2 |
3 | import info.sanaebadi.domain.model.base.BaseDomainModel
4 |
5 | class AnswerList(val items: List) :BaseDomainModel
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/user/FavoritedByUser.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.user
2 |
3 | import info.sanaebadi.domain.model.base.BaseDomainModel
4 |
5 | data class FavoritedByUser(
6 | var userId: Long,
7 | var questionIds: List
8 | ): BaseDomainModel {
9 |
10 | constructor() : this(-1, emptyList())
11 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/user/Owner.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.user
2 |
3 | import info.sanaebadi.domain.model.base.BaseDomainModel
4 |
5 |
6 |
7 | data class Owner(var userId: Long) : BaseDomainModel {
8 |
9 | constructor() : this(-1)
10 | }
11 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/user/Question.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.user
2 |
3 | import info.sanaebadi.domain.model.base.BaseDomainModel
4 |
5 |
6 | data class Question(
7 | var viewCount: Long,
8 | var score: Long,
9 | var title: String,
10 | var link: String,
11 | var questionId: Long,
12 | var ownerEntity: Owner
13 | ) : BaseDomainModel {
14 |
15 |
16 | constructor() : this(0, 0, "", "", -1, Owner())
17 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/user/QuestionList.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.user
2 |
3 | import info.sanaebadi.domain.model.base.BaseDomainModel
4 |
5 | class QuestionList(val items: List) : BaseDomainModel
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/user/User.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.user
2 |
3 | import info.sanaebadi.domain.model.base.BaseDomainModel
4 |
5 |
6 | data class User(
7 | var userId: Long,
8 | var displayName: String,
9 | var reputation: Long,
10 | var profileImage: String
11 | ) : BaseDomainModel {
12 |
13 | constructor() : this(-1, "", 0, "")
14 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/model/user/UserListModel.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.model.user
2 |
3 | import info.sanaebadi.domain.model.base.BaseDomainModel
4 |
5 |
6 | class UserListModel(val items: List) : BaseDomainModel
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/repository/CacheStrategy.java:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.repository;
2 |
3 | public enum CacheStrategy {
4 | ONLINE_FIRST,
5 | CACHE_FIRST
6 | }
7 |
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/repository/DetailsRepository.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.repository
2 |
3 | import info.sanaebadi.domain.model.user.Answer
4 | import info.sanaebadi.domain.model.user.Question
5 | import io.reactivex.Single
6 |
7 | interface DetailsRepository {
8 | fun getQuestionsByUser(userId: Long): Single>
9 | fun getAnswersByUser(userId: Long): Single>
10 | fun getFavoritesByUser(userId: Long): Single>
11 | fun getQuestionsById(ids: List, userId: Long): Single>
12 | }
--------------------------------------------------------------------------------
/domain/src/main/java/info/sanaebadi/domain/repository/UserRepository.kt:
--------------------------------------------------------------------------------
1 | package info.sanaebadi.domain.repository
2 |
3 | import info.sanaebadi.domain.model.user.UserListModel
4 | import io.reactivex.Single
5 |
6 | interface UserRepository {
7 | fun getUsers(page: Int): Single
8 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sanaebadi97/StackOverFlowApi/a240e4e0f29d4af06da7d80cb638e3552e074e47/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Sep 17 18:44:23 IRDT 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no "java" command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | include(":domain")
2 | include(":data")
3 | include (":app")
4 | rootProject.name = "StackOverFlowProject"
--------------------------------------------------------------------------------