From 6e6b50d0c235a7177532f93f2591474e14f59a7a Mon Sep 17 00:00:00 2001 From: "Alexander \"PapaTutuWawa" Date: Fri, 8 Sep 2023 19:40:03 +0200 Subject: [PATCH] feat: Move over the contacts API --- .../moxxy/moxxy_native/MoxxyNativePlugin.kt | 9 ++ .../moxxy_native/contacts/ContactsApi.kt | 94 ++++++++++++++++++ .../contacts/ContactsImplementation.kt | 67 +++++++++++++ android/src/main/res/mipmap-hdpi/notes.png | Bin 0 -> 911 bytes android/src/main/res/mipmap-hdpi/person.png | Bin 0 -> 1291 bytes android/src/main/res/mipmap-mdpi/notes.png | Bin 0 -> 701 bytes android/src/main/res/mipmap-mdpi/person.png | Bin 0 -> 828 bytes android/src/main/res/mipmap-xhdpi/notes.png | Bin 0 -> 1240 bytes android/src/main/res/mipmap-xhdpi/person.png | Bin 0 -> 1627 bytes android/src/main/res/mipmap-xxhdpi/notes.png | Bin 0 -> 1872 bytes android/src/main/res/mipmap-xxhdpi/person.png | Bin 0 -> 2545 bytes android/src/main/res/mipmap-xxxhdpi/notes.png | Bin 0 -> 2673 bytes .../src/main/res/mipmap-xxxhdpi/person.png | Bin 0 -> 3560 bytes lib/moxxy_native.dart | 1 + lib/pigeon/contacts.g.dart | 49 +++++++++ pigeon/contacts.dart | 29 ++++++ 16 files changed, 249 insertions(+) create mode 100644 android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsApi.kt create mode 100644 android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsImplementation.kt create mode 100644 android/src/main/res/mipmap-hdpi/notes.png create mode 100644 android/src/main/res/mipmap-hdpi/person.png create mode 100644 android/src/main/res/mipmap-mdpi/notes.png create mode 100644 android/src/main/res/mipmap-mdpi/person.png create mode 100644 android/src/main/res/mipmap-xhdpi/notes.png create mode 100644 android/src/main/res/mipmap-xhdpi/person.png create mode 100644 android/src/main/res/mipmap-xxhdpi/notes.png create mode 100644 android/src/main/res/mipmap-xxhdpi/person.png create mode 100644 android/src/main/res/mipmap-xxxhdpi/notes.png create mode 100644 android/src/main/res/mipmap-xxxhdpi/person.png create mode 100644 lib/pigeon/contacts.g.dart create mode 100644 pigeon/contacts.dart diff --git a/android/src/main/kotlin/org/moxxy/moxxy_native/MoxxyNativePlugin.kt b/android/src/main/kotlin/org/moxxy/moxxy_native/MoxxyNativePlugin.kt index 2236926..fa66d28 100644 --- a/android/src/main/kotlin/org/moxxy/moxxy_native/MoxxyNativePlugin.kt +++ b/android/src/main/kotlin/org/moxxy/moxxy_native/MoxxyNativePlugin.kt @@ -13,6 +13,8 @@ import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding import io.flutter.plugin.common.EventChannel +import org.moxxy.moxxy_native.contacts.ContactsImplementation +import org.moxxy.moxxy_native.contacts.MoxxyContactsApi import org.moxxy.moxxy_native.cryptography.CryptographyImplementation import org.moxxy.moxxy_native.cryptography.MoxxyCryptographyApi import org.moxxy.moxxy_native.notifications.MessagingNotification @@ -60,12 +62,19 @@ class MoxxyNativePlugin : FlutterPlugin, ActivityAware, MoxxyPickerApi, MoxxyNot private lateinit var activityClass: Class private lateinit var pickerListener: PickerResultListener private val cryptographyImplementation = CryptographyImplementation() + private lateinit var contactsImplementation: ContactsImplementation override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { context = flutterPluginBinding.applicationContext + contactsImplementation = ContactsImplementation(context!!) + + // Register the pigeon handlers MoxxyPickerApi.setUp(flutterPluginBinding.binaryMessenger, this) MoxxyNotificationsApi.setUp(flutterPluginBinding.binaryMessenger, this) MoxxyCryptographyApi.setUp(flutterPluginBinding.binaryMessenger, cryptographyImplementation) + MoxxyContactsApi.setUp(flutterPluginBinding.binaryMessenger, contactsImplementation) + + // Register the picker handler pickerListener = PickerResultListener(context!!) Log.d(TAG, "Attached to engine") } diff --git a/android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsApi.kt b/android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsApi.kt new file mode 100644 index 0000000..5236e9c --- /dev/null +++ b/android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsApi.kt @@ -0,0 +1,94 @@ +// Autogenerated from Pigeon (v11.0.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +package org.moxxy.moxxy_native.contacts + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer + +private fun wrapResult(result: Any?): List { + return listOf(result) +} + +private fun wrapError(exception: Throwable): List { + if (exception is FlutterError) { + return listOf( + exception.code, + exception.message, + exception.details + ) + } else { + return listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) + ) + } +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class FlutterError ( + val code: String, + override val message: String? = null, + val details: Any? = null +) : Throwable() + +/** The type of icon to use when no avatar path is provided. */ +enum class FallbackIconType(val raw: Int) { + NONE(0), + PERSON(1), + NOTES(2); + + companion object { + fun ofRaw(raw: Int): FallbackIconType? { + return values().firstOrNull { it.raw == raw } + } + } +} +/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ +interface MoxxyContactsApi { + fun recordSentMessage(name: String, jid: String, avatarPath: String?, fallbackIcon: FallbackIconType) + + companion object { + /** The codec used by MoxxyContactsApi. */ + val codec: MessageCodec by lazy { + StandardMessageCodec() + } + /** Sets up an instance of `MoxxyContactsApi` to handle messages through the `binaryMessenger`. */ + @Suppress("UNCHECKED_CAST") + fun setUp(binaryMessenger: BinaryMessenger, api: MoxxyContactsApi?) { + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyContactsApi.recordSentMessage", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val nameArg = args[0] as String + val jidArg = args[1] as String + val avatarPathArg = args[2] as String? + val fallbackIconArg = FallbackIconType.ofRaw(args[3] as Int)!! + var wrapped: List + try { + api.recordSentMessage(nameArg, jidArg, avatarPathArg, fallbackIconArg) + wrapped = listOf(null) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} diff --git a/android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsImplementation.kt b/android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsImplementation.kt new file mode 100644 index 0000000..3390624 --- /dev/null +++ b/android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsImplementation.kt @@ -0,0 +1,67 @@ +package org.moxxy.moxxy_native.contacts + +import android.content.Context +import android.content.Intent +import android.graphics.BitmapFactory +import androidx.core.app.Person +import androidx.core.content.pm.ShortcutInfoCompat +import androidx.core.content.pm.ShortcutManagerCompat +import androidx.core.graphics.drawable.IconCompat +import org.moxxy.moxxy_native.R + +/* + * Implementation of Moxxy's contact APIs. + * */ +class ContactsImplementation(private val context: Context) : MoxxyContactsApi { + override fun recordSentMessage( + name: String, + jid: String, + avatarPath: String?, + fallbackIcon: FallbackIconType + ) { + val pkgName = context.packageName + val intent = Intent(context, Class.forName("$pkgName.MainActivity")).apply { + action = Intent.ACTION_SEND + + // Compatibility with share_handler + putExtra("conversationIdentifier", jid) + } + + val shortcutTarget = "$pkgName.dynamic_share_target" + val shortcutBuilder = ShortcutInfoCompat.Builder(context, jid).apply { + setShortLabel(name) + setIsConversation() + setCategories(setOf(shortcutTarget)) + setIntent(intent) + setLongLived(true) + } + + val personBuilder = Person.Builder().apply { + setKey(jid) + setName(name) + } + + // Either set an avatar image OR a fallback icon + if (avatarPath != null) { + val icon = IconCompat.createWithAdaptiveBitmap( + BitmapFactory.decodeFile(avatarPath), + ) + shortcutBuilder.setIcon(icon) + personBuilder.setIcon(icon) + } else { + val resourceId = when(fallbackIcon) { + FallbackIconType.NONE, FallbackIconType.PERSON -> R.mipmap.person + FallbackIconType.NOTES -> R.mipmap.notes + } + val icon = IconCompat.createWithResource(context, resourceId) + shortcutBuilder.setIcon(icon) + personBuilder.setIcon(icon) + } + + shortcutBuilder.setPerson(personBuilder.build()) + ShortcutManagerCompat.addDynamicShortcuts( + context, + listOf(shortcutBuilder.build()), + ) + } +} \ No newline at end of file diff --git a/android/src/main/res/mipmap-hdpi/notes.png b/android/src/main/res/mipmap-hdpi/notes.png new file mode 100644 index 0000000000000000000000000000000000000000..0b7a673c614547a55c4624bcb90771837733a6b8 GIT binary patch literal 911 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U=H(iaSW-5dpq0TL!?mTczEy& z{fY@D9|c@wwT?t2U5<*$ik%z!a*?d{^_9WX{hX#ZaWO9}Te{`U0@K}BHDwLCz00rP z<;r)hZ#m+uB>ME-oAvjjV|60L-wDqr4t)wCVrDhc@X)< zNNUv`_T{%CDr1t0bY>(vgaoyy&t7V&d^)%L>8mxB)2r%_EjgoMGH22yO?AeZ$C$g5 zZIZ(J7QR>cA=Lc(^?~=-=E%H_cPyz`cg5whzS)!7>+8%MR>JV zdS-UoX3p5j8F`jNOD;QR2kY568X1+Vm;T_IwUZkpI8pj}{_|Ox`3g2Qtc?pg%x}&< zo8@+)qu!3?>>Qnp3$x!euUW>z`}_H!3ujI?$<6h+)4WE-gPYSy!I49Sqme~%f&zk|0h=In~l^|0^| zU;-Ny#@)nx>-mJgBJUhGIw!tV{oQD}W%J9VoeEa$FYmaxh6UWJ;|dda^H;z8&GLl( z%`MGPYZJCEIQuLA-(SmnyHnr(z1DlR$?Ubvm(R@a@9z6n_qq*g>p{lcZS{|TUdes% zA)RG4DgpE_*8a<=P*vs=8Ov(=W@f*d1># z*ai%euh;il&CV8^dMP_!N$2Go<(ZEgUCW-HI8b>)s>pw8mhGR-VR8j`58eEH<+~x9 zx1dy-t0lt;rkQeb{c07*vQA{ZSQxj$!<~g?YNhsVDW!WUNozh@S6}|q?wCBWG54#| zh68d}{MBA-FPS`HpC(%WIn&B9#YX?-uNTl?hAbD2jnVlpQf zBDJ!#vdTWJ-ne#Yc;58gTeh7EFH4xdyXOA6S$CC~L7Fc;yVJpR+pnRktIMn77k6d1 Wj+5WM#cO~Wjlt8^&t;ucLK6V|cA>Wb literal 0 HcmV?d00001 diff --git a/android/src/main/res/mipmap-hdpi/person.png b/android/src/main/res/mipmap-hdpi/person.png new file mode 100644 index 0000000000000000000000000000000000000000..5e527649557329f73d6a5a66def64a4ea3de1b1e GIT binary patch literal 1291 zcmV+m1@!ufP)Fy#dG2tR9+PVT|L3`Of{XGAjE?Lf5cV=g%?96z+D1JyQl(0jDsLCnP;D$kOZ@~gi8(D5b*<_V03ndix8>6nkjIy3dfSxr~* z`Kg8H52N8oIG6Pk$aJ(lGsq+6AyJAM^38e!St@Em=yCbbP&tq58&*f#YMn)y+XeyU~p5tRBES*-|K8f#1M zC^Qo{;Cc8F1VMelHD}n}E(>-YBXF>hJWG}K>5_G6_GKyw?7WCPpiQUMm1c@j? z1}H%WC_x5zMo@%Nd;_Dz)0|EE6!Tavjdc<)2s-uxqjNhL{e6Z}ZjKSl=~K*OIess$ z;~1_M#E*{DYh1+X1u;w}FX|K@_liDV>R}f*3xb@P30X=hFb?Cz9=36-AY5OjhGh}u zxHPnIT`JMfGHw<0>l?BFL-@7nLhfY?w+gzf$>GhANy@!!;Z{MvZI{EF;p_);FI%`(Q1UrO(|^bU$}v5muP64h zg-b|tlu>qC7Eua}JJ+MHC-$<1TLl4x9q;9j6IoeEF?ie<-?a#GfSUyY?FmMw zxAMEwNq&@EW%&<-1?H~spFtl1r->3l8bs(WelD<>FXJ@rt0T zp#&M=B|+MHMv135&*)Rki(?$e&4Tcm2G#iu zZQLXX7u@47@=wFt^t%(j1iNX2nVTRwc~oBcbR4j+g%9qNxh9Q(YOo~D88eirA=j#-SJnC@(f^<&?W z0a=g<*_u~1-*SEG%BnW7GH@%OuHf9mxu5fZ$3X^UX=rR{T+XMJom!b+LFMmePx& zV*LRP+ETIIB-WG&{sOUW8gnCQc5<9!voJfGxTfq^a9()Wusd_k`(|@)G7Swv9@az* zeDO}$;wI>U_hl*=gv|(l-!0YThh6yTGVD>J(30+ggKmJm(L*I~6{Rhp8+W97U^pe0 zzNaLz;wscbvWE<#C)Q&{X%7>!`Yb7zAR!UYFw>oTPOWXK8bBMCcr?FPk<=f5Hp*%t zDHD>ERhJ-S-9rgxBKf6}GavS`UUkBW$Lp)JnIno+T*Uxbg#RX-W<5v=X1nsaryXyP zvtD)5ZoWJ@eKa8zv)X39pwqAc9=DDAS+6>=0lfMK9=492V7=-j0@#EIz!!8H5r8j< zWCkdAEoQ*j$F=~)UjzuT7PVmPBLY+luyCEgmmAiCHTgca1#l7(fG>!odntVu(`)Qw zTY$PB;<^uzzC~cM-(qeX``8x1Nkjm?AhK|ka;z- z?h*KUzjhYy7;BkfO8_Sk0r-MWBLeURo#y`xP}hI%z6j19^XeNIY99-*UUkwA4W4wo zJ}}q4wv3y+a=?+20p3TlD-QyX4x`7x&bToEs(gI2ee&G5iFs)aa3co6s~c#&=Pndr z{Iv3hdTXqD#Dpq8^tJ5{`Nu-@lT+cP>~v)HCrzKjtCMIwr^3tG(a^_tfn7oT`S|`C z099VlNI4X2j-0>L(jUFJ|E4Qo?^Dg;FnU2xrsg%_!k9m{jecyR>~xtX^zzTdpZ jv@2WPr0T#5c|^Yft~kL=(Uh|U00000NkvXXu0mjfnR`SI literal 0 HcmV?d00001 diff --git a/android/src/main/res/mipmap-mdpi/person.png b/android/src/main/res/mipmap-mdpi/person.png new file mode 100644 index 0000000000000000000000000000000000000000..24b3b06e1b1fd0b446d3d4d278bf98690beb19ed GIT binary patch literal 828 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 N&W?v2O6>{P{sNMV_09kQ literal 0 HcmV?d00001 diff --git a/android/src/main/res/mipmap-xxhdpi/notes.png b/android/src/main/res/mipmap-xxhdpi/notes.png new file mode 100644 index 0000000000000000000000000000000000000000..c81ae4753840e7f4f70d2de269bbfe18daaf9304 GIT binary patch literal 1872 zcmbVNdobJi7MCty{04B_2!CL|e~xMNy3| zl_n)y5wDh_ptJ{uI+ZsK|8{Lp?L*^ z9SXM0ke36yIL4ir@0rC^>bZF5L4N^IesGcWmXc?bmzG`9x4v|%u5PQnekuU{n z-)3{iUsB)E0Ugs5gUCVi_#RonO>mom(~;@uqk?V!?#sJ&M+?EV~=|Gqs=V02F%q|6BL zG=h+KRZR$MWzWmvrxJN=M&u^GWJ*XvA&lXN2628)t*bjPP?N$7f9x2NB&c{uR-Dt_ zol1CZQ{fjSa%SS%&>gY6Zf01dyIl-yCHE8h zR_qL$&SWAMnJ{|o7a!OTqX&%bD;-{%H1|bhH`vsvG4TQYP5zZ^37~b|h*8723*Rd4 zSY;SG6wm(b5NkqgYPxJomhAgivAsT8T4bX7Ff7F_|5ghHQ)(sN@o^ymhhA>=7m)PG z(ry#6&K&2X(fr5V=@rx3mocx7{DKS(lvvNczo(nceNi^n-#3pf!>kQontia;qXrH! zb)_$(1ss80^7k3GWE`+qs2N%EyOlmT#3BJgv|xv9C8MgMmWS8%mI+`|QNubFn*Z$e zm)z-=x3*GEFunP403BxFS)ccfrvU_<0D^$`0?5-Kx{?|cLcjoz!C=r=NN6<;LsR~r zTw3@YTfyg1q3=kw0qX+{D2GIeeA`qSM z6G_z3cy09UOxn`=e!D~rz;OL%8si}Phh^ymvAkh=_%<~#O;sIw+01((WY6d4FaWe2 z48{Tq>fjn02AOgAcl&@1s&IHo*G0kNk}3qug#2@6dPw8p%~<92jqo=hdhP5}ABDAr zp5JEQI)nixtDjd{Azf@{7AxQoFT{UbiI~z8zs9lPXVsV2UUqH))7`-T_gDUx0*u#U zZe7yG6gM)7rYL^t+nCsrN1F9M4gGoY*MByTSE*UsyLCU0fYzI~ zB$$*3jrGkH1Ih*Or3tmz*<&@drf3n{;HPEv4B#DYmJXVhMdGZrLi zy-tVa#1!uMb9dAPZf|b2I#leueB;320bmraYlm*uiHS z(Ve2HAE%MV6)xIfG7g>95OKo#SmF5fL|W4Wa&fN2XLS!uLXLFBuDLaKd#5S&u47i^J$RfH_@ZXX?@ToZm-$H>#l?E* z5la$&eV_5&_UOvHh-c_9db}GztOviz>g}C;P@5Db>wGTt$mXX}--Nn3W|M=V4|5vL zzZU33JlZ`u{Z*AOX~c2lnrV^Ul_txBit&LRGM(-=)$=wFN_*tnN@xt4O=h(fPIft- z=Zvdl?&^*!Rk?58U?u?K(Y7&@Ys_dKyT5NP>ls@2)kU6m&c48b*8|5kCtk^k2l=6n zQxA$r^D~6i zO8>@w)5rgGI4)j;6U8;GtJq(6P%0F?=z{Htc;vIRTa|fo%#^DwyG^hdaJazVNaCAp zi`gMfwPh*L(%zY?O>Bg&1BJ&qVoCJc$?Eu_Nhi+tvHs0%f84PN~imN0~tM*uu^PWist6+YdMP-7ih={EbQLgPy_b6JpxpD z&~)W@*r%u%gsjC|Rjf>Q93e~?8+wHEo`jkhh7!i?ef4{@7BAMQsLcI!5%D(QD2Qgw Uh3&i56q{1X^{_jR?|3@(-@ZahCjbBd literal 0 HcmV?d00001 diff --git a/android/src/main/res/mipmap-xxhdpi/person.png b/android/src/main/res/mipmap-xxhdpi/person.png new file mode 100644 index 0000000000000000000000000000000000000000..55addb5320a1c87949d7371d6392ed4856df7b8d GIT binary patch literal 2545 zcmb7GXHXN^7M2hqO$i2Y1(7IaLsbG2MU;s2B4DElxbz}oKv7D>peRK`2&e=pL6#;V zE>e}YKX;tl8h3%dC`c~=W$D&$AxouA8`%a36kobr;APlSvFWcJS$r8>im zmEHhNARYkFA?sow@KEy-jT62;Rx%QaMx4HzT_KIu}m$K2h{)45kiEyms6wa$JwQ8IAUPFBCPtSv!c%`$v&cuqrJ zJyf}|cEj8`^z&W0X_R~l$?YVUv&;_aO6VC#fxpP2JD%PcEn>W?v>=``sHQhI^!2X2 z0!14;^?Ti-v8v!?o^`;t*oCA}HDJh*RjcTlkhq=FuREaZnQ70{omCTuxO?{7sg(Dtr3V0& zxzxGWjSY2?U;3J}x>c{5`Q$#X#xM<2bDYpbT){=*=^M?G7&mo8`3SGhRCQIx{N(7` z`zPX<{xE5-i)C^h6z9?>6mg$cOivDusCx>(Zw&Rsy;xKaa6m#4ypKq^!*^V52wP%; z9A+KFtpGXlin}8U4AIFEyN13*OoPWFp$GBmb}GP-b1_H)SePOJ1YAKvp+f%?wwL|C z)^q(yi^t`+5NO+)tP%`TWX7?wEn<&UmKY?+icn$}1>5WpM)bkd_8 z(`FLqg74LugUt`-TzKR6n>{vt!f=E~dgR``qb>oI)oD7X8@4pAD6DPTv&dc#uRVhu zMiR9p>ufyPQBa?OfY$wn z_2Su*g0{MXqlzy|mB28q%S%!%Rf**BgsGDKzyz^R!hQ#awX`bY{+bf<7FuyZ%A~T{ zTFQk10HD>HT_tH$Md)!)L>CDG6A0OC%Hzd?ZCek800E50Y${0mRxPIlvTY|OETxlE zrwqD{&@HHxsCC*d1)p zz_gp-ju2gcVQ9VeXV^(1=iHenkLPEyKk?6uhsye;LBn_V1U63(Y@Wb~G!|*=DlVjK zJ17V%(N=Q&zjn311((5xx)o4ClH5UgB=ITo@DW?X788ASQMjzqD5vmywXhSn_dJqF znPlXABUaC52KPJqAsGr~D5KY#>)7Q=M)wcBzNm)@w zp1y7aL#)Bdj#{<1x!kPc&%u|f^K($^-=V^~Ds#&6tE5fVpl%qarmgw-ie)H?-rJAP zM86zob4ORN9OT~)u->dbu(oY?yP)mamWjwA8vU%+fZSF(?Lop$kswf3Is*G{0kLJq z>ZG3fKpz?qtVg)lvuRKqa-mw6xgFC+&OY2?t*5))$F{2;Q(wzE3Z?s2kQwfD>4p=a zLfPDlXzj7d!|N?hP`jt8(O-0WgtTFwbB}N+T*?j#D|NW&`?1Ii5~hHzPXsAZk=2xYjaY$Bw;6_n)4fn2(KZdL4}1c0<1sGzDwFKnkgF?6c|ORW!H zxMBzW6m$Fh+|+@H49chRHCzn9bsj9S@oeZ1wXMGv?Rhc71@r5b23HSDfx;E3gssXwUh5GWfpVJB32grIZox4$FznwDXG;z^1^%H zJwcy*v{>JyA8b}bCY=Xnvc0)0%kJG{3jZpfw;LzBtexKb-LL&}wxlc1DZopwy@OuH zaJZLJR*}97|8>yug>-&?e(9HgWxlEZ;|KHXgZI3d(#H25WCbMw_p$nQGO+hk&1KNlh`-M2GdIt*Ul!40ekXkoa7FKJR)4 ze@l8nh4JYttag%LJb8jTO>f?c7@JFCaaf7vj6!LQ7rs8-*B(jug=J@&cD;W_yE`o| zJ8m0q7L1kgDL2?U8%7pzlE`c^SV|M{zDT&a(5Lg3l!j~92%t#C%Xr;$%eR^u&~U9( z@hb!Uhh?W%aHgvR;_BmB0aGk;!bMRH(xiPW;Buf&p?}my_;-5(foUJtcmE7T@JqRU N7ABXC$ws$g{tbut)n)(y literal 0 HcmV?d00001 diff --git a/android/src/main/res/mipmap-xxxhdpi/notes.png b/android/src/main/res/mipmap-xxxhdpi/notes.png new file mode 100644 index 0000000000000000000000000000000000000000..2f074bb65fef933401b998d62142c8a6e822f712 GIT binary patch literal 2673 zcmb_edoQ!14(S(wU2(jkuUwh8Zo}E4W$G!KD@7#O8bMHO(d^ddv z9xzQqO#lF3xZ_ygt=RU5LDjds?`RYR05reEVO{(aL&OCaqfSO3+EKiq5KX#^miC_c zDfiR6^fjZ@G_`k1x64w|(i*c|fjW?kd`lJVoqPi?{gNha_lPkz%<7 z79;&QT`iKqB-?*UL$hqAR!S_eap~1H(AG`juhubvZ;!B#G^!M`9ZeF49d|r8jczv@ zl@EIF(0OPi>X=>|sAO>Yk&$s)XST%@nLOz7@N(0<#TdDExW!WB-D30UCsI*dyj$JD z2pZzj1VT9jv}kosmDcznhKOI~Hm)9TA-JQ5{7(HcssSO_nq_&~nKN`IeyBHPe2z-V z@t9kHTW$1Bws_7(Tlf)bnq9`k=U4;ZX*aEOl z)vak^$}a zoV7r4rXT1qwe4|0YjIaf+?FH$e zHrvGc;}=G$QMa20cb>o1o8glv8%N99(l5PSOI1C-Ab!6~8&f=cRuubKB5$(qtFBs; z^oWKUO8Z2R@~)YAwIX7YyHSq5-^8QV4_Nltu_meDK|fSTsDWk+(Lp@=JSN z_2^9Y(|tpcNWcU{!4(WYStKj$%VGk{s_jlGNf@g{m%)L#ZTa0a zaRX%Lsi|)?vvnB*%o@6aE;THo#PE|&AvM)bwkrx10XN@f<+v+I{pgSLEpjM8#6JZ> znRT@;#I!rW^G@xxkNHB8F3^-41!_T0LoE3Xf^fqIBYh3fnmYK-#<>+stv^tB50Kp| zi=9rxr)HiBD3eT+Ydv0>>rdPqLRn*h+3%L1 zwqI`L^Z~^H{WG9RMHLu80{7HGZHJ*inG0YG1JfdP0dG1GX86BD7*KvAYK~ByD!~Yk z$S#Cx>9T;{4ZAr8ZdQjJ9bY4B06>}ms0psxVWMga22a7kJ3*i&2meemzfT9{F)usSyG~fjUtPgdWgD_)p>pk|h`uum_Z@Czdcd_|3Jb=|>~ULUmyVu_7c4?NBwHK*wOF<=®%bJ)d4^u40Qfvlm{Q^BXj3H8uoXxLs}P{cH=S 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 codec = StandardMessageCodec(); + + Future recordSentMessage(String arg_name, String arg_jid, String? arg_avatarPath, FallbackIconType arg_fallbackIcon) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.moxxy_native.MoxxyContactsApi.recordSentMessage', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_name, arg_jid, arg_avatarPath, arg_fallbackIcon.index]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } +} diff --git a/pigeon/contacts.dart b/pigeon/contacts.dart new file mode 100644 index 0000000..0f61260 --- /dev/null +++ b/pigeon/contacts.dart @@ -0,0 +1,29 @@ +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/pigeon/contacts.g.dart', + kotlinOut: + 'android/src/main/kotlin/org/moxxy/moxxy_native/contacts/ContactsApi.kt', + kotlinOptions: KotlinOptions( + package: 'org.moxxy.moxxy_native.contacts', + ), + ), +) + +/// The type of icon to use when no avatar path is provided. +enum FallbackIconType { + none, + person, + notes; +} + +@HostApi() +abstract class MoxxyContactsApi { + void recordSentMessage( + String name, + String jid, + String? avatarPath, + FallbackIconType fallbackIcon, + ); +}