diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt index ef78d83..6cb1e17 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt @@ -2,7 +2,6 @@ package im.cwtch.flwtch import android.app.* import android.content.Context -import android.content.Context.ACTIVITY_SERVICE import android.content.Intent import android.graphics.BitmapFactory import android.graphics.Color @@ -24,7 +23,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : NotificationManager private var notificationID: MutableMap = mutableMapOf() - private var notificationIDnext: Int = 1; + private var notificationIDnext: Int = 1 override suspend fun doWork(): Result { val method = inputData.getString(KEY_METHOD) @@ -32,7 +31,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : val args = inputData.getString(KEY_ARGS) ?: return Result.failure() // Mark the Worker as important - val progress = "Trying to do a Flwtch"//todo:translate + val progress = "Cwtch is keeping Tor running in the background"//todo:translate setForeground(createForegroundInfo(progress)) return handleCwtch(method, args) } @@ -45,8 +44,8 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : return notificationID[k] ?: -1 } - private suspend fun handleCwtch(method: String, args: String): Result { - val a = JSONObject(args); + private fun handleCwtch(method: String, args: String): Result { + val a = JSONObject(args) when (method) { "Start" -> { Log.i("FlwtchWorker.kt", "handleAppInfo Start") @@ -54,12 +53,13 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : val torPath = (a.get("torPath") as? String) ?: "tor" Log.i("FlwtchWorker.kt", "appDir: '$appDir' torPath: '$torPath'") - if (Cwtch.startCwtch(appDir, torPath) != 0.toByte()) return Result.failure() + //todo: maybe change this back to toByte after lcg gets merged? not sure why it got changed + if (Cwtch.startCwtch(appDir, torPath) != 0.toLong()) return Result.failure() // infinite coroutine :) while(true) { val evt = MainActivity.AppbusEvent(Cwtch.getAppBusEvent()) - if (evt.EventType == "NewMessageFromPeer") { + if (evt.EventType == "NewMessageFromPeer" || evt.EventType == "NewMessageFromGroup") { val data = JSONObject(evt.Data) val channelId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -75,7 +75,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : val fh = applicationContext.assets.open(key) val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent -> - intent.setAction(Intent.ACTION_RUN) + intent.action = Intent.ACTION_RUN intent.putExtra("EventType", "NotificationClicked") intent.putExtra("ProfileOnion", data.getString("ProfileOnion")) intent.putExtra("RemotePeer", data.getString("RemotePeer")) @@ -83,7 +83,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : val newNotification = NotificationCompat.Builder(applicationContext, channelId) .setContentTitle(data.getString("Nick")) - .setContentText("New message") + .setContentText("New message")//todo: translate .setLargeIcon(BitmapFactory.decodeStream(fh)) .setSmallIcon(R.mipmap.knott) .setContentIntent(PendingIntent.getActivity(applicationContext, 1, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)) @@ -93,7 +93,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : } Intent().also { intent -> - intent.setAction("im.cwtch.flwtch.broadcast.SERVICE_EVENT_BUS") + intent.action = "im.cwtch.flwtch.broadcast.SERVICE_EVENT_BUS" intent.putExtra("EventType", evt.EventType) intent.putExtra("Data", evt.Data) intent.putExtra("EventID", evt.EventID) @@ -105,123 +105,124 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : Cwtch.reconnectCwtchForeground() } "SelectProfile" -> { - val onion = (a.get("profile") as? String) ?: ""; - Cwtch.selectProfile(onion) + //val onion = (a.get("profile") as? String) ?: "" + //todo: maybe remove or readd after lcg merge? not sure why + //Cwtch.selectProfile(onion) } "CreateProfile" -> { - val nick = (a.get("nick") as? String) ?: ""; - val pass = (a.get("pass") as? String) ?: ""; + val nick = (a.get("nick") as? String) ?: "" + val pass = (a.get("pass") as? String) ?: "" Cwtch.createProfile(nick, pass) } "LoadProfiles" -> { - val pass = (a.get("pass") as? String) ?: ""; + val pass = (a.get("pass") as? String) ?: "" Cwtch.loadProfiles(pass) } "GetProfiles" -> Result.success(Data.Builder().putString("result", Cwtch.getProfiles()).build()) // "ACNEvents" -> result.success(Cwtch.acnEvents()) "ContactEvents" -> Result.success(Data.Builder().putString("result", Cwtch.contactEvents()).build()) "NumMessages" -> { - val profile = (a.get("profile") as? String) ?: ""; - val handle = (a.get("contact") as? String) ?: ""; + val profile = (a.get("profile") as? String) ?: "" + val handle = (a.get("contact") as? String) ?: "" return Result.success(Data.Builder().putLong("result", Cwtch.numMessages(profile, handle)).build()) } "GetMessage" -> { - val profile = (a.get("profile") as? String) ?: ""; - val handle = (a.get("contact") as? String) ?: ""; - val indexI = a.getInt("index") ?: 0; - Log.i("FlwtchWorker.kt", "indexI = " + indexI) + val profile = (a.get("profile") as? String) ?: "" + val handle = (a.get("contact") as? String) ?: "" + val indexI = a.getInt("index") + Log.i("FlwtchWorker.kt", "indexI = $indexI") return Result.success(Data.Builder().putString("result", Cwtch.getMessage(profile, handle, indexI.toLong())).build()) } "GetMessages" -> { - val profile = (a.get("profile") as? String) ?: ""; - val handle = (a.get("contact") as? String) ?: ""; - val start = (a.get("start") as? Long) ?: 0; - val end = (a.get("end") as? Long) ?: 0; + val profile = (a.get("profile") as? String) ?: "" + val handle = (a.get("contact") as? String) ?: "" + val start = (a.get("start") as? Long) ?: 0 + val end = (a.get("end") as? Long) ?: 0 return Result.success(Data.Builder().putString("result", Cwtch.getMessages(profile, handle, start, end)).build()) } "UpdateMessageFlags" -> { - val profile = (a.get("profile") as? String) ?: ""; - val handle = (a.get("contact") as? String) ?: ""; - val midx = (a.get("midx") as? Long) ?: 0; - val flags = (a.get("flags") as? Long) ?: 0; - Cwtch.updateMessageFlags(profile, handle, midx, flags); + val profile = (a.get("profile") as? String) ?: "" + val handle = (a.get("contact") as? String) ?: "" + val midx = (a.get("midx") as? Long) ?: 0 + val flags = (a.get("flags") as? Long) ?: 0 + Cwtch.updateMessageFlags(profile, handle, midx, flags) } "AcceptContact" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val handle = (a.get("handle") as? String) ?: ""; - Cwtch.acceptContact(profile, handle); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val handle = (a.get("handle") as? String) ?: "" + Cwtch.acceptContact(profile, handle) } "BlockContact" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val handle = (a.get("handle") as? String) ?: ""; - Cwtch.blockContact(profile, handle); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val handle = (a.get("handle") as? String) ?: "" + Cwtch.blockContact(profile, handle) } "DebugResetContact" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val handle = (a.get("handle") as? String) ?: ""; - Cwtch.debugResetContact(profile, handle); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val handle = (a.get("handle") as? String) ?: "" + Cwtch.debugResetContact(profile, handle) } "SendMessage" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val handle = (a.get("handle") as? String) ?: ""; - val message = (a.get("message") as? String) ?: ""; - Cwtch.sendMessage(profile, handle, message); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val handle = (a.get("handle") as? String) ?: "" + val message = (a.get("message") as? String) ?: "" + Cwtch.sendMessage(profile, handle, message) } "SendInvitation" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val handle = (a.get("handle") as? String) ?: ""; - val target = (a.get("target") as? String) ?: ""; - Cwtch.sendInvitation(profile, handle, target); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val handle = (a.get("handle") as? String) ?: "" + val target = (a.get("target") as? String) ?: "" + Cwtch.sendInvitation(profile, handle, target) } "SendProfileEvent" -> { - val onion = (a.get("onion") as? String) ?: ""; - val jsonEvent = (a.get("jsonEvent") as? String) ?: ""; - Cwtch.sendProfileEvent(onion, jsonEvent); + val onion = (a.get("onion") as? String) ?: "" + val jsonEvent = (a.get("jsonEvent") as? String) ?: "" + Cwtch.sendProfileEvent(onion, jsonEvent) } "SendAppEvent" -> { - val jsonEvent = (a.get("jsonEvent") as? String) ?: ""; - Cwtch.sendAppEvent(jsonEvent); + val jsonEvent = (a.get("jsonEvent") as? String) ?: "" + Cwtch.sendAppEvent(jsonEvent) } "ResetTor" -> { - Cwtch.resetTor(); + Cwtch.resetTor() } "ImportBundle" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val bundle = (a.get("bundle") as? String) ?: ""; - Cwtch.importBundle(profile, bundle); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val bundle = (a.get("bundle") as? String) ?: "" + Cwtch.importBundle(profile, bundle) } "SetGroupAttribute" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val groupHandle = (a.get("groupHandle") as? String) ?: ""; - val key = (a.get("key") as? String) ?: ""; - val value = (a.get("value") as? String) ?: ""; - Cwtch.setGroupAttribute(profile, groupHandle, key, value); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val groupHandle = (a.get("groupHandle") as? String) ?: "" + val key = (a.get("key") as? String) ?: "" + val value = (a.get("value") as? String) ?: "" + Cwtch.setGroupAttribute(profile, groupHandle, key, value) } "CreateGroup" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val server = (a.get("server") as? String) ?: ""; - val groupName = (a.get("groupname") as? String) ?: ""; - Cwtch.createGroup(profile, server, groupName); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val server = (a.get("server") as? String) ?: "" + val groupName = (a.get("groupname") as? String) ?: "" + Cwtch.createGroup(profile, server, groupName) } "DeleteProfile" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val groupHandle = (a.get("pass") as? String) ?: ""; - Cwtch.deleteProfile(profile, groupHandle); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val groupHandle = (a.get("pass") as? String) ?: "" + Cwtch.deleteProfile(profile, groupHandle) } "LeaveConversation" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val contactHandle = (a.get("contactHandle") as? String) ?: ""; - Cwtch.leaveConversation(profile, contactHandle); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val contactHandle = (a.get("contactHandle") as? String) ?: "" + Cwtch.leaveConversation(profile, contactHandle) } "LeaveGroup" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val groupHandle = (a.get("groupHandle") as? String) ?: ""; - Cwtch.leaveGroup(profile, groupHandle); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val groupHandle = (a.get("groupHandle") as? String) ?: "" + Cwtch.leaveGroup(profile, groupHandle) } "RejectInvite" -> { - val profile = (a.get("ProfileOnion") as? String) ?: ""; - val groupHandle = (a.get("groupHandle") as? String) ?: ""; - Cwtch.rejectInvite(profile, groupHandle); + val profile = (a.get("ProfileOnion") as? String) ?: "" + val groupHandle = (a.get("groupHandle") as? String) ?: "" + Cwtch.rejectInvite(profile, groupHandle) } else -> return Result.failure() } @@ -233,20 +234,11 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : private fun createForegroundInfo(progress: String): ForegroundInfo { val id = "flwtch" val title = "Flwtch" - val cancel = "Nevermind"//todo: translate + val cancel = "Shut down"//todo: translate // This PendingIntent can be used to cancel the worker val intent = WorkManager.getInstance(applicationContext) .createCancelPendingIntent(getId()) - val channelId = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - createNotificationChannel(id, id) - } else { - // If earlier version channel ID is not used - // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) - "" - } - val notification = NotificationCompat.Builder(applicationContext, id) .setContentTitle(title) .setTicker(title) @@ -261,18 +253,6 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : return ForegroundInfo(101, notification) } - - @RequiresApi(Build.VERSION_CODES.O) - private fun createNotificationChannel(channelId: String, channelName: String): String{ - val chan = NotificationChannel(channelId, - channelName, NotificationManager.IMPORTANCE_NONE) - chan.lightColor = Color.MAGENTA - chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE - notificationManager.createNotificationChannel(chan) - return channelId - } - - @RequiresApi(Build.VERSION_CODES.O) private fun createMessageNotificationChannel(channelId: String, channelName: String): String{ val chan = NotificationChannel(channelId, @@ -287,10 +267,4 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : const val KEY_METHOD = "KEY_METHOD" const val KEY_ARGS = "KEY_ARGS" } - - class AppbusEvent(json: String) : JSONObject(json) { - val EventType = this.optString("EventType") - val EventID = this.optString("EventID") - val Data = this.optString("Data") - } } diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt index 4db21d5..e9a6d11 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt @@ -11,6 +11,7 @@ import android.os.Build import android.os.Bundle import android.os.Looper import android.util.Log +import android.view.Window import android.widget.Toast import androidx.annotation.RequiresApi import androidx.lifecycle.Observer @@ -74,6 +75,8 @@ class MainActivity: FlutterActivity() { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) // Note: this methods are invoked on the main thread. + //note to self: ask someone if this does anything ^ea + requestWindowFeature(Window.FEATURE_NO_TITLE) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_APP_INFO).setMethodCallHandler { call, result -> handleAppInfo(call, result) } MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_CWTCH).setMethodCallHandler { call, result -> handleCwtch(call, result) } methodChan = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NOTIF_CLICK) diff --git a/lib/views/messageview.dart b/lib/views/messageview.dart index 552a055..f9496b5 100644 --- a/lib/views/messageview.dart +++ b/lib/views/messageview.dart @@ -193,12 +193,12 @@ class _MessageViewState extends State { ), ElevatedButton( child: Text(AppLocalizations.of(bcontext)!.inviteBtn, semanticsLabel: AppLocalizations.of(bcontext)!.inviteBtn), - onPressed: this.selectedContact == "" - ? null - : () { - this._sendInvitation(); - Navigator.pop(bcontext); - }, + onPressed: () { + if (this.selectedContact != "") { + this._sendInvitation(); + } + Navigator.pop(bcontext); + }, ), ], )),