diff --git a/app/src/main/java/com/geeksville/mesh/DataPacket.kt b/app/src/main/java/com/geeksville/mesh/DataPacket.kt index 3346007ce..7f5f20b76 100644 --- a/app/src/main/java/com/geeksville/mesh/DataPacket.kt +++ b/app/src/main/java/com/geeksville/mesh/DataPacket.kt @@ -4,6 +4,8 @@ import android.os.Parcel import android.os.Parcelable import kotlinx.parcelize.Parcelize import kotlinx.serialization.Serializable +import java.nio.charset.Charset + @Parcelize enum class MessageStatus : Parcelable { @@ -143,6 +145,8 @@ data class DataPacket( override fun newArray(size: Int): Array { return arrayOfNulls(size) } + val utf8 = Charset.forName("UTF-8") } + } \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index f312bb667..1824a2238 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -7,10 +7,7 @@ import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothManager import android.companion.CompanionDeviceManager -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter +import android.content.* import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.hardware.usb.UsbDevice @@ -28,7 +25,9 @@ import android.view.View import android.widget.TextView import android.widget.Toast import androidx.activity.viewModels +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.widget.Toolbar import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -379,6 +378,9 @@ class MainActivity : AppCompatActivity(), Logging, val prefs = UIViewModel.getPreferences(this) model.ownerName.value = prefs.getString("owner", "")!! + /// Set theme + setUITheme(prefs) + /// Set initial bluetooth state updateBluetoothEnabled() @@ -1068,6 +1070,10 @@ class MainActivity : AppCompatActivity(), Logging, startActivityForResult(intent, CREATE_CSV_FILE) return true } + R.id.theme -> { + chooseThemeDialog() + return true + } else -> super.onOptionsItemSelected(item) } } @@ -1114,5 +1120,80 @@ class MainActivity : AppCompatActivity(), Logging, } } } + + + /// Theme functions + + private fun chooseThemeDialog() { + + /// Prepare dialog and its items + val builder = AlertDialog.Builder(this) + builder.setTitle(getString(R.string.choose_theme_title)) + + val styles = arrayOf( + getString(R.string.theme_light), + getString(R.string.theme_dark), + getString(R.string.theme_system)) + + /// Load preferences and its value + val prefs = UIViewModel.getPreferences(this) + val editor: SharedPreferences.Editor = prefs.edit() + val checkedItem = prefs.getInt("theme", 2) + + builder.setSingleChoiceItems(styles, checkedItem) { dialog, which -> + + when (which) { + 0 -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + editor.putInt("theme", 0) + editor.apply() + + delegate.applyDayNight() + dialog.dismiss() + } + 1 -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) + editor.putInt("theme", 1) + editor.apply() + + delegate.applyDayNight() + dialog.dismiss() + } + 2 -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) + editor.putInt("theme", 2) + editor.apply() + + delegate.applyDayNight() + dialog.dismiss() + } + + } + } + + val dialog = builder.create() + dialog.show() + } + + private fun setUITheme(prefs: SharedPreferences) { + /// Read theme settings from preferences and set it + /// If nothing is found set FOLLOW SYSTEM option + + when (prefs.getInt("theme", 2)) { + 0 -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + delegate.applyDayNight() + } + 1 -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) + delegate.applyDayNight() + } + 2 -> { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) + delegate.applyDayNight() + } + } + } + } diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index e1e6dfa30..0a61cd403 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -191,57 +191,27 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging { val oldDevs = devices.value!! val oldEntry = oldDevs[fullAddr] if (oldEntry == null || oldEntry.bonded != isBonded) { // Don't spam the GUI with endless updates for non changing nodes - - val skipBogus = try { - // Note Soyes XS has a buggy BLE scan implementation and returns devices we didn't ask for. So we check to see if the - // last two chars of the name matches the last two of the address - if not we skip it - - // Note: the address is always two more than the hex string we show in the name - - // nasty parsing of a string that ends with ab:45 as four hex digits - val lastAddr = (addr.substring( - addr.length - 5, - addr.length - 3 - ) + addr.substring(addr.length - 2)).toInt(16) - - val lastName = - result.device.name.substring(result.device.name.length - 4).toInt(16) - - // ESP32 macaddr are two higher than the reported device name - // NRF52 macaddrs match the portion used in the string - // either would be acceptable - (lastAddr - 2) != lastName && lastAddr != lastName - } catch (ex: Throwable) { - false // If we fail parsing anything, don't do this nasty hack + val entry = DeviceListEntry( + result.device.name + ?: "unnamed-$addr", // autobug: some devices might not have a name, if someone is running really old device code? + fullAddr, + isBonded + ) + // If nothing was selected, by default select the first valid thing we see + val activity: MainActivity? = try { + GeeksvilleApplication.currentActivity as MainActivity? // Can be null if app is shutting down + } catch (_: ClassCastException) { + // Buggy "Z812" phones apparently have the wrong class type for this + errormsg("Unexpected class for main activity") + null } - if (skipBogus) - errormsg("Skipping bogus BLE entry $result") - else { - val entry = DeviceListEntry( - result.device.name - ?: "unnamed-$addr", // autobug: some devices might not have a name, if someone is running really old device code? - fullAddr, - isBonded + if (selectedAddress == null && entry.bonded && activity != null) + changeScanSelection( + activity, + fullAddr ) - debug("onScanResult ${entry}") - - // If nothing was selected, by default select the first valid thing we see - val activity: MainActivity? = try { - GeeksvilleApplication.currentActivity as MainActivity? // Can be null if app is shutting down - } catch (_: ClassCastException) { - // Buggy "Z812" phones apparently have the wrong class type for this - errormsg("Unexpected class for main activity") - null - } - - if (selectedAddress == null && entry.bonded && activity != null) - changeScanSelection( - activity, - fullAddr - ) - addDevice(entry) // Add/replace entry - } + addDevice(entry) // Add/replace entry } } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index cf7de3c07..7608ff3cb 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -23,6 +23,7 @@ + app:srcCompat="@drawable/cloud_download_outline_24" + android:contentDescription="TODO" + app:tint="@color/colorIconTint" /> diff --git a/app/src/main/res/layout/advanced_settings.xml b/app/src/main/res/layout/advanced_settings.xml index 79f9fb0a8..690a745c7 100644 --- a/app/src/main/res/layout/advanced_settings.xml +++ b/app/src/main/res/layout/advanced_settings.xml @@ -3,8 +3,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="match_parent" android:background="#FFFFFF" - > + android:layout_height="match_parent" + android:background="@color/colorAdvancedBackground"> \ No newline at end of file + android:textAppearance="?attr/textAppearanceSubtitle1" + /> \ No newline at end of file diff --git a/app/src/main/res/layout/settings_fragment.xml b/app/src/main/res/layout/settings_fragment.xml index 352fab9a0..07650f079 100644 --- a/app/src/main/res/layout/settings_fragment.xml +++ b/app/src/main/res/layout/settings_fragment.xml @@ -132,7 +132,7 @@ android:layout_marginStart="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" - android:background="@color/cardview_light_background" + android:background="@android:color/transparent" android:checked="true" android:text="@string/analytics_okay" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 45f8e5cf0..03211deb0 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -24,6 +24,10 @@ android:id="@+id/save_messages_csv" app:showAsAction="withText" android:title="@string/save_messages" /> + + + #3700B3 + #3700B3 + #212121 + #212121 + #141414 + #141414 + #FFFFFF + #FFFFFF + #000000 + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 545dd613b..d8da3c610 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -4,4 +4,9 @@ #3700B3 #F2F2F2 #EDEAF4 + #FFFFFF + #FFFFFF + #000000 + #000000 + #FFFFFF diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1e930b4ac..85adfc271 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -103,4 +103,9 @@ Reset to defaults Apply No application found to send URLs + Theme + Light + Dark + System default + Choose theme diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e36ac68c6..eeaff9859 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,14 +1,14 @@ - - @@ -31,7 +31,7 @@ + + // Toolbar style +