Loading app/ui/legacy/build.gradle.kts +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ android { buildFeatures { buildConfig = true aidl = true } buildTypes { Loading app/ui/legacy/src/main/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ <!-- Used by OpenPgpAppSelectDialog --> <action android:name="org.openintents.openpgp.IOpenPgpService" /> </intent> <package android:name="foundation.e.murenagenie" /> </queries> </manifest> app/ui/legacy/src/main/aidl/foundation/e/murenagenie/IAidlMurenaGenieInterface.aidl 0 → 100644 +6 −0 Original line number Diff line number Diff line // IAidlMurenaGenieInterface.aidl package foundation.e.murenagenie; interface IAidlMurenaGenieInterface { String generate(in String type, in String prompt); } app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt +68 −0 Original line number Diff line number Diff line Loading @@ -2,11 +2,14 @@ package com.fsck.k9.ui.messageview import android.app.Activity import android.content.ActivityNotFoundException import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.IntentSender import android.content.IntentSender.SendIntentException import android.content.ServiceConnection import android.os.Bundle import android.os.IBinder import android.os.Parcelable import android.os.SystemClock import android.view.ContextThemeWrapper Loading @@ -17,11 +20,13 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.core.app.ActivityCompat import androidx.core.content.withStyledAttributes import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.lifecycleScope import com.fsck.k9.Account import com.fsck.k9.K9 import com.fsck.k9.activity.MessageCompose Loading Loading @@ -52,7 +57,9 @@ import com.fsck.k9.ui.messageview.MessageCryptoPresenter.MessageCryptoMvpView import com.fsck.k9.ui.settings.account.AccountSettingsActivity import com.fsck.k9.ui.share.ShareIntentBuilder import com.fsck.k9.ui.withArguments import foundation.e.murenagenie.IAidlMurenaGenieInterface import java.util.Locale import kotlinx.coroutines.launch import org.koin.android.ext.android.inject import timber.log.Timber Loading Loading @@ -94,6 +101,18 @@ class MessageViewFragment : private var isActive: Boolean = false private set private var messageText: String? = null private var iAidlMurenaGenieInterface: IAidlMurenaGenieInterface? = null private val aidlServiceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { iAidlMurenaGenieInterface = IAidlMurenaGenieInterface.Stub.asInterface(service) } override fun onServiceDisconnected(name: ComponentName?) { } } override fun onAttach(context: Context) { super.onAttach(context) Loading Loading @@ -135,6 +154,25 @@ class MessageViewFragment : ) setFragmentResultListener(MessageDetailsFragment.FRAGMENT_RESULT_KEY, ::onMessageDetailsResult) bindMurenaGenieAidlService() } private fun bindMurenaGenieAidlService() { val intent = Intent() intent.setComponent( ComponentName( "foundation.e.murenagenie", "foundation.e.murenagenie.service.AidlService", ), ) /* val intent = Intent("foundation.e.murenagenie.generate") intent.setPackage("foundation.e.murenagenie"); */ context?.applicationContext?.bindService(intent, aidlServiceConnection, Context.BIND_AUTO_CREATE or Context.BIND_ABOVE_CLIENT) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { Loading Loading @@ -218,6 +256,8 @@ class MessageViewFragment : } else { messageLoaderHelper.onDestroy() } context?.applicationContext?.unbindService(aidlServiceConnection) } override fun onPrepareOptionsMenu(menu: Menu) { Loading Loading @@ -284,6 +324,7 @@ class MessageViewFragment : menu.findItem(R.id.single_message_options).isVisible = true menu.findItem(R.id.unsubscribe).isVisible = canMessageBeUnsubscribed() menu.findItem(R.id.show_headers).isVisible = true menu.findItem(R.id.ai_summarize).isVisible = true menu.findItem(R.id.compose).isVisible = true val toggleTheme = menu.findItem(R.id.toggle_message_view_theme) Loading Loading @@ -320,12 +361,28 @@ class MessageViewFragment : R.id.move_to_drafts -> onMoveToDrafts() R.id.unsubscribe -> onUnsubscribe() R.id.show_headers -> onShowHeaders() R.id.ai_summarize -> showAISummarizedText() else -> return false } return true } private fun showAISummarizedText() { lifecycleScope.launch { Toast.makeText(context, "Please wait!!!", Toast.LENGTH_SHORT).show() val result = iAidlMurenaGenieInterface?.generate("Summarize", messageText) AlertDialog.Builder(requireContext()) .setTitle("Summary of the message") .setMessage(result) .setPositiveButton("Done") { dialog, _ -> dialog.dismiss() } .show() } } private fun onShowHeaders() { val launchIntent = MessageSourceActivity.createLaunchIntent(requireActivity(), messageReference) startActivity(launchIntent) Loading Loading @@ -589,9 +646,11 @@ class MessageViewFragment : MessageDetailsFragment.ACTION_SEARCH_KEYS -> { messageCryptoPresenter.onClickSearchKey() } MessageDetailsFragment.ACTION_SHOW_WARNING -> { messageCryptoPresenter.onClickShowCryptoWarningDetails() } else -> { error("Unsupported action: $action") } Loading Loading @@ -685,6 +744,7 @@ class MessageViewFragment : cancelText, ) } R.id.dialog_confirm_spam -> { val title = getString(R.string.dialog_confirm_spam_title) val message = resources.getQuantityString(R.plurals.dialog_confirm_spam_message, 1) Loading @@ -698,6 +758,7 @@ class MessageViewFragment : cancelText, ) } R.id.dialog_attachment_progress -> { val currentAttachmentViewInfo = checkNotNull(this.currentAttachmentViewInfo) Loading @@ -705,6 +766,7 @@ class MessageViewFragment : val size = currentAttachmentViewInfo.size AttachmentDownloadDialogFragment.newInstance(size, message) } else -> { throw RuntimeException("Called showDialog(int) with unknown dialog id.") } Loading Loading @@ -781,9 +843,11 @@ class MessageViewFragment : putExtra(MessageCompose.EXTRA_ACCOUNT, messageReference.accountUuid) } } is HttpsUnsubscribeUri -> { Intent(Intent.ACTION_VIEW, unsubscribeUri.uri) } else -> error("Unknown UnsubscribeUri - $unsubscribeUri") } Loading Loading @@ -887,12 +951,16 @@ class MessageViewFragment : } override fun onMessageViewInfoLoadFinished(messageViewInfo: MessageViewInfo) { messageText = messageViewInfo.text showMessage(messageViewInfo) preferredUnsubscribeUri = messageViewInfo.preferredUnsubscribeUri showProgressThreshold = null } override fun onMessageViewInfoLoadFailed(messageViewInfo: MessageViewInfo) { messageText = null showMessage(messageViewInfo) preferredUnsubscribeUri = null showProgressThreshold = null Loading app/ui/legacy/src/main/res/menu/message_list_option.xml +7 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,13 @@ android:visible="false" app:showAsAction="never" /> <item android:id="@+id/ai_summarize" android:title="Summarize using AI" android:visible="false" app:showAsAction="never" /> <!-- always --> <item android:id="@+id/compose" Loading Loading
app/ui/legacy/build.gradle.kts +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ android { buildFeatures { buildConfig = true aidl = true } buildTypes { Loading
app/ui/legacy/src/main/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ <!-- Used by OpenPgpAppSelectDialog --> <action android:name="org.openintents.openpgp.IOpenPgpService" /> </intent> <package android:name="foundation.e.murenagenie" /> </queries> </manifest>
app/ui/legacy/src/main/aidl/foundation/e/murenagenie/IAidlMurenaGenieInterface.aidl 0 → 100644 +6 −0 Original line number Diff line number Diff line // IAidlMurenaGenieInterface.aidl package foundation.e.murenagenie; interface IAidlMurenaGenieInterface { String generate(in String type, in String prompt); }
app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt +68 −0 Original line number Diff line number Diff line Loading @@ -2,11 +2,14 @@ package com.fsck.k9.ui.messageview import android.app.Activity import android.content.ActivityNotFoundException import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.IntentSender import android.content.IntentSender.SendIntentException import android.content.ServiceConnection import android.os.Bundle import android.os.IBinder import android.os.Parcelable import android.os.SystemClock import android.view.ContextThemeWrapper Loading @@ -17,11 +20,13 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.core.app.ActivityCompat import androidx.core.content.withStyledAttributes import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.lifecycleScope import com.fsck.k9.Account import com.fsck.k9.K9 import com.fsck.k9.activity.MessageCompose Loading Loading @@ -52,7 +57,9 @@ import com.fsck.k9.ui.messageview.MessageCryptoPresenter.MessageCryptoMvpView import com.fsck.k9.ui.settings.account.AccountSettingsActivity import com.fsck.k9.ui.share.ShareIntentBuilder import com.fsck.k9.ui.withArguments import foundation.e.murenagenie.IAidlMurenaGenieInterface import java.util.Locale import kotlinx.coroutines.launch import org.koin.android.ext.android.inject import timber.log.Timber Loading Loading @@ -94,6 +101,18 @@ class MessageViewFragment : private var isActive: Boolean = false private set private var messageText: String? = null private var iAidlMurenaGenieInterface: IAidlMurenaGenieInterface? = null private val aidlServiceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { iAidlMurenaGenieInterface = IAidlMurenaGenieInterface.Stub.asInterface(service) } override fun onServiceDisconnected(name: ComponentName?) { } } override fun onAttach(context: Context) { super.onAttach(context) Loading Loading @@ -135,6 +154,25 @@ class MessageViewFragment : ) setFragmentResultListener(MessageDetailsFragment.FRAGMENT_RESULT_KEY, ::onMessageDetailsResult) bindMurenaGenieAidlService() } private fun bindMurenaGenieAidlService() { val intent = Intent() intent.setComponent( ComponentName( "foundation.e.murenagenie", "foundation.e.murenagenie.service.AidlService", ), ) /* val intent = Intent("foundation.e.murenagenie.generate") intent.setPackage("foundation.e.murenagenie"); */ context?.applicationContext?.bindService(intent, aidlServiceConnection, Context.BIND_AUTO_CREATE or Context.BIND_ABOVE_CLIENT) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { Loading Loading @@ -218,6 +256,8 @@ class MessageViewFragment : } else { messageLoaderHelper.onDestroy() } context?.applicationContext?.unbindService(aidlServiceConnection) } override fun onPrepareOptionsMenu(menu: Menu) { Loading Loading @@ -284,6 +324,7 @@ class MessageViewFragment : menu.findItem(R.id.single_message_options).isVisible = true menu.findItem(R.id.unsubscribe).isVisible = canMessageBeUnsubscribed() menu.findItem(R.id.show_headers).isVisible = true menu.findItem(R.id.ai_summarize).isVisible = true menu.findItem(R.id.compose).isVisible = true val toggleTheme = menu.findItem(R.id.toggle_message_view_theme) Loading Loading @@ -320,12 +361,28 @@ class MessageViewFragment : R.id.move_to_drafts -> onMoveToDrafts() R.id.unsubscribe -> onUnsubscribe() R.id.show_headers -> onShowHeaders() R.id.ai_summarize -> showAISummarizedText() else -> return false } return true } private fun showAISummarizedText() { lifecycleScope.launch { Toast.makeText(context, "Please wait!!!", Toast.LENGTH_SHORT).show() val result = iAidlMurenaGenieInterface?.generate("Summarize", messageText) AlertDialog.Builder(requireContext()) .setTitle("Summary of the message") .setMessage(result) .setPositiveButton("Done") { dialog, _ -> dialog.dismiss() } .show() } } private fun onShowHeaders() { val launchIntent = MessageSourceActivity.createLaunchIntent(requireActivity(), messageReference) startActivity(launchIntent) Loading Loading @@ -589,9 +646,11 @@ class MessageViewFragment : MessageDetailsFragment.ACTION_SEARCH_KEYS -> { messageCryptoPresenter.onClickSearchKey() } MessageDetailsFragment.ACTION_SHOW_WARNING -> { messageCryptoPresenter.onClickShowCryptoWarningDetails() } else -> { error("Unsupported action: $action") } Loading Loading @@ -685,6 +744,7 @@ class MessageViewFragment : cancelText, ) } R.id.dialog_confirm_spam -> { val title = getString(R.string.dialog_confirm_spam_title) val message = resources.getQuantityString(R.plurals.dialog_confirm_spam_message, 1) Loading @@ -698,6 +758,7 @@ class MessageViewFragment : cancelText, ) } R.id.dialog_attachment_progress -> { val currentAttachmentViewInfo = checkNotNull(this.currentAttachmentViewInfo) Loading @@ -705,6 +766,7 @@ class MessageViewFragment : val size = currentAttachmentViewInfo.size AttachmentDownloadDialogFragment.newInstance(size, message) } else -> { throw RuntimeException("Called showDialog(int) with unknown dialog id.") } Loading Loading @@ -781,9 +843,11 @@ class MessageViewFragment : putExtra(MessageCompose.EXTRA_ACCOUNT, messageReference.accountUuid) } } is HttpsUnsubscribeUri -> { Intent(Intent.ACTION_VIEW, unsubscribeUri.uri) } else -> error("Unknown UnsubscribeUri - $unsubscribeUri") } Loading Loading @@ -887,12 +951,16 @@ class MessageViewFragment : } override fun onMessageViewInfoLoadFinished(messageViewInfo: MessageViewInfo) { messageText = messageViewInfo.text showMessage(messageViewInfo) preferredUnsubscribeUri = messageViewInfo.preferredUnsubscribeUri showProgressThreshold = null } override fun onMessageViewInfoLoadFailed(messageViewInfo: MessageViewInfo) { messageText = null showMessage(messageViewInfo) preferredUnsubscribeUri = null showProgressThreshold = null Loading
app/ui/legacy/src/main/res/menu/message_list_option.xml +7 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,13 @@ android:visible="false" app:showAsAction="never" /> <item android:id="@+id/ai_summarize" android:title="Summarize using AI" android:visible="false" app:showAsAction="never" /> <!-- always --> <item android:id="@+id/compose" Loading