Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb38cfba authored by Fahim Salam Chowdhury's avatar Fahim Salam Chowdhury 👽
Browse files

feat: add summarize mail by using ai feature

parent 28888677
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ android {

    buildFeatures {
        buildConfig = true
        aidl = true
    }

    buildTypes {
+2 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@
            <!-- Used by OpenPgpAppSelectDialog -->
            <action android:name="org.openintents.openpgp.IOpenPgpService" />
        </intent>

        <package android:name="foundation.e.murenagenie" />
    </queries>

</manifest>
+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);
}
+68 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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

@@ -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)

@@ -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? {
@@ -218,6 +256,8 @@ class MessageViewFragment :
        } else {
            messageLoaderHelper.onDestroy()
        }

        context?.applicationContext?.unbindService(aidlServiceConnection)
    }

    override fun onPrepareOptionsMenu(menu: Menu) {
@@ -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)
@@ -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)
@@ -589,9 +646,11 @@ class MessageViewFragment :
            MessageDetailsFragment.ACTION_SEARCH_KEYS -> {
                messageCryptoPresenter.onClickSearchKey()
            }

            MessageDetailsFragment.ACTION_SHOW_WARNING -> {
                messageCryptoPresenter.onClickShowCryptoWarningDetails()
            }

            else -> {
                error("Unsupported action: $action")
            }
@@ -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)
@@ -698,6 +758,7 @@ class MessageViewFragment :
                    cancelText,
                )
            }

            R.id.dialog_attachment_progress -> {
                val currentAttachmentViewInfo = checkNotNull(this.currentAttachmentViewInfo)

@@ -705,6 +766,7 @@ class MessageViewFragment :
                val size = currentAttachmentViewInfo.size
                AttachmentDownloadDialogFragment.newInstance(size, message)
            }

            else -> {
                throw RuntimeException("Called showDialog(int) with unknown dialog id.")
            }
@@ -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")
        }

@@ -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
+7 −0
Original line number Diff line number Diff line
@@ -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