Combine view models

This commit is contained in:
Philipp Heckel 2021-10-26 14:35:51 -04:00
parent 18787d36e4
commit 1c6156c638
7 changed files with 34 additions and 72 deletions

View file

@ -27,7 +27,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="io.heckel.ntfy.list.TopicsListActivity">
<activity android:name="io.heckel.ntfy.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.heckel.ntfy.list
package io.heckel.ntfy
import android.app.Activity
import android.app.NotificationChannel
@ -33,13 +33,14 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.google.gson.JsonSyntaxException
import io.heckel.ntfy.R
import io.heckel.ntfy.add.AddTopicActivity
import io.heckel.ntfy.add.TOPIC_URL
import io.heckel.ntfy.data.Topic
import io.heckel.ntfy.detail.TopicDetailActivity
import io.heckel.ntfy.list.TopicsAdapter
import io.heckel.ntfy.list.TopicsViewModelFactory
import io.heckel.ntfy.list.TopicsViewModel
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.IOException
import java.net.HttpURLConnection
import java.net.URL
@ -47,12 +48,12 @@ import kotlin.random.Random
const val TOPIC_ID = "topic id"
class TopicsListActivity : AppCompatActivity() {
class MainActivity : AppCompatActivity() {
private val gson = GsonBuilder().create()
private val jobs = mutableMapOf<Long, Job>()
private val newTopicActivityRequestCode = 1
private val topicsListViewModel by viewModels<TopicsListViewModel> {
TopicsListViewModelFactory(this)
private val topicsListViewModel by viewModels<TopicsViewModel> {
TopicsViewModelFactory(this)
}
override fun onCreate(savedInstanceState: Bundle?) {

View file

@ -23,19 +23,27 @@ import androidx.lifecycle.ViewModelProvider
import io.heckel.ntfy.data.DataSource
import io.heckel.ntfy.data.Topic
class TopicsListViewModel(val dataSource: DataSource) : ViewModel() {
class TopicsViewModel(val dataSource: DataSource) : ViewModel() {
val topics: LiveData<List<Topic>> = dataSource.getTopicList()
fun add(topic: Topic) {
dataSource.addTopic(topic)
dataSource.add(topic)
}
fun get(id: Long) : Topic? {
return dataSource.get(id)
}
fun remove(topic: Topic) {
dataSource.remove(topic)
}
}
class TopicsListViewModelFactory(private val context: Context) : ViewModelProvider.Factory {
class TopicsViewModelFactory(private val context: Context) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(TopicsListViewModel::class.java)) {
if (modelClass.isAssignableFrom(TopicsViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return TopicsListViewModel(
return TopicsViewModel(
dataSource = DataSource.getDataSource(context.resources)
) as T
}

View file

@ -25,7 +25,7 @@ class DataSource(resources: Resources) {
private val topicsLiveData: MutableLiveData<List<Topic>> = MutableLiveData(mutableListOf())
/* Adds topic to liveData and posts value. */
fun addTopic(topic: Topic) {
fun add(topic: Topic) {
val currentList = topicsLiveData.value
if (currentList == null) {
topicsLiveData.postValue(listOf(topic))
@ -37,7 +37,7 @@ class DataSource(resources: Resources) {
}
/* Removes topic from liveData and posts value. */
fun removeTopic(topic: Topic) {
fun remove(topic: Topic) {
val currentList = topicsLiveData.value
if (currentList != null) {
val updatedList = currentList.toMutableList()
@ -47,7 +47,7 @@ class DataSource(resources: Resources) {
}
/* Returns topic given an ID. */
fun getTopicForId(id: Long): Topic? {
fun get(id: Long): Topic? {
topicsLiveData.value?.let { topics ->
return topics.firstOrNull{ it.id == id}
}
@ -59,12 +59,12 @@ class DataSource(resources: Resources) {
}
companion object {
private var INSTANCE: DataSource? = null
private var instance: DataSource? = null
fun getDataSource(resources: Resources): DataSource {
return synchronized(DataSource::class) {
val newInstance = INSTANCE ?: DataSource(resources)
INSTANCE = newInstance
val newInstance = instance ?: DataSource(resources)
instance = newInstance
newInstance
}
}

View file

@ -22,11 +22,13 @@ import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import io.heckel.ntfy.R
import io.heckel.ntfy.list.TOPIC_ID
import io.heckel.ntfy.TOPIC_ID
import io.heckel.ntfy.list.TopicsViewModel
import io.heckel.ntfy.list.TopicsViewModelFactory
class TopicDetailActivity : AppCompatActivity() {
private val topicDetailViewModel by viewModels<TopicDetailViewModel> {
TopicDetailViewModelFactory(this)
private val topicDetailViewModel by viewModels<TopicsViewModel> {
TopicsViewModelFactory(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
@ -47,12 +49,12 @@ class TopicDetailActivity : AppCompatActivity() {
/* If currentTopicId is not null, get corresponding topic and set name, image and
description */
currentTopicId?.let {
val currentTopic = topicDetailViewModel.getTopicForId(it)
val currentTopic = topicDetailViewModel.get(it)
topicUrl.text = currentTopic?.url
removeTopicButton.setOnClickListener {
if (currentTopic != null) {
topicDetailViewModel.removeTopic(currentTopic)
topicDetailViewModel.remove(currentTopic)
}
finish()
}

View file

@ -1,49 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* 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 io.heckel.ntfy.detail
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import io.heckel.ntfy.data.DataSource
import io.heckel.ntfy.data.Topic
class TopicDetailViewModel(private val datasource: DataSource) : ViewModel() {
/* Queries datasource to returns a topic that corresponds to an id. */
fun getTopicForId(id: Long) : Topic? {
return datasource.getTopicForId(id)
}
/* Queries datasource to remove a topic. */
fun removeTopic(topic: Topic) {
datasource.removeTopic(topic)
}
}
class TopicDetailViewModelFactory(private val context: Context) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(TopicDetailViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return TopicDetailViewModel(
datasource = DataSource.getDataSource(context.resources)
) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}