Skip to content

Instantly share code, notes, and snippets.

@malmstein
Last active March 18, 2022 16:05
Show Gist options
  • Select an option

  • Save malmstein/9bbf54ab4a7a16cbc862f6666bae2a0f to your computer and use it in GitHub Desktop.

Select an option

Save malmstein/9bbf54ab4a7a16cbc862f6666bae2a0f to your computer and use it in GitHub Desktop.
/*
* Copyright (c) 2022 DuckDuckGo
*
* 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 dummy
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import androidx.annotation.VisibleForTesting
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.duckduckgo.app.global.DispatcherProvider
import com.duckduckgo.app.global.DuckDuckGoActivity
import com.duckduckgo.mobile.android.vpn.cohort.RealCohortStore
import com.duckduckgo.mobile.android.vpn.cohort.RealCohortStore.Companion
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flatMap
import kotlinx.coroutines.flow.flatMapConcat
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.threeten.bp.LocalDate
import javax.inject.Inject
data class DataEntity(
val id: Long,
val title: String
)
data class DataModel(val title: String)
interface DataStore {
fun getData(): DataModel
fun storeData(data: DataModel)
}
class RealDataStore @Inject constructor(
private val context: Context
) : DataStore {
@VisibleForTesting
val preferences: SharedPreferences
get() = context.getSharedPreferences(FILENAME, Context.MODE_MULTI_PROCESS)
override fun getData(): DataModel {
return DataModel(preferences.getString(KEY_TITLE, "empty")!!)
}
override fun storeData(data: DataModel) {
preferences.edit {
putString(KEY_TITLE, data.title)
}
}
companion object {
private const val FILENAME = "com.duckduckgo.mobile.prefs"
private const val KEY_TITLE = "KEY_TITLE"
}
}
@Dao
interface DataSuspendingDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(data: DataEntity)
@Query("select * from data_table")
suspend fun getAll(): List<DataEntity>
@Query("select * from data_table where id = :id")
suspend fun getId(id: Long): DataEntity
@Query("select * from data_table")
suspend fun getFlow(): Flow<List<DataEntity>>
}
@Dao
interface DataDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(data: DataEntity)
@Query("select * from data_table")
fun getAll(): List<DataEntity>
@Query("select * from data_table where id = :id")
fun getId(id: Long): DataEntity
@Query("select * from data_table")
fun getFlow(): Flow<List<DataEntity>>
}
interface Repository {
suspend fun getAllFromDao(): List<DataEntity>
suspend fun getIdFromDao(id: Long): DataEntity
suspend fun getAllTransformed(): List<DataModel>
fun getFromDataStore(): DataModel
suspend fun getFlow(): Flow<List<DataEntity>>
}
class RealRepository @Inject constructor(
private val dao: DataDao,
private val suspendingDao: DataSuspendingDao,
private val dataStore: DataStore,
private val dispatcherProvider: DispatcherProvider
) : Repository {
override suspend fun getAllFromDao(): List<DataEntity> {
return dao.getAll()
}
override suspend fun getIdFromDao(id: Long): DataEntity {
return dao.getId(id)
}
override suspend fun getAllTransformed(): List<DataModel> {
return dao.getAll().map { dataEntity ->
DataModel(dataEntity.title)
}
}
override suspend fun getFlow(): Flow<List<DataEntity>> {
return dao.getFlow()
.flowOn(dispatcherProvider.io())
}
override fun getFromDataStore(): DataModel {
return dataStore.getData()
}
}
data class ViewState(val excludedApps: List<DataModel>)
class DataViewModel(private val repository: Repository,
private val dispatcherProvider: DispatcherProvider) : ViewModel() {
private val viewStateFlow: MutableStateFlow<ViewState> =
MutableStateFlow(ViewState(emptyList()))
val viewState: StateFlow<ViewState> = viewStateFlow
internal suspend fun getDataFlow(): Flow<ViewState> = repository.getFlow().map { dataEntityList ->
ViewState(dataEntityList.map { dataEntity ->
DataModel(dataEntity.title)
})
}
internal suspend fun getFromDataStore() {
viewModelScope.launch {
val dataModel = withContext(dispatcherProvider.io()) {
repository.getFromDataStore()
}
viewStateFlow.emit(ViewState(listOf(dataModel)))
}
}
}
class DataActivity() : DuckDuckGoActivity() {
private val viewModel: DataViewModel by bindViewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
observeViewModel()
}
private fun observeViewModel() {
viewModel.viewState.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).onEach { render(it) }
lifecycleScope.launch {
viewModel.getDataFlow()
.flowWithLifecycle(lifecycle, Lifecycle.State.CREATED)
.onEach {
render(it)
}
}
}
private fun render(viewState: ViewState) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment