1 /*
<lambda>null2  * Copyright (C) 2019 The Android Open Source Project
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *       http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package com.example.android.bubbles.ui.chat
17 
18 import android.app.Application
19 import androidx.lifecycle.AndroidViewModel
20 import androidx.lifecycle.LiveData
21 import androidx.lifecycle.MutableLiveData
22 import androidx.lifecycle.Transformations
23 import com.example.android.bubbles.data.ChatRepository
24 import com.example.android.bubbles.data.Contact
25 import com.example.android.bubbles.data.DefaultChatRepository
26 import com.example.android.bubbles.data.Message
27 
28 class ChatViewModel @JvmOverloads constructor(
29     application: Application,
30     private val repository: ChatRepository = DefaultChatRepository.getInstance(application)
31 ) : AndroidViewModel(application) {
32 
33     private val chatId = MutableLiveData<Long>()
34 
35     /**
36      * We want to dismiss a notification when the corresponding chat screen is open. Setting this to `true` dismisses
37      * the current notification and suppresses further notifications.
38      *
39      * We do want to keep on showing and updating the notification when the chat screen is opened as an expanded bubble.
40      * [ChatFragment] should set this to false if it is launched in BubbleActivity. Otherwise, the expanding a bubble
41      * would remove the notification and the bubble.
42      */
43     var foreground = false
44         set(value) {
45             field = value
46             chatId.value?.let { id ->
47                 if (value) {
48                     repository.activateChat(id)
49                 } else {
50                     repository.deactivateChat(id)
51                 }
52             }
53         }
54 
55     /**
56      * The contact of this chat.
57      */
58     val contact: LiveData<Contact?> = Transformations.switchMap(chatId) { id ->
59         repository.findContact(id)
60     }
61 
62     /**
63      * The list of all the messages in this chat.
64      */
65     val messages: LiveData<List<Message>> = Transformations.switchMap(chatId) { id ->
66         repository.findMessages(id)
67     }
68 
69     /**
70      * Whether the "Show as Bubble" button should be shown.
71      */
72     val showAsBubbleVisible: LiveData<Boolean> = object: LiveData<Boolean>() {
73         override fun onActive() {
74             // We hide the "Show as Bubble" button if we are not allowed to show the bubble.
75             value = repository.canBubble()
76         }
77     }
78 
79     fun setChatId(id: Long) {
80         chatId.value = id
81         if (foreground) {
82             repository.activateChat(id)
83         } else {
84             repository.deactivateChat(id)
85         }
86     }
87 
88     fun send(text: String) {
89         val id = chatId.value
90         if (id != null && id != 0L) {
91             repository.sendMessage(id, text)
92         }
93     }
94 
95     fun showAsBubble() {
96         chatId.value?.let { id ->
97             repository.showAsBubble(id)
98         }
99     }
100 
101     override fun onCleared() {
102         chatId.value?.let { id -> repository.deactivateChat(id) }
103     }
104 }
105