Combine view models
This commit is contained in:
parent
18787d36e4
commit
1c6156c638
7 changed files with 34 additions and 72 deletions
|
@ -27,7 +27,7 @@
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity android:name="io.heckel.ntfy.list.TopicsListActivity">
|
<activity android:name="io.heckel.ntfy.MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.heckel.ntfy.list
|
package io.heckel.ntfy
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
|
@ -33,13 +33,14 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.google.gson.JsonSyntaxException
|
import com.google.gson.JsonSyntaxException
|
||||||
import io.heckel.ntfy.R
|
|
||||||
import io.heckel.ntfy.add.AddTopicActivity
|
import io.heckel.ntfy.add.AddTopicActivity
|
||||||
import io.heckel.ntfy.add.TOPIC_URL
|
import io.heckel.ntfy.add.TOPIC_URL
|
||||||
import io.heckel.ntfy.data.Topic
|
import io.heckel.ntfy.data.Topic
|
||||||
import io.heckel.ntfy.detail.TopicDetailActivity
|
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 kotlinx.coroutines.*
|
||||||
import java.io.BufferedReader
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
@ -47,12 +48,12 @@ import kotlin.random.Random
|
||||||
|
|
||||||
const val TOPIC_ID = "topic id"
|
const val TOPIC_ID = "topic id"
|
||||||
|
|
||||||
class TopicsListActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
private val gson = GsonBuilder().create()
|
private val gson = GsonBuilder().create()
|
||||||
private val jobs = mutableMapOf<Long, Job>()
|
private val jobs = mutableMapOf<Long, Job>()
|
||||||
private val newTopicActivityRequestCode = 1
|
private val newTopicActivityRequestCode = 1
|
||||||
private val topicsListViewModel by viewModels<TopicsListViewModel> {
|
private val topicsListViewModel by viewModels<TopicsViewModel> {
|
||||||
TopicsListViewModelFactory(this)
|
TopicsViewModelFactory(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
@ -23,19 +23,27 @@ import androidx.lifecycle.ViewModelProvider
|
||||||
import io.heckel.ntfy.data.DataSource
|
import io.heckel.ntfy.data.DataSource
|
||||||
import io.heckel.ntfy.data.Topic
|
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()
|
val topics: LiveData<List<Topic>> = dataSource.getTopicList()
|
||||||
|
|
||||||
fun add(topic: Topic) {
|
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 {
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
if (modelClass.isAssignableFrom(TopicsListViewModel::class.java)) {
|
if (modelClass.isAssignableFrom(TopicsViewModel::class.java)) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return TopicsListViewModel(
|
return TopicsViewModel(
|
||||||
dataSource = DataSource.getDataSource(context.resources)
|
dataSource = DataSource.getDataSource(context.resources)
|
||||||
) as T
|
) as T
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@ class DataSource(resources: Resources) {
|
||||||
private val topicsLiveData: MutableLiveData<List<Topic>> = MutableLiveData(mutableListOf())
|
private val topicsLiveData: MutableLiveData<List<Topic>> = MutableLiveData(mutableListOf())
|
||||||
|
|
||||||
/* Adds topic to liveData and posts value. */
|
/* Adds topic to liveData and posts value. */
|
||||||
fun addTopic(topic: Topic) {
|
fun add(topic: Topic) {
|
||||||
val currentList = topicsLiveData.value
|
val currentList = topicsLiveData.value
|
||||||
if (currentList == null) {
|
if (currentList == null) {
|
||||||
topicsLiveData.postValue(listOf(topic))
|
topicsLiveData.postValue(listOf(topic))
|
||||||
|
@ -37,7 +37,7 @@ class DataSource(resources: Resources) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Removes topic from liveData and posts value. */
|
/* Removes topic from liveData and posts value. */
|
||||||
fun removeTopic(topic: Topic) {
|
fun remove(topic: Topic) {
|
||||||
val currentList = topicsLiveData.value
|
val currentList = topicsLiveData.value
|
||||||
if (currentList != null) {
|
if (currentList != null) {
|
||||||
val updatedList = currentList.toMutableList()
|
val updatedList = currentList.toMutableList()
|
||||||
|
@ -47,7 +47,7 @@ class DataSource(resources: Resources) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns topic given an ID. */
|
/* Returns topic given an ID. */
|
||||||
fun getTopicForId(id: Long): Topic? {
|
fun get(id: Long): Topic? {
|
||||||
topicsLiveData.value?.let { topics ->
|
topicsLiveData.value?.let { topics ->
|
||||||
return topics.firstOrNull{ it.id == id}
|
return topics.firstOrNull{ it.id == id}
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,12 @@ class DataSource(resources: Resources) {
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var INSTANCE: DataSource? = null
|
private var instance: DataSource? = null
|
||||||
|
|
||||||
fun getDataSource(resources: Resources): DataSource {
|
fun getDataSource(resources: Resources): DataSource {
|
||||||
return synchronized(DataSource::class) {
|
return synchronized(DataSource::class) {
|
||||||
val newInstance = INSTANCE ?: DataSource(resources)
|
val newInstance = instance ?: DataSource(resources)
|
||||||
INSTANCE = newInstance
|
instance = newInstance
|
||||||
newInstance
|
newInstance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,13 @@ import android.widget.TextView
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import io.heckel.ntfy.R
|
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() {
|
class TopicDetailActivity : AppCompatActivity() {
|
||||||
private val topicDetailViewModel by viewModels<TopicDetailViewModel> {
|
private val topicDetailViewModel by viewModels<TopicsViewModel> {
|
||||||
TopicDetailViewModelFactory(this)
|
TopicsViewModelFactory(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
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
|
/* If currentTopicId is not null, get corresponding topic and set name, image and
|
||||||
description */
|
description */
|
||||||
currentTopicId?.let {
|
currentTopicId?.let {
|
||||||
val currentTopic = topicDetailViewModel.getTopicForId(it)
|
val currentTopic = topicDetailViewModel.get(it)
|
||||||
topicUrl.text = currentTopic?.url
|
topicUrl.text = currentTopic?.url
|
||||||
|
|
||||||
removeTopicButton.setOnClickListener {
|
removeTopicButton.setOnClickListener {
|
||||||
if (currentTopic != null) {
|
if (currentTopic != null) {
|
||||||
topicDetailViewModel.removeTopic(currentTopic)
|
topicDetailViewModel.remove(currentTopic)
|
||||||
}
|
}
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue