From bd8ec5ea6a89c3d4891f90d444ecb1bf68df93e5 Mon Sep 17 00:00:00 2001 From: cooltey Date: Fri, 20 Oct 2023 14:45:59 -0700 Subject: [PATCH] Adding mutiple livedata --- .../diff/ArticleEditDetailsFragment.kt | 3 +- .../org/wikipedia/talk/TalkReplyActivity.kt | 85 ++++++++++++++++++- .../org/wikipedia/talk/TalkReplyViewModel.kt | 30 +++++++ .../template/TalkTemplatesTextInputDialog.kt | 9 ++ 4 files changed, 124 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt b/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt index 08eb176562c..be98be3a0ee 100644 --- a/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt +++ b/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt @@ -45,6 +45,7 @@ import org.wikipedia.page.edithistory.EditHistoryListActivity import org.wikipedia.page.linkpreview.LinkPreviewDialog import org.wikipedia.readinglist.AddToReadingListDialog import org.wikipedia.staticdata.UserAliasData +import org.wikipedia.staticdata.UserTalkAliasData import org.wikipedia.talk.TalkReplyActivity import org.wikipedia.talk.TalkTopicsActivity import org.wikipedia.talk.UserTalkPopupHelper @@ -275,7 +276,7 @@ class ArticleEditDetailsFragment : Fragment(), WatchlistExpiryDialog.Callback, L binding.warnButton.setOnClickListener { viewModel.revisionTo?.let { revision -> - val pageTitle = PageTitle(UserAliasData.valueFor(viewModel.pageTitle.wikiSite.languageCode), revision.user, viewModel.pageTitle.wikiSite) + val pageTitle = PageTitle(UserTalkAliasData.valueFor(viewModel.pageTitle.wikiSite.languageCode), revision.user, viewModel.pageTitle.wikiSite) requestWarn.launch(TalkReplyActivity.newIntent(requireContext(), pageTitle, null, null, invokeSource = InvokeSource.DIFF_ACTIVITY, fromDiff = true)) } } diff --git a/app/src/main/java/org/wikipedia/talk/TalkReplyActivity.kt b/app/src/main/java/org/wikipedia/talk/TalkReplyActivity.kt index 7972a75a25e..f6ae6ee71ad 100644 --- a/app/src/main/java/org/wikipedia/talk/TalkReplyActivity.kt +++ b/app/src/main/java/org/wikipedia/talk/TalkReplyActivity.kt @@ -37,6 +37,7 @@ import org.wikipedia.page.linkpreview.LinkPreviewDialog import org.wikipedia.readinglist.AddToReadingListDialog import org.wikipedia.staticdata.TalkAliasData import org.wikipedia.talk.template.TalkTemplatesActivity +import org.wikipedia.talk.template.TalkTemplatesTextInputDialog import org.wikipedia.util.ClipboardUtil import org.wikipedia.util.DeviceUtil import org.wikipedia.util.FeedbackUtil @@ -144,6 +145,24 @@ class TalkReplyActivity : BaseActivity(), LinkPreviewDialog.Callback, UserMentio } } + viewModel.loadTemplateData.observe(this) { + if (it is Resource.Success) { + // TODO: handle this + } else if (it is Resource.Error) { + FeedbackUtil.showError(this, it.throwable) + } + } + + viewModel.saveTemplateData.observe(this) { + if (it is Resource.Success) { + viewModel.talkTemplateSaved = true + binding.progressBar.isVisible = true + viewModel.postReply(it.data.subject, it.data.message) + } else if (it is Resource.Error) { + FeedbackUtil.showError(this, it.throwable) + } + } + SyntaxHighlightViewAdapter(this, viewModel.pageTitle, binding.root, binding.replyInputView.editText, binding.editKeyboardOverlay, binding.editKeyboardOverlayFormatting, binding.editKeyboardOverlayHeadings, Constants.InvokeSource.TALK_REPLY_ACTIVITY, requestInsertMedia, true) @@ -207,6 +226,10 @@ class TalkReplyActivity : BaseActivity(), LinkPreviewDialog.Callback, UserMentio } private fun setToolbarTitle(pageTitle: PageTitle) { + if (fromDiff) { + supportActionBar?.title = getString(R.string.talk_warn) + return + } val title = StringUtil.fromHtml( if (viewModel.isNewTopic) pageTitle.namespace.ifEmpty { TalkAliasData.valueFor(pageTitle.wikiSite.languageCode) } + ": " + "${StringUtil.removeNamespace(pageTitle.displayText)}" else intent.getStringExtra(EXTRA_PARENT_SUBJECT).orEmpty() @@ -258,6 +281,58 @@ class TalkReplyActivity : BaseActivity(), LinkPreviewDialog.Callback, UserMentio .getThemedColor(this, if (enabled) R.attr.progressive_color else R.attr.inactive_color)) } + private fun showSaveDialog(subject: String, body: String) { + TalkTemplatesTextInputDialog(this, R.string.talk_warn_save_dialog_publish, + R.string.talk_warn_save_dialog_cancel).let { textInputDialog -> + textInputDialog.callback = object : TalkTemplatesTextInputDialog.Callback { + override fun onShow(dialog: TalkTemplatesTextInputDialog) { + dialog.setTitleHint(R.string.talk_warn_save_dialog_hint) + dialog.setPositiveButtonEnabled(false) + } + + override fun onTextChanged(text: CharSequence, dialog: TalkTemplatesTextInputDialog) { + text.toString().trim().let { + when { + it.isEmpty() -> { + dialog.setError(null) + dialog.setPositiveButtonEnabled(false) + } + + viewModel.talkTemplatesList.any { item -> item.title == it } -> { + dialog.setError( + dialog.context.getString( + R.string.talk_templates_new_message_dialog_exists, + it + ) + ) + dialog.setPositiveButtonEnabled(false) + } + + else -> { + dialog.setError(null) + dialog.setPositiveButtonEnabled(true) + } + } + } + } + + override fun onSuccess(titleText: CharSequence, subjectText: CharSequence, bodyText: CharSequence) { + viewModel.saveTemplate(titleText.toString(), subject, body) + } + + override fun onCancel() { + setSaveButtonEnabled(true) + } + + override fun onDismiss() { + setSaveButtonEnabled(true) + } + } + textInputDialog.showTemplateCheckbox(true) + textInputDialog.setTitle(R.string.talk_warn_save_dialog_title) + }.show() + } + private fun onSaveClicked() { val subject = binding.replySubjectText.text.toString().trim() val body = binding.replyInputView.editText.text.toString().trim() @@ -278,10 +353,14 @@ class TalkReplyActivity : BaseActivity(), LinkPreviewDialog.Callback, UserMentio return } - binding.progressBar.visibility = View.VISIBLE setSaveButtonEnabled(false) - viewModel.postReply(subject, body) + if (fromDiff) { + showSaveDialog(subject, body) + } else { + binding.progressBar.visibility = View.VISIBLE + viewModel.postReply(subject, body) + } } private fun onSaveSuccess(newRevision: Long) { @@ -291,6 +370,8 @@ class TalkReplyActivity : BaseActivity(), LinkPreviewDialog.Callback, UserMentio setSaveButtonEnabled(true) EditAttemptStepEvent.logSaveSuccess(viewModel.pageTitle) + // TODO: return to diff screen with different message vs save to template + Intent().let { it.putExtra(RESULT_NEW_REVISION_ID, newRevision) it.putExtra(EXTRA_SUBJECT, binding.replySubjectText.text) diff --git a/app/src/main/java/org/wikipedia/talk/TalkReplyViewModel.kt b/app/src/main/java/org/wikipedia/talk/TalkReplyViewModel.kt index 34b1b31eaa7..87d95cac4ee 100644 --- a/app/src/main/java/org/wikipedia/talk/TalkReplyViewModel.kt +++ b/app/src/main/java/org/wikipedia/talk/TalkReplyViewModel.kt @@ -6,18 +6,28 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import kotlinx.coroutines.* import org.wikipedia.Constants +import org.wikipedia.database.AppDatabase import org.wikipedia.dataclient.ServiceFactory import org.wikipedia.dataclient.discussiontools.ThreadItem import org.wikipedia.extensions.parcelable import org.wikipedia.page.PageTitle +import org.wikipedia.talk.db.TalkTemplate +import org.wikipedia.talk.template.TalkTemplatesRepository import org.wikipedia.util.Resource import org.wikipedia.util.SingleLiveData class TalkReplyViewModel(bundle: Bundle) : ViewModel() { + private val talkTemplatesRepository = TalkTemplatesRepository(AppDatabase.instance.talkTemplateDao()) + + var talkTemplateSaved = false + val talkTemplatesList = mutableListOf() + val pageTitle = bundle.parcelable(Constants.ARG_TITLE)!! val topic = bundle.parcelable(TalkReplyActivity.EXTRA_TOPIC) val isNewTopic = topic == null val postReplyData = SingleLiveData>() + val saveTemplateData = SingleLiveData>() + val loadTemplateData = SingleLiveData>() fun postReply(subject: String, body: String) { viewModelScope.launch(CoroutineExceptionHandler { _, throwable -> @@ -33,6 +43,26 @@ class TalkReplyViewModel(bundle: Bundle) : ViewModel() { } } + fun saveTemplate(title: String, subject: String, body: String) { + viewModelScope.launch(CoroutineExceptionHandler { _, throwable -> + saveTemplateData.postValue(Resource.Error(throwable)) + }) { + val orderNumber = talkTemplatesRepository.getLastOrderNumber() + 1 + val talkTemplate = TalkTemplate(type = 0, order = orderNumber, title = title, subject = subject, message = body) + talkTemplatesRepository.insertTemplate(talkTemplate) + saveTemplateData.postValue(Resource.Success(talkTemplate)) + } + } + + private fun loadTemplates() { + viewModelScope.launch(CoroutineExceptionHandler { _, throwable -> + loadTemplateData.postValue(Resource.Error(throwable)) + }) { + talkTemplatesList.addAll(talkTemplatesRepository.getAllTemplates()) + loadTemplateData.postValue(Resource.Success(talkTemplatesList.size)) + } + } + class Factory(val bundle: Bundle) : ViewModelProvider.Factory { @Suppress("unchecked_cast") override fun create(modelClass: Class): T { diff --git a/app/src/main/java/org/wikipedia/talk/template/TalkTemplatesTextInputDialog.kt b/app/src/main/java/org/wikipedia/talk/template/TalkTemplatesTextInputDialog.kt index b125fc5fcd0..24cbb00827c 100644 --- a/app/src/main/java/org/wikipedia/talk/template/TalkTemplatesTextInputDialog.kt +++ b/app/src/main/java/org/wikipedia/talk/template/TalkTemplatesTextInputDialog.kt @@ -91,6 +91,15 @@ class TalkTemplatesTextInputDialog constructor(context: Context, binding.bodyTextInput.editText.addTextChangedListener(textWatcher) } + fun showTemplateCheckbox(show: Boolean) { + binding.dialogSaveAsNewCheckbox.isVisible = show + } + + fun showTemplateRadios(show: Boolean) { + binding.dialogSaveAsNewRadio.isVisible = show + binding.dialogSaveExistingRadio.isVisible = show + } + fun setDialogMessage(text: String) { binding.dialogMessage.text = text }