Skip to content

Feature/channel first impl #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ android {

dependencies {
def ktx_version = "2.0.0"
def kotlin_coroutines_version = "1.0.1"

implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
Expand All @@ -39,6 +40,10 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$ktx_version"
implementation project (':ktandroidarchitecturecore')
testImplementation 'junit:junit:4.12'

implementation 'androidx.paging:paging-runtime-ktx:2.1.0'

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
Expand Down
32 changes: 32 additions & 0 deletions app/src/main/java/com/sysdata/kt/ktandroidarchitecture/DIUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture

import com.sysdata.kt.ktandroidarchitecture.ui.Note
import it.sysdata.ktandroidarchitecturecore.interactor.Channel

class DIUtils {

private object Holder {
val INSTANCE = Channel<Note>()
}

companion object {
val channel: Channel<Note> by lazy {
Holder.INSTANCE
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture

import android.app.Application
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture

class MainApplicationConfig private constructor() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture.repository

import com.sysdata.kt.ktandroidarchitecture.repository.model.UserLogged
import it.sysdata.ktandroidarchitecturecore.BaseRepository
import it.sysdata.ktandroidarchitecturecore.exception.Failure
import it.sysdata.ktandroidarchitecturecore.functional.Either

/**
* Mock implementation of a repository
*/
class AuthRepository:BaseRepository() {

private object Holder {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture.repository.model


Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture.repository.model


Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture.ui

import android.app.Activity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import android.os.Bundle

import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModelProviders
import androidx.paging.PagedList
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.sysdata.kt.ktandroidarchitecture.R
import com.sysdata.kt.ktandroidarchitecture.repository.model.UIUserLogged
import com.sysdata.kt.ktandroidarchitecture.repository.model.UserLogged
import com.sysdata.kt.ktandroidarchitecture.usecase.LoginActionParams
import com.sysdata.kt.ktandroidarchitecture.viewmodel.LoginViewModel
import it.sysdata.ktandroidarchitecturecore.exception.Failure
Expand All @@ -20,6 +36,7 @@ import kotlinx.android.synthetic.main.activity_login.*
class LoginActivity : FragmentActivity(), View.OnClickListener, TextWatcher {

private var viewModel : LoginViewModel? = null
private var adapter: PagedListAdapterImpl? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -37,6 +54,41 @@ class LoginActivity : FragmentActivity(), View.OnClickListener, TextWatcher {

viewModel?.actionLogin?.observe(this, ::onUserLoggged)
viewModel?.actionLogin?.observeFailure(this, ::onLoginFailed)

// initalization of the datasource channel only with the page size because we use a test datasource that don't need initial datas
viewModel?.channelNotes?.initDatasource(pageSize = 10)

// init of the adapter with a click listener for the items
adapter = PagedListAdapterImpl {
viewModel?.channelPostNotes?.postData(it)
}

recycler_view.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
recycler_view.adapter = adapter

// we observe channel notes to have the updates from the adapter that sends the datas through livedata
viewModel?.channelNotes?.observe(this,::onPostNote)
// we observe a general channel used to send datas not related to the adapter
viewModel?.channelPostNotes?.observe(this, ::onReceivePost)
}

/**
* This method recieves the datas from the channel not related to the adapter of the paged list
* @param note Note?
*/
private fun onReceivePost(note: Note?) {
Toast.makeText(this, "note : $note", Toast.LENGTH_SHORT).show()
}

/**
* this method update the adapter with the the list recieved by the livedata
*
* @param list PagedList<Note>?
*/
private fun onPostNote(list: PagedList<Note>?) {
list?.let {
adapter?.submitList(list)
}
}

private fun onLoginFailed(failure: Failure?) {
Expand Down
42 changes: 42 additions & 0 deletions app/src/main/java/com/sysdata/kt/ktandroidarchitecture/ui/Note.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture.ui

import androidx.recyclerview.widget.DiffUtil
import java.util.*

/**
* Data object used into the paged lisi adapter, we implement a [diff callback][DiffUtil.ItemCallback] because is need by the adapter
*
* @property index Int
* @property noteId String
* @property title String
* @property content String
* @constructor
*/
data class Note(val index:Int, val noteId: String = UUID.randomUUID().toString()) {
companion object {
val DiffCallback = object : DiffUtil.ItemCallback<Note>() {
override fun areItemsTheSame(oldItem: Note, newItem: Note): Boolean
= oldItem.noteId == newItem.noteId

override fun areContentsTheSame(oldItem: Note, newItem: Note): Boolean
= oldItem.noteId == newItem.noteId && oldItem.title == newItem.title && oldItem.content == newItem.content
}
}
var title: String = ""
var content: String = ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture.ui

import it.sysdata.ktandroidarchitecturecore.BasePositionalDatasource

/**
* Implementation of [BasePositionalDatasource] with notes
*/
class NoteDataSource: BasePositionalDatasource<Note>()
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright (C) 2019 Sysdata S.p.a.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sysdata.kt.ktandroidarchitecture.ui

import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.sysdata.kt.ktandroidarchitecture.R

/**
* Dummy implementation of [PagedListAdapter]
*
* @property onClick Function1<Note, Unit>
* @constructor
*/
class PagedListAdapterImpl(val onClick: (Note) -> Unit) : PagedListAdapter<Note, PagedListAdapterImpl.ListItemViewHolder>(Note.DiffCallback) {
class ListItemViewHolder(val view: View): RecyclerView.ViewHolder(view) {
var note: Note? = null
set(value) {
if(value != null){
val tv: TextView = view.findViewById(R.id.itemText)
tv.text = value.toString()
}
field = value
}
}

companion object {
private val TAG = this::class.java.simpleName
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemViewHolder
= ListItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.note_list_item, parent, false))

override fun onBindViewHolder(holder: ListItemViewHolder, position: Int) {
Log.d(TAG, "Binding view holder at position $position")
holder.note = getItem(position)
holder.view.setOnClickListener { onClick(holder.note!!) }
}

}
Loading