mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-23 17:17:46 +01:00
Dashboard: Show widgets preview in preferences
This commit is contained in:
parent
2ad7f8aef9
commit
d71c50150e
@ -238,6 +238,7 @@ public class DashboardFragment extends Fragment implements MenuProvider {
|
||||
if (widget == null) {
|
||||
continue;
|
||||
}
|
||||
widget.reloadPreferences();
|
||||
if ("today".equals(widgetName) || "goals".equals(widgetName)) {
|
||||
columnSpan = prefs.getBoolean("dashboard_widget_" + widgetName + "_2columns", true) ? 2 : 1;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.InputType;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
@ -31,6 +32,7 @@ import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.preferences.DashboardWidgetPreviewPreference;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
|
||||
public class DashboardPreferencesActivity extends AbstractSettingsActivityV2 {
|
||||
@ -51,6 +53,9 @@ public class DashboardPreferencesActivity extends AbstractSettingsActivityV2 {
|
||||
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
|
||||
setPreferencesFromResource(R.xml.dashboard_preferences, rootKey);
|
||||
|
||||
final DashboardWidgetPreviewPreference previewToday = findPreference("dashboard_widget_preview_today");
|
||||
final DashboardWidgetPreviewPreference previewGoals = findPreference("dashboard_widget_preview_goals");
|
||||
|
||||
setInputTypeFor("dashboard_widget_today_hr_interval", InputType.TYPE_CLASS_NUMBER);
|
||||
|
||||
final MultiSelectListPreference dashboardDevices = findPreference("dashboard_devices_multiselect");
|
||||
@ -78,11 +83,21 @@ public class DashboardPreferencesActivity extends AbstractSettingsActivityV2 {
|
||||
"dashboard_devices_multiselect"
|
||||
);
|
||||
Preference pref;
|
||||
final Handler handler = new Handler(requireContext().getMainLooper());
|
||||
for (String dashboardPref : dashboardPrefs) {
|
||||
pref = findPreference(dashboardPref);
|
||||
if (pref != null) {
|
||||
pref.setOnPreferenceChangeListener((preference, autoExportEnabled) -> {
|
||||
sendDashboardConfigChangedIntent();
|
||||
// Delay so preferences are persisted
|
||||
handler.postDelayed(() -> {
|
||||
if (previewToday != null) {
|
||||
previewToday.refresh();
|
||||
}
|
||||
if (previewGoals != null) {
|
||||
previewGoals.refresh();
|
||||
}
|
||||
}, 500);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -28,9 +28,6 @@ import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
@ -43,8 +40,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public abstract class AbstractDashboardWidget extends Fragment {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractDashboardWidget.class);
|
||||
|
||||
protected static String ARG_DASHBOARD_DATA = "dashboard_widget_argument_data";
|
||||
|
||||
protected DashboardData dashboardData;
|
||||
@ -70,9 +65,14 @@ public abstract class AbstractDashboardWidget extends Fragment {
|
||||
}
|
||||
|
||||
public void update() {
|
||||
reloadPreferences();
|
||||
fillData();
|
||||
}
|
||||
|
||||
public void reloadPreferences() {
|
||||
|
||||
}
|
||||
|
||||
protected abstract void fillData();
|
||||
|
||||
protected boolean isSupportedBy(final GBDevice device) {
|
||||
|
@ -49,6 +49,7 @@ public class DashboardGoalsWidget extends AbstractDashboardWidget {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DashboardGoalsWidget.class);
|
||||
private View goalsView;
|
||||
private ImageView goalsChart;
|
||||
private TextView legend;
|
||||
|
||||
public DashboardGoalsWidget() {
|
||||
// Required empty public constructor
|
||||
@ -75,7 +76,7 @@ public class DashboardGoalsWidget extends AbstractDashboardWidget {
|
||||
goalsChart = goalsView.findViewById(R.id.dashboard_goals_chart);
|
||||
|
||||
// Initialize legend
|
||||
TextView legend = goalsView.findViewById(R.id.dashboard_goals_legend);
|
||||
legend = goalsView.findViewById(R.id.dashboard_goals_legend);
|
||||
SpannableString l_steps = new SpannableString("■ " + getString(R.string.steps));
|
||||
l_steps.setSpan(new ForegroundColorSpan(color_activity), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
SpannableString l_distance = new SpannableString("■ " + getString(R.string.distance));
|
||||
@ -87,9 +88,6 @@ public class DashboardGoalsWidget extends AbstractDashboardWidget {
|
||||
SpannableStringBuilder legendBuilder = new SpannableStringBuilder();
|
||||
legend.setText(legendBuilder.append(l_steps).append(" ").append(l_distance).append("\n").append(l_active_time).append(" ").append(l_sleep));
|
||||
|
||||
Prefs prefs = GBApplication.getPrefs();
|
||||
legend.setVisibility(prefs.getBoolean("dashboard_widget_goals_legend", true) ? View.VISIBLE : View.GONE);
|
||||
|
||||
return goalsView;
|
||||
}
|
||||
|
||||
@ -99,6 +97,14 @@ public class DashboardGoalsWidget extends AbstractDashboardWidget {
|
||||
if (goalsChart != null) fillData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadPreferences() {
|
||||
super.reloadPreferences();
|
||||
|
||||
final Prefs prefs = GBApplication.getPrefs();
|
||||
legend.setVisibility(prefs.getBoolean("dashboard_widget_goals_legend", true) ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillData() {
|
||||
if (goalsView == null) return;
|
||||
|
@ -70,6 +70,7 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
||||
|
||||
private View todayView;
|
||||
private ImageView todayChart;
|
||||
private TextView legend;
|
||||
|
||||
private boolean mode_24h;
|
||||
|
||||
@ -92,18 +93,26 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadPreferences() {
|
||||
super.reloadPreferences();
|
||||
|
||||
final Prefs prefs = GBApplication.getPrefs();
|
||||
|
||||
// Determine whether to draw a single or a double chart. In case 24h mode is selected,
|
||||
// use just the outer chart (chart_12_24) for all data.
|
||||
mode_24h = prefs.getBoolean("dashboard_widget_today_24h", false);
|
||||
|
||||
legend.setVisibility(prefs.getBoolean("dashboard_widget_today_legend", true) ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
todayView = inflater.inflate(R.layout.dashboard_widget_today, container, false);
|
||||
todayChart = todayView.findViewById(R.id.dashboard_today_chart);
|
||||
|
||||
// Determine whether to draw a single or a double chart. In case 24h mode is selected,
|
||||
// use just the outer chart (chart_12_24) for all data.
|
||||
Prefs prefs = GBApplication.getPrefs();
|
||||
mode_24h = prefs.getBoolean("dashboard_widget_today_24h", false);
|
||||
|
||||
// Initialize legend
|
||||
TextView legend = todayView.findViewById(R.id.dashboard_piechart_legend);
|
||||
legend = todayView.findViewById(R.id.dashboard_piechart_legend);
|
||||
SpannableString l_not_worn = new SpannableString("■ " + getString(R.string.abstract_chart_fragment_kind_not_worn));
|
||||
l_not_worn.setSpan(new ForegroundColorSpan(color_not_worn), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
SpannableString l_worn = new SpannableString("■ " + getString(R.string.activity_type_worn));
|
||||
@ -121,8 +130,6 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
||||
SpannableStringBuilder legendBuilder = new SpannableStringBuilder();
|
||||
legend.setText(legendBuilder.append(l_not_worn).append(" ").append(l_worn).append("\n").append(l_activity).append(" ").append(l_exercise).append("\n").append(l_light_sleep).append(" ").append(l_deep_sleep).append(" ").append(l_rem_sleep));
|
||||
|
||||
legend.setVisibility(prefs.getBoolean("dashboard_widget_today_legend", true) ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (!dashboardData.generalizedActivities.isEmpty()) {
|
||||
draw();
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.dashboard.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentContainerView;
|
||||
import androidx.gridlayout.widget.GridLayout;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.AbstractDashboardWidget;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.data.DashboardData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.widgets.DashboardWidgetFactory;
|
||||
|
||||
public class DashboardWidgetPreviewPreference extends Preference {
|
||||
private final String widgetName;
|
||||
private AbstractDashboardWidget widget;
|
||||
private DashboardData dashboardData;
|
||||
|
||||
public DashboardWidgetPreviewPreference(@NonNull final Context context,
|
||||
@Nullable final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setPersistent(false);
|
||||
|
||||
// Obtain custom attributes
|
||||
try (TypedArray a = context.getTheme().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.DashboardWidgetPreviewPreference,
|
||||
0, 0)) {
|
||||
if (attrs != null) {
|
||||
widgetName = a.getString(R.styleable.DashboardWidgetPreviewPreference_widgetName);
|
||||
} else {
|
||||
widgetName = null;
|
||||
}
|
||||
}
|
||||
setLayoutResource(R.layout.dashboard_widget_preview_preference);
|
||||
setWidgetLayoutResource(R.layout.dashboard_widget_preview_empty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
|
||||
dashboardData = new DashboardData();
|
||||
dashboardData.reloadPreferences(GregorianCalendar.getInstance());
|
||||
|
||||
if (widget == null) {
|
||||
widget = DashboardWidgetFactory.createWidget(widgetName, dashboardData);
|
||||
if (widget == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final FragmentActivity activity = (FragmentActivity) getContext();
|
||||
|
||||
final int columnSpan = 1;
|
||||
|
||||
final GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams(
|
||||
GridLayout.spec(GridLayout.UNDEFINED, GridLayout.FILL, 1f),
|
||||
GridLayout.spec(GridLayout.UNDEFINED, columnSpan, GridLayout.FILL, 1f)
|
||||
);
|
||||
final float scale = activity.getResources().getDisplayMetrics().density;
|
||||
layoutParams.width = 0;
|
||||
final int pixels_8dp = (int) (8 * scale + 0.5f);
|
||||
layoutParams.setMargins(pixels_8dp, pixels_8dp, pixels_8dp, pixels_8dp);
|
||||
|
||||
final FragmentContainerView fragment = new FragmentContainerView(activity);
|
||||
int fragmentId = View.generateViewId();
|
||||
fragment.setId(fragmentId);
|
||||
fragment.setLayoutParams(layoutParams);
|
||||
|
||||
activity.getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(fragmentId, widget)
|
||||
.commitAllowingStateLoss();
|
||||
|
||||
final GridLayout gridlayout = (GridLayout) holder.findViewById(R.id.widget_preview_gridlayout);
|
||||
gridlayout.addView(fragment);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
if (dashboardData != null) {
|
||||
dashboardData.reloadPreferences(GregorianCalendar.getInstance());
|
||||
}
|
||||
if (widget != null) {
|
||||
widget.update();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@android:id/widget_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<!-- FIXME we need something to pass to setWidgetLayoutResource or nothing shows up ? -->
|
||||
</LinearLayout>
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@android:id/widget_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.gridlayout.widget.GridLayout
|
||||
android:id="@+id/widget_preview_gridlayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:columnCount="1" />
|
||||
|
||||
</LinearLayout>
|
@ -22,4 +22,8 @@
|
||||
<attr name="deviceIconOnPrimary" format="color" />
|
||||
<attr name="deviceIconLight" format="color" />
|
||||
<attr name="deviceIconDark" format="color" />
|
||||
|
||||
<declare-styleable name="DashboardWidgetPreviewPreference">
|
||||
<attr name="widgetName" format="string" />
|
||||
</declare-styleable>
|
||||
</resources>
|
@ -2916,6 +2916,7 @@
|
||||
<string name="title">Title</string>
|
||||
<string name="description">Description</string>
|
||||
<string name="preview_image">Preview image</string>
|
||||
<string name="preview">Preview</string>
|
||||
<string name="status_icon">Status icon</string>
|
||||
<string name="changelog_full_title">Changelog</string>
|
||||
<string name="changelog_show_full">More…</string>
|
||||
|
@ -39,62 +39,94 @@
|
||||
android:key="pref_key_dashboard_today"
|
||||
android:title="@string/pref_dashboard_widget_today_title"
|
||||
app:iconSpaceReserved="false">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="dashboard_widget_today_24h"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_today_24h_title"
|
||||
android:summary="@string/pref_dashboard_widget_today_24h_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="dashboard_widget_today_24h_upside_down"
|
||||
android:dependency="dashboard_widget_today_24h"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_today_upside_down_title"
|
||||
android:summary="@string/pref_dashboard_widget_today_upside_down_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dashboard_widget_today_2columns"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_double_size_title"
|
||||
android:summary="@string/pref_dashboard_widget_double_size_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dashboard_widget_today_legend"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_show_legend_title"
|
||||
android:summary="@string/pref_dashboard_widget_show_legend_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<EditTextPreference
|
||||
android:defaultValue="1"
|
||||
android:inputType="number"
|
||||
android:key="dashboard_widget_today_hr_interval"
|
||||
android:maxLength="4"
|
||||
android:summary="@string/pref_dashboard_widget_today_hr_interval_summary"
|
||||
android:title="@string/pref_dashboard_widget_today_hr_interval_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_dashboard_today_preview"
|
||||
android:title="@string/preview"
|
||||
app:iconSpaceReserved="false">
|
||||
<nodomain.freeyourgadget.gadgetbridge.activities.dashboard.preferences.DashboardWidgetPreviewPreference
|
||||
android:key="dashboard_widget_preview_today"
|
||||
app:widgetName="today"
|
||||
android:title=""
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_dashboard_today_settings"
|
||||
android:title="@string/action_settings"
|
||||
app:iconSpaceReserved="false">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="dashboard_widget_today_24h"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_today_24h_title"
|
||||
android:summary="@string/pref_dashboard_widget_today_24h_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="dashboard_widget_today_24h_upside_down"
|
||||
android:dependency="dashboard_widget_today_24h"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_today_upside_down_title"
|
||||
android:summary="@string/pref_dashboard_widget_today_upside_down_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dashboard_widget_today_2columns"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_double_size_title"
|
||||
android:summary="@string/pref_dashboard_widget_double_size_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dashboard_widget_today_legend"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_show_legend_title"
|
||||
android:summary="@string/pref_dashboard_widget_show_legend_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<EditTextPreference
|
||||
android:defaultValue="1"
|
||||
android:inputType="number"
|
||||
android:key="dashboard_widget_today_hr_interval"
|
||||
android:maxLength="4"
|
||||
android:summary="@string/pref_dashboard_widget_today_hr_interval_summary"
|
||||
android:title="@string/pref_dashboard_widget_today_hr_interval_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
android:key="pref_key_dashboard_goals"
|
||||
android:title="@string/pref_dashboard_widget_goals_chart_title"
|
||||
app:iconSpaceReserved="false">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dashboard_widget_goals_2columns"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_double_size_title"
|
||||
android:summary="@string/pref_dashboard_widget_double_size_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dashboard_widget_goals_legend"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_show_legend_title"
|
||||
android:summary="@string/pref_dashboard_widget_show_legend_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_dashboard_goals_preview"
|
||||
android:title="@string/preview"
|
||||
app:iconSpaceReserved="false">
|
||||
<nodomain.freeyourgadget.gadgetbridge.activities.dashboard.preferences.DashboardWidgetPreviewPreference
|
||||
android:key="dashboard_widget_preview_goals"
|
||||
app:widgetName="goals"
|
||||
android:title=""
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_dashboard_goals_settings"
|
||||
android:title="@string/action_settings"
|
||||
app:iconSpaceReserved="false">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dashboard_widget_goals_2columns"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_double_size_title"
|
||||
android:summary="@string/pref_dashboard_widget_double_size_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dashboard_widget_goals_legend"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_dashboard_widget_show_legend_title"
|
||||
android:summary="@string/pref_dashboard_widget_show_legend_summary"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
</PreferenceCategory>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user