Skip to content

Commit

Permalink
Merge pull request #2724 from BlueBubblesApp/development
Browse files Browse the repository at this point in the history
v1.13.1
  • Loading branch information
zlshames authored Apr 20, 2024
2 parents d0257c9 + 1d20fe9 commit 175fcb2
Show file tree
Hide file tree
Showing 55 changed files with 3,371 additions and 1,813 deletions.
37 changes: 19 additions & 18 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
Expand All @@ -12,11 +18,6 @@ if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
Expand All @@ -27,10 +28,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
namespace "com.bluebubbles.messaging"
compileSdk 34
Expand All @@ -47,15 +44,16 @@ android {
defaultConfig {
applicationId "com.bluebubbles.messaging"
minSdkVersion 23
targetSdkVersion 33
targetSdkVersion 34
versionCode 20002000 + flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

signingConfigs {
Expand Down Expand Up @@ -145,24 +143,24 @@ configurations.all {

dependencies {
// Android native functions
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "androidx.core:core-ktx:1.12.0"
implementation "androidx.sharetarget:sharetarget:1.2.0"
implementation 'androidx.browser:browser:1.7.0'
implementation 'androidx.browser:browser:1.8.0'
implementation 'androidx.activity:activity-ktx:1.8.2'
implementation "androidx.work:work-runtime:2.9.0"

// Firebase items
implementation 'com.google.firebase:firebase-messaging:23.4.0'
implementation 'com.google.firebase:firebase-database:20.3.0'
implementation 'com.google.firebase:firebase-messaging-directboot:23.4.0'
implementation 'com.google.firebase:firebase-messaging:23.4.1'
implementation 'com.google.firebase:firebase-database:20.3.1'
implementation 'com.google.firebase:firebase-messaging-directboot:23.4.1'
implementation 'com.google.firebase:firebase-iid:21.1.0'
implementation 'com.google.firebase:firebase-firestore:24.10.1'
implementation 'com.google.firebase:firebase-firestore:24.11.0'

// Kotlin Coroutines (async)
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0"

// Socket IO
implementation ('io.socket:socket.io-client:2.0.0') {
Expand All @@ -171,4 +169,7 @@ dependencies {

// JSON parsing
implementation 'com.google.code.gson:gson:2.10.1'

// For AGP 7.4+ desugaring
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,46 +24,55 @@ import io.flutter.view.FlutterCallbackInformation
import io.flutter.view.FlutterMain
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.util.Timer
import kotlin.concurrent.schedule
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.guava.future

class DartWorker(context: Context, workerParams: WorkerParameters): ListenableWorker(context, workerParams) {

companion object {
var workerEngine: FlutterEngine? = null
var engineReady = Mutex()
}

override fun startWork(): ListenableFuture<Result> {
val method = inputData.getString("method")!!
val data = inputData.getString("data")!!
if (engine == null && workerEngine == null) {
Log.d(Constants.logTag, "Initializing engine for worker with method $method")
initNewEngine()
}
val gson = GsonBuilder()
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.create()

if (engine != null) {
Log.d(Constants.logTag, "Using MainActivity engine to send to Dart")
} else {
Log.d(Constants.logTag, "Using DartWorker engine to send to Dart")
}
return CallbackToFutureAdapter.getFuture { completer ->
runBlocking {
Log.d(Constants.logTag, "Sending method $method to Dart")
val gson = GsonBuilder()
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.create()
return CoroutineScope(Dispatchers.Main).future {
engineReady.withLock {
if (engine == null && workerEngine == null) {
Log.d(Constants.logTag, "Initializing engine for worker with method $method")
initNewEngine()
}
}
Log.d(Constants.logTag, "Sending method $method to Dart")
suspendCoroutine { cont ->
MethodChannel((engine ?: workerEngine)!!.dartExecutor.binaryMessenger, Constants.methodChannel).invokeMethod(method, gson.fromJson(data, TypeToken.getParameterized(HashMap::class.java, String::class.java, Any::class.java).type), object : MethodChannel.Result {
override fun success(result: Any?) {
Log.d(Constants.logTag, "Worker with method $method completed successfully")
completer.set(Result.success())
cont.resume(Result.success())
closeEngineIfNeeded()
}

override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
Log.e(Constants.logTag, "Worker with method $method failed!")
completer.set(Result.failure())
cont.resume(Result.failure())
closeEngineIfNeeded()
}

Expand All @@ -74,7 +83,7 @@ class DartWorker(context: Context, workerParams: WorkerParameters): ListenableWo
}

/// Code idea taken from https://github.com/flutter/flutter/wiki/Experimental:-Reuse-FlutterEngine-across-screens
private fun initNewEngine() {
private suspend fun initNewEngine() {
Log.d(Constants.logTag, "Ensuring Flutter is initialized before creating engine")
// We use the deprecated class here anyways, the new one doesn't work correctly using the same code
FlutterMain.startInitialization(applicationContext)
Expand All @@ -83,15 +92,23 @@ class DartWorker(context: Context, workerParams: WorkerParameters): ListenableWo
Log.d(Constants.logTag, "Loading callback info")
val info = ApplicationInfoLoader.load(applicationContext)
workerEngine = FlutterEngine(applicationContext)
// set up the method channel to receive events from Dart
MethodChannel(workerEngine!!.dartExecutor.binaryMessenger, Constants.methodChannel).setMethodCallHandler {
call, result -> MethodCallHandler().methodCallHandler(call, result, applicationContext)
}
val callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(applicationContext.getSharedPreferences("FlutterSharedPreferences", 0).getLong("flutter.backgroundCallbackHandle", -1))
val callback = DartExecutor.DartCallback(applicationContext.assets, info.flutterAssetsDir, callbackInfo)
suspendCoroutine { cont ->
// set up the method channel to receive events from Dart
MethodChannel(workerEngine!!.dartExecutor.binaryMessenger, Constants.methodChannel).setMethodCallHandler {
call, result -> run {
if (call.method == "ready") {
cont.resume(Unit)
} else {
MethodCallHandler().methodCallHandler(call, result, applicationContext)
}
}
}
val callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(applicationContext.getSharedPreferences("FlutterSharedPreferences", 0).getLong("flutter.backgroundCallbackHandle", -1))
val callback = DartExecutor.DartCallback(applicationContext.assets, info.flutterAssetsDir, callbackInfo)

Log.d(Constants.logTag, "Executing Dart callback")
workerEngine!!.dartExecutor.executeDartCallback(callback)
Log.d(Constants.logTag, "Executing Dart callback")
workerEngine!!.dartExecutor.executeDartCallback(callback)
}
}

private fun closeEngineIfNeeded() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class BlueBubblesFirebaseMessagingService: FirebaseMessagingService() {
override fun success(result: Any?) {
Log.d(Constants.logTag, "Got URL: $result - sending to Tasker...")
val intent = Intent()
intent.setAction("net.dinglisch.android.taskerm.BB_SERVER_URL")
intent.setAction("net.dinglisch.android.taskerm.BB_EVENT")
intent.putExtra("url", result.toString())
intent.putExtra("event", type)
intent.putExtras(bundleOf(*message.data.toList().toTypedArray()))
Expand Down
14 changes: 0 additions & 14 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
buildscript {
ext.kotlin_version = '1.7.22'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
classpath 'com.google.gms:google-services:4.3.15'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
google()
Expand Down
5 changes: 3 additions & 2 deletions android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-all.zip
32 changes: 22 additions & 10 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
include ':app'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()

def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.3.1" apply false
id "com.android.library" version "8.3.1" apply false
id "org.jetbrains.kotlin.android" version "1.9.23" apply false
id "com.google.gms.google-services" version "4.4.1" apply false
}

include ":app"
36 changes: 36 additions & 0 deletions assets/changelog/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,42 @@

Below are the last few BlueBubbles App release changelogs

## v1.13.1

This update includes a couple of new minor features as well as a bunch of QOL enhancements and bug fixes.

### Enhancements

- Search improvements
- You can now filter based on chat, sender, and date
- Updates iOS emoji pack to iOS 17.4
- App stays connected when "inactive" but not necessarily hidden
- Hiding the full screen image viewer controls will now also hide the app bar
- Adds light haptic feedback when sending a message
- App startup time is now slightly quicker
- Location widgets now show the Apple Maps preview
- Adds ability to switch linked Google Firebase projects

### Bug Fixes

- Fixes issue delivering background messages (i.e. replies from notifications)
- Fixes issue where an event dispatched to tasker would have the wrong intent
- Fixes issue where a custom landing page for the server would break the detect localhost feature
- Fixes issue where the keyboard would be dismissed when trying to change GBoard languages
- Fixes issue where non-US phone numbers would be formatted incorrectly
- Fixes issue causing the device ID for the app to change when your phone updated
- Fixes issue where a new chat would not show up in the chat list until a full app restart (sometimes two)
- Fixes issue where the search would return case-sensitive results from the server. The search is now case-insensitive
- Fixes issue where the app would hang on startup due to a failed network request
- Fixes issue with infinite "Server Password" popups when connecting to your Google Account

### Developer Notes

- Increased target SDK to 34
- Upgraded a ton of dependencies
- iOS emoji pack now always links to the latest release
- This is so we don't need to update the app to push emoji font updates

## v1.13.0

This update sgnificantly overhauls the underlying Java code for the Android app, bringing better stability, fixing bugs, and more features.
Expand Down
Loading

0 comments on commit 175fcb2

Please sign in to comment.