1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2025-02-22 18:04:45 +01:00

Add incognito mode in messages (#1970)

Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
This commit is contained in:
Mateusz Idziejczak 2023-07-26 22:17:58 +02:00 committed by GitHub
parent 91d7ee442e
commit 64cc24ae60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 96 additions and 17 deletions

View File

@ -3,18 +3,26 @@ package io.github.wulkanowy.data.repositories
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
import io.github.wulkanowy.data.*
import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.dao.MailboxDao
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.entities.*
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.enums.MessageFolder
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
import io.github.wulkanowy.data.enums.MessageFolder.TRASHED
import io.github.wulkanowy.data.mappers.mapFromEntities
import io.github.wulkanowy.data.mappers.mapToEntities
import io.github.wulkanowy.data.networkBoundResource
import io.github.wulkanowy.data.onResourceError
import io.github.wulkanowy.data.onResourceSuccess
import io.github.wulkanowy.data.pojos.MessageDraft
import io.github.wulkanowy.data.waitForResult
import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Folder
@ -25,7 +33,6 @@ import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.sync.Mutex
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import timber.log.Timber
@ -97,7 +104,7 @@ class MessageRepository @Inject constructor(
shouldFetch = {
checkNotNull(it) { "This message no longer exist!" }
Timber.d("Message content in db empty: ${it.message.content.isBlank()}")
it.message.unread || it.message.content.isBlank()
(it.message.unread && markAsRead) || it.message.content.isBlank()
},
query = {
messagesDb.loadMessageWithAttachment(message.messageGlobalKey)
@ -113,7 +120,10 @@ class MessageRepository @Inject constructor(
messagesDb.updateAll(
listOf(old.message.apply {
id = message.id
unread = !markAsRead
unread = when {
markAsRead -> false
else -> unread
}
sender = new.sender
recipients = new.recipients.singleOrNull() ?: "Wielu adresatów"
content = content.ifBlank { new.content }
@ -123,7 +133,7 @@ class MessageRepository @Inject constructor(
items = new.attachments.mapToEntities(message.messageGlobalKey),
)
Timber.d("Message ${message.messageId} with blank content: ${old.message.content.isBlank()}, marked as read")
Timber.d("Message ${message.messageId} with blank content: ${old.message.content.isBlank()}, marked as read: $markAsRead")
}
)

View File

@ -343,6 +343,12 @@ class PreferencesRepository @Inject constructor(
)
}
var isIncognitoMode: Boolean
get() = getBoolean(R.string.pref_key_incognito_moge, R.bool.pref_default_incognito_mode)
set(value) = sharedPref.edit {
putBoolean(context.getString(R.string.pref_key_incognito_moge), value)
}
var installationId: String
get() = sharedPref.getString(PREF_KEY_INSTALLATION_ID, null).orEmpty()
private set(value) = sharedPref.edit { putString(PREF_KEY_INSTALLATION_ID, value) }

View File

@ -11,7 +11,9 @@ import androidx.core.view.updateMargins
import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.enums.MessageFolder.*
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
import io.github.wulkanowy.data.enums.MessageFolder.SENT
import io.github.wulkanowy.data.enums.MessageFolder.TRASHED
import io.github.wulkanowy.databinding.FragmentMessageBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
@ -49,6 +51,7 @@ class MessageFragment : BaseFragment<FragmentMessageBinding>(R.layout.fragment_m
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMessageBinding.bind(view)
messageContainer = binding.messageViewPager
presenter.onAttachView(this)
}
@ -95,6 +98,10 @@ class MessageFragment : BaseFragment<FragmentMessageBinding>(R.layout.fragment_m
binding.messageProgress.visibility = if (show) VISIBLE else INVISIBLE
}
override fun showMessage(messageId: Int) {
showMessage(getString(messageId))
}
override fun showNewMessage(show: Boolean) {
binding.openSendMessageButton.run {
if (show) show() else hide()

View File

@ -1,5 +1,7 @@
package io.github.wulkanowy.ui.modules.message
import io.github.wulkanowy.R
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
@ -9,7 +11,8 @@ import javax.inject.Inject
class MessagePresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository
studentRepository: StudentRepository,
private val preferencesRepository: PreferencesRepository,
) : BasePresenter<MessageView>(errorHandler, studentRepository) {
override fun onAttachView(view: MessageView) {
@ -19,6 +22,14 @@ class MessagePresenter @Inject constructor(
Timber.i("Message view was initialized")
loadData()
}
showIncognitoModeReminderMessage()
}
private fun showIncognitoModeReminderMessage() {
if (preferencesRepository.isIncognitoMode) {
view?.showMessage(R.string.message_incognito_mode_on)
}
}
fun onPageSelected(index: Int) {

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.message
import androidx.annotation.StringRes
import io.github.wulkanowy.ui.base.BaseView
interface MessageView : BaseView {
@ -12,6 +13,8 @@ interface MessageView : BaseView {
fun showProgress(show: Boolean)
fun showMessage(@StringRes messageId: Int)
fun showNewMessage(show: Boolean)
fun showTabLayout(show: Boolean)

View File

@ -12,6 +12,7 @@ import android.view.View.VISIBLE
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.annotation.StringRes
import androidx.core.content.getSystemService
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
@ -164,6 +165,10 @@ class MessagePreviewFragment :
binding.messagePreviewErrorRetry.setOnClickListener { callback() }
}
override fun showMessage(@StringRes messageId: Int) {
showMessage(getString(messageId))
}
override fun openMessageReply(message: Message?) {
context?.let { it.startActivity(SendMessageActivity.getStartIntent(it, message, true)) }
}

View File

@ -2,11 +2,13 @@ package io.github.wulkanowy.ui.modules.message.preview
import android.annotation.SuppressLint
import androidx.core.text.parseAsHtml
import io.github.wulkanowy.R
import io.github.wulkanowy.data.*
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.enums.MessageFolder
import io.github.wulkanowy.data.repositories.MessageRepository
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
@ -20,6 +22,7 @@ class MessagePreviewPresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val messageRepository: MessageRepository,
private val preferencesRepository: PreferencesRepository,
private val analytics: AnalyticsHelper
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository) {
@ -54,7 +57,11 @@ class MessagePreviewPresenter @Inject constructor(
private fun loadData(messageToLoad: Message) {
flatResourceFlow {
val student = studentRepository.getCurrentStudent()
messageRepository.getMessage(student, messageToLoad, true)
messageRepository.getMessage(
student = student,
message = messageToLoad,
markAsRead = !preferencesRepository.isIncognitoMode,
)
}
.logResourceStatus("message ${messageToLoad.messageId} preview")
.onResourceData {
@ -65,6 +72,10 @@ class MessagePreviewPresenter @Inject constructor(
setMessageWithAttachment(it)
showContent(true)
initOptions()
if (preferencesRepository.isIncognitoMode && it.message.unread) {
showMessage(R.string.message_incognito_description)
}
}
} else {
view?.run {

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.message.preview
import androidx.annotation.StringRes
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.ui.base.BaseView
@ -43,4 +44,6 @@ interface MessagePreviewView : BaseView {
fun popView()
fun printDocument(html: String, jobName: String)
fun showMessage(@StringRes messageId: Int)
}

View File

@ -7,6 +7,7 @@ import android.view.MenuItem
import android.view.View
import android.view.View.*
import android.widget.CompoundButton
import androidx.annotation.StringRes
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.SearchView
import androidx.core.os.bundleOf
@ -134,14 +135,20 @@ class MessageTabFragment : BaseFragment<FragmentMessageTabBinding>(R.layout.frag
}
}
@Deprecated("Deprecated in Java")
@Suppress("DEPRECATION")
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.action_menu_message_tab, menu)
val searchView = menu.findItem(R.id.action_search).actionView as SearchView
searchView.queryHint = getString(R.string.all_search_hint)
searchView.maxWidth = Int.MAX_VALUE
initializeSearchView(menu)
}
private fun initializeSearchView(menu: Menu) {
val searchView = (menu.findItem(R.id.action_search).actionView as SearchView).apply {
queryHint = getString(R.string.all_search_hint)
maxWidth = Int.MAX_VALUE
}
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String) = false
override fun onQueryTextChange(query: String): Boolean {
@ -207,8 +214,8 @@ class MessageTabFragment : BaseFragment<FragmentMessageTabBinding>(R.layout.frag
binding.messageTabSwipe.isRefreshing = show
}
override fun showMessagesDeleted() {
showMessage(getString(R.string.message_messages_deleted))
override fun showMessage(@StringRes messageId: Int) {
showMessage(getString(messageId))
}
override fun notifyParentShowNewMessage(show: Boolean) {

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.message.tab
import io.github.wulkanowy.R
import io.github.wulkanowy.data.*
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Message
@ -26,7 +27,7 @@ class MessageTabPresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val messageRepository: MessageRepository,
private val analytics: AnalyticsHelper
private val analytics: AnalyticsHelper,
) : BasePresenter<MessageTabView>(errorHandler, studentRepository) {
lateinit var folder: MessageFolder
@ -135,7 +136,7 @@ class MessageTabPresenter @Inject constructor(
messageRepository.deleteMessages(student, selectedMailbox, messageList)
}
.onFailure(errorHandler::dispatch)
.onSuccess { view?.showMessagesDeleted() }
.onSuccess { view?.showMessage(R.string.message_messages_deleted) }
}
}

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.message.tab
import androidx.annotation.StringRes
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.ui.base.BaseView
@ -26,7 +27,7 @@ interface MessageTabView : BaseView {
fun showEmpty(show: Boolean)
fun showMessagesDeleted()
fun showMessage(@StringRes messageId: Int)
fun showErrorView(show: Boolean)

View File

@ -38,4 +38,5 @@
</string-array>
<bool name="pref_default_ads_enabled">false</bool>
<bool name="pref_default_ads_consent_data_processing">false</bool>
<bool name="pref_default_incognito_mode">false</bool>
</resources>

View File

@ -39,5 +39,6 @@
<string name="pref_key_ads_privacy_policy">ads_privacy_policy</string>
<string name="pref_key_ads_consent_data_processing">ads_consent_data_processing</string>
<string name="pref_key_ads_over_eighteen">ads_over_eighteen</string>
<string name="pref_key_incognito_moge">incognito_mode</string>
<string name="pref_key_menu_order">appearance_menu_order</string>
</resources>

View File

@ -339,6 +339,8 @@
</plurals>
<string name="message_messages_deleted">Messages deleted</string>
<string name="message_mailbox_chooser_title">Choose mailbox</string>
<string name="message_incognito_mode_on">Incognito mode is on</string>
<string name="message_incognito_description">Thanks to incognito mode sender is not notified when you read the message</string>
<!--Note-->
@ -728,6 +730,9 @@
<string name="pref_other_grade_modifier_minus">Value of the minus</string>
<string name="pref_other_fill_message_content">Reply with message history</string>
<string name="pref_other_optional_arithmetic_average">Show arithmetic average when no weights provided</string>
<string name="pref_other_incognito_mode">Incognito mode</string>
<string name="pref_other_incognito_mode_summary">Do not inform about reading the message</string>
<string name="pref_ads_support_category_name">Support</string>
<string name="pref_ads_privacy_policy">Privacy Policy</string>
<string name="pref_ads_agreements">Agreements</string>

View File

@ -53,5 +53,12 @@
app:key="@string/pref_key_fill_message_content"
app:singleLineTitle="false"
app:title="@string/pref_other_fill_message_content" />
<SwitchPreferenceCompat
app:defaultValue="@bool/pref_default_incognito_mode"
app:iconSpaceReserved="false"
app:key="@string/pref_key_incognito_moge"
app:singleLineTitle="false"
app:title="@string/pref_other_incognito_mode"
app:summary="@string/pref_other_incognito_mode_summary" />
</PreferenceCategory>
</PreferenceScreen>