From 62f77ef8d02c0c76f09af946af471d7684515867 Mon Sep 17 00:00:00 2001 From: Daniel Dakhno Date: Thu, 23 Jun 2022 23:12:08 +0200 Subject: [PATCH] ControlCenter: added folders to ControlCenter --- .../gadgetbridge/daogen/GBDaoGenerator.java | 5 +- .../activities/ControlCenterv2.java | 1 + .../activities/DebugActivity.java | 2 +- .../adapter/GBDeviceAdapterv2.java | 421 +++++++++++++----- .../schema/GadgetbridgeUpdate_42.java | 38 ++ .../devices/AbstractDeviceCoordinator.java | 2 +- .../gadgetbridge/devices/DeviceManager.java | 2 +- .../gadgetbridge/impl/GBDevice.java | 45 +- .../gadgetbridge/impl/GBDeviceFolder.java | 9 + .../gadgetbridge/util/DeviceHelper.java | 6 +- .../gadgetbridge/util/StringUtils.java | 4 + .../main/res/drawable/ic_device_folder.xml | 23 + .../drawable/ic_device_folder_disabled.xml | 32 ++ app/src/main/res/layout/device_itemv2.xml | 33 +- ...ctivity_controlcenterv2_device_submenu.xml | 21 + app/src/main/res/values-de/strings.xml | 3 + app/src/main/res/values/strings.xml | 5 + 17 files changed, 505 insertions(+), 147 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_42.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceFolder.java create mode 100644 app/src/main/res/drawable/ic_device_folder.xml create mode 100644 app/src/main/res/drawable/ic_device_folder_disabled.xml create mode 100644 app/src/main/res/menu/activity_controlcenterv2_device_submenu.xml diff --git a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java index 11cda37c9..365fce34c 100644 --- a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java +++ b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java @@ -43,7 +43,7 @@ public class GBDaoGenerator { public static void main(String[] args) throws Exception { - final Schema schema = new Schema(38, MAIN_PACKAGE + ".entities"); + final Schema schema = new Schema(42, MAIN_PACKAGE + ".entities"); Entity userAttributes = addUserAttributes(schema); Entity user = addUserInfo(schema, userAttributes); @@ -181,8 +181,9 @@ public class GBDaoGenerator { device.addStringProperty("manufacturer").notNull(); device.addStringProperty("identifier").notNull().unique().javaDocGetterAndSetter("The fixed identifier, i.e. MAC address of the device."); device.addIntProperty("type").notNull().javaDocGetterAndSetter("The DeviceType key, i.e. the GBDevice's type."); - device.addStringProperty("model").javaDocGetterAndSetter("An optional model, further specifying the kind of device-"); + device.addStringProperty("model").javaDocGetterAndSetter("An optional model, further specifying the kind of device."); device.addStringProperty("alias"); + device.addStringProperty("parentFolder").javaDocGetterAndSetter("Folder name containing this device."); Property deviceId = deviceAttributes.addLongProperty("deviceId").notNull().getProperty(); // sorted by the from-date, newest first Property deviceAttributesSortProperty = getPropertyByName(deviceAttributes, VALID_FROM_UTC); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java index 0e9a24e0e..f3bde0f07 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java @@ -121,6 +121,7 @@ public class ControlCenterv2 extends AppCompatActivity case DeviceManager.ACTION_DEVICES_CHANGED: case GBApplication.ACTION_NEW_DATA: createRefreshTask("get activity data", getApplication()).execute(); + mGBDeviceAdapter.rebuildFolders(); refreshPairedDevices(); break; case DeviceService.ACTION_REALTIME_SAMPLES: diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index 33987a5f6..b9529206f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -769,7 +769,7 @@ public class DebugActivity extends AbstractGBActivity { try ( DBHandler db = GBApplication.acquireDB()) { DaoSession daoSession = db.getDaoSession(); - GBDevice gbDevice = new GBDevice(deviceMac, deviceType.name(), "", deviceType); + GBDevice gbDevice = new GBDevice(deviceMac, deviceType.name(), "", null, deviceType); gbDevice.setFirmwareVersion("N/A"); gbDevice.setFirmwareVersion2("N/A"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index fd2a8900a..a7e0e2bb3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -23,13 +23,17 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.res.Resources; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.text.InputType; import android.text.TextUtils; import android.transition.TransitionManager; +import android.util.ArraySet; import android.util.Pair; +import android.util.TypedValue; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; @@ -40,6 +44,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.NumberPicker; +import android.widget.PopupMenu; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; @@ -47,6 +52,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.cardview.widget.CardView; +import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.recyclerview.widget.RecyclerView; @@ -55,6 +61,7 @@ import com.github.mikephil.charting.data.PieData; import com.github.mikephil.charting.data.PieDataSet; import com.github.mikephil.charting.data.PieEntry; import com.github.mikephil.charting.utils.MPPointF; +import com.google.android.flexbox.FlexboxLayout; import com.google.android.material.snackbar.Snackbar; import com.jaredrummler.android.colorpicker.ColorPickerDialog; import com.jaredrummler.android.colorpicker.ColorPickerDialogListener; @@ -68,6 +75,7 @@ import java.util.Hashtable; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -78,7 +86,6 @@ import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms; import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureReminders; import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2; import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateDialog; -import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.VibrationActivity; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsActivity; @@ -90,6 +97,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceFolder; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; @@ -99,6 +107,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.FormatUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; /** * Adapter for displaying GBDevice instances. @@ -108,16 +117,52 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter deviceList; + private List devicesListWithFolders; private String expandedDeviceAddress = ""; + private String expandedFolderName = ""; private ViewGroup parent; private HashMap deviceActivityMap = new HashMap(); public GBDeviceAdapterv2(Context context, List deviceList, HashMap deviceMap) { this.context = context; this.deviceList = deviceList; + rebuildFolders(); this.deviceActivityMap = deviceMap; } + public void rebuildFolders(){ + this.devicesListWithFolders = enrichDeviceListWithFolder(deviceList); + } + + private List enrichDeviceListWithFolder(List deviceList) { + ArrayList enrichedList = new ArrayList<>(); + Set folders = new ArraySet<>(); + for(GBDevice device : deviceList){ + String parentFolder = device.getParentFolder(); + if(StringUtils.isNullOrEmpty(parentFolder)){ + enrichedList.add(device); + continue; + } + folders.add(parentFolder); + } + + for(String folder : folders){ + enrichedList.add(new GBDeviceFolder(folder)); + for(GBDevice potentialChild : deviceList){ + String parentFolder = potentialChild.getParentFolder(); + if(StringUtils.isNullOrEmpty(parentFolder)){ + continue; + } + if(!parentFolder.equals(folder)){ + continue; + } + enrichedList.add(potentialChild); + } + } + + return enrichedList; + } + @NonNull @Override public GBDeviceAdapterv2.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @@ -126,9 +171,94 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter