some fixes;
This commit is contained in:
parent
63351ebf66
commit
81ce5a4372
3 changed files with 180 additions and 167 deletions
|
@ -1,159 +1,158 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
android:layout_width="fill_parent"
|
||||||
android:layout_width="fill_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:background="?attr/expandable_list_item_background"
|
||||||
android:background="?attr/expandable_list_item_background"
|
android:minHeight="@dimen/favorites_list_item_height"
|
||||||
android:minHeight="@dimen/favorites_list_item_height"
|
android:orientation="vertical">
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/divider"
|
android:id="@+id/divider"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="?attr/dashboard_divider"
|
android:background="?attr/dashboard_divider"
|
||||||
android:visibility="gone"/>
|
android:visibility="gone" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/list_divider"
|
android:id="@+id/list_divider"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="?attr/dashboard_divider"
|
android:layout_marginStart="@dimen/settings_divider_margin_start"
|
||||||
android:visibility="gone"
|
android:layout_marginLeft="@dimen/settings_divider_margin_start"
|
||||||
android:layout_marginLeft="@dimen/settings_divider_margin_start"
|
android:background="?attr/dashboard_divider"
|
||||||
android:layout_marginStart="@dimen/settings_divider_margin_start" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="@dimen/favorites_list_item_height"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_gravity="center_vertical"
|
android:minHeight="@dimen/favorites_list_item_height"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingStart="@dimen/favorites_my_places_icon_left_padding"
|
android:paddingStart="@dimen/favorites_my_places_icon_left_padding"
|
||||||
android:paddingLeft="@dimen/favorites_my_places_icon_left_padding"
|
android:paddingLeft="@dimen/favorites_my_places_icon_left_padding"
|
||||||
android:paddingEnd="@dimen/favorites_my_places_icon_left_padding"
|
android:paddingEnd="@dimen/favorites_my_places_icon_left_padding"
|
||||||
android:paddingRight="@dimen/favorites_my_places_icon_left_padding">
|
android:paddingRight="@dimen/favorites_my_places_icon_left_padding">
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="@dimen/favorites_my_places_icon_size"
|
android:layout_width="@dimen/favorites_my_places_icon_size"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="center_vertical">
|
android:layout_gravity="center_vertical">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatCheckBox
|
<androidx.appcompat.widget.AppCompatCheckBox
|
||||||
android:id="@+id/toggle_item"
|
android:id="@+id/toggle_item"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:focusable="false"
|
android:focusable="false"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/favourite_icon"
|
android:id="@+id/favourite_icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:contentDescription="@string/favorite"
|
android:contentDescription="@string/favorite"
|
||||||
tools:src="@drawable/bg_point_circle"/>
|
tools:src="@drawable/bg_point_circle" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_weight="1"
|
android:layout_marginStart="@dimen/favorites_my_places_icon_right_padding"
|
||||||
android:orientation="vertical"
|
android:layout_marginLeft="@dimen/favorites_my_places_icon_right_padding"
|
||||||
android:layout_marginStart="@dimen/favorites_my_places_icon_right_padding"
|
android:layout_marginEnd="@dimen/favorites_my_places_icon_right_padding"
|
||||||
android:layout_marginLeft="@dimen/favorites_my_places_icon_right_padding"
|
android:layout_marginRight="@dimen/favorites_my_places_icon_right_padding"
|
||||||
android:layout_marginEnd="@dimen/favorites_my_places_icon_right_padding"
|
android:layout_weight="1"
|
||||||
android:layout_marginRight="@dimen/favorites_my_places_icon_right_padding"
|
android:orientation="vertical"
|
||||||
android:paddingTop="@dimen/context_menu_padding_margin_small"
|
android:paddingTop="@dimen/context_menu_padding_margin_small"
|
||||||
android:paddingBottom="@dimen/context_menu_padding_margin_small">
|
android:paddingBottom="@dimen/context_menu_padding_margin_small">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/favourite_label"
|
android:id="@+id/favourite_label"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxLines="2"
|
android:layout_marginBottom="@dimen/subHeaderPadding"
|
||||||
android:scrollbars="none"
|
android:maxLines="2"
|
||||||
android:textColor="?android:textColorPrimary"
|
android:scrollbars="none"
|
||||||
android:layout_marginBottom="@dimen/subHeaderPadding"
|
android:textColor="?android:textColorPrimary"
|
||||||
android:textSize="@dimen/default_list_text_size"
|
android:textSize="@dimen/default_list_text_size"
|
||||||
tools:text="@string/lorem_ipsum" />
|
tools:text="@string/lorem_ipsum" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/direction"
|
android:id="@+id/direction"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginTop="1sp"
|
android:layout_marginTop="1sp"
|
||||||
android:contentDescription="@string/show_view_angle"
|
android:contentDescription="@string/show_view_angle"
|
||||||
osmand:srcCompat="@drawable/ic_direction_arrow" />
|
osmand:srcCompat="@drawable/ic_direction_arrow" />
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:id="@+id/distance"
|
android:id="@+id/distance"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/gpx_small_icon_margin"
|
android:layout_marginStart="@dimen/gpx_small_icon_margin"
|
||||||
android:layout_marginLeft="@dimen/gpx_small_icon_margin"
|
android:layout_marginLeft="@dimen/gpx_small_icon_margin"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textColor="?android:textColorSecondary"
|
android:textColor="?android:textColorSecondary"
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
tools:text="100500 km" />
|
tools:text="100500 km" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/group_image"
|
android:id="@+id/group_image"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginStart="@dimen/list_item_button_padding"
|
android:layout_marginStart="@dimen/list_item_button_padding"
|
||||||
android:layout_marginLeft="@dimen/list_item_button_padding"
|
android:layout_marginLeft="@dimen/list_item_button_padding"
|
||||||
android:contentDescription="@string/favorite_category_name"
|
android:contentDescription="@string/favorite_category_name"
|
||||||
osmand:srcCompat="@drawable/ic_action_group_name_16" />
|
osmand:srcCompat="@drawable/ic_action_group_name_16" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/group_name"
|
android:id="@+id/group_name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginStart="@dimen/gpx_small_icon_margin"
|
android:layout_marginStart="@dimen/gpx_small_icon_margin"
|
||||||
android:layout_marginLeft="@dimen/gpx_small_icon_margin"
|
android:layout_marginLeft="@dimen/gpx_small_icon_margin"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textColor="?android:textColorSecondary"
|
android:textColor="?android:textColorSecondary"
|
||||||
android:textSize="@dimen/default_desc_text_size" />
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/navigate_to"
|
android:id="@+id/navigate_to"
|
||||||
android:layout_width="@dimen/list_item_height"
|
android:layout_width="@dimen/list_item_height"
|
||||||
android:layout_height="@dimen/list_item_height"
|
android:layout_height="@dimen/list_item_height"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginStart="@dimen/dashFavIconMargin"
|
android:layout_marginStart="@dimen/dashFavIconMargin"
|
||||||
android:layout_marginLeft="@dimen/dashFavIconMargin"
|
android:layout_marginLeft="@dimen/dashFavIconMargin"
|
||||||
android:background="?attr/dashboard_button"
|
android:background="?attr/dashboard_button"
|
||||||
android:contentDescription="@string/context_menu_item_directions_to"
|
android:contentDescription="@string/context_menu_item_directions_to"
|
||||||
osmand:srcCompat="@drawable/ic_action_remove_dark"
|
android:visibility="gone"
|
||||||
android:visibility="gone" />
|
osmand:srcCompat="@drawable/ic_action_remove_dark" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/options"
|
android:id="@+id/options"
|
||||||
android:layout_width="@dimen/list_item_height"
|
android:layout_width="@dimen/list_item_height"
|
||||||
android:layout_height="@dimen/list_item_height"
|
android:layout_height="@dimen/list_item_height"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:background="?attr/dashboard_button"
|
android:background="?attr/dashboard_button"
|
||||||
android:contentDescription="@string/shared_string_more"
|
android:contentDescription="@string/shared_string_more"
|
||||||
osmand:srcCompat="@drawable/ic_overflow_menu_white"
|
android:visibility="gone"
|
||||||
android:visibility="gone" />
|
osmand:srcCompat="@drawable/ic_overflow_menu_white" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -19,6 +19,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||||
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||||
import net.osmand.plus.OsmAndFormatter;
|
import net.osmand.plus.OsmAndFormatter;
|
||||||
|
@ -31,12 +32,17 @@ import net.osmand.plus.myplaces.SegmentActionsListener;
|
||||||
import net.osmand.plus.widgets.TextViewEx;
|
import net.osmand.plus.widgets.TextViewEx;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class GpxBlockStatisticsBuilder {
|
public class GpxBlockStatisticsBuilder {
|
||||||
|
|
||||||
|
private static final Log log = PlatformUtil.getLog(GpxBlockStatisticsBuilder.class);
|
||||||
|
private static final int GENERAL_UPDATE_INTERVAL = 1000;
|
||||||
|
|
||||||
private final OsmandApplication app;
|
private final OsmandApplication app;
|
||||||
private RecyclerView blocksView;
|
private RecyclerView blocksView;
|
||||||
private final SelectedGpxFile selectedGpxFile;
|
private final SelectedGpxFile selectedGpxFile;
|
||||||
|
@ -89,20 +95,25 @@ public class GpxBlockStatisticsBuilder {
|
||||||
updateRunning = false;
|
updateRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runUpdatingStatBlocks() {
|
public void runUpdatingStatBlocksIfNeeded() {
|
||||||
updatingItems = new Runnable() {
|
if (!isUpdateRunning()) {
|
||||||
@Override
|
if (handler.hasCallbacks(updatingItems)) {
|
||||||
public void run() {
|
stopUpdatingStatBlocks();
|
||||||
initItems();
|
|
||||||
if (adapter != null) {
|
|
||||||
adapter.setItems(items);
|
|
||||||
}
|
|
||||||
AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items));
|
|
||||||
int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get();
|
|
||||||
handler.postDelayed(this, Math.max(1000, interval));
|
|
||||||
}
|
}
|
||||||
};
|
updatingItems = new Runnable() {
|
||||||
updateRunning = handler.post(updatingItems);
|
@Override
|
||||||
|
public void run() {
|
||||||
|
initItems();
|
||||||
|
if (adapter != null) {
|
||||||
|
adapter.setItems(items);
|
||||||
|
}
|
||||||
|
AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items));
|
||||||
|
int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get();
|
||||||
|
updateRunning = handler.postDelayed(this, Math.max(GENERAL_UPDATE_INTERVAL, interval));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
updateRunning = handler.post(updatingItems);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initItems() {
|
public void initItems() {
|
||||||
|
@ -171,7 +182,7 @@ public class GpxBlockStatisticsBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StatBlock {
|
public static class StatBlock {
|
||||||
private final String title;
|
private final String title;
|
||||||
private final String value;
|
private final String value;
|
||||||
private final int imageResId;
|
private final int imageResId;
|
||||||
|
@ -207,6 +218,9 @@ public class GpxBlockStatisticsBuilder {
|
||||||
@ColorInt
|
@ColorInt
|
||||||
private final int activeColor;
|
private final int activeColor;
|
||||||
private final boolean nightMode;
|
private final boolean nightMode;
|
||||||
|
private final int minWidthPx;
|
||||||
|
private final int maxWidthPx;
|
||||||
|
private final int textSize;
|
||||||
|
|
||||||
public BlockStatisticsAdapter(GpxDisplayItem displayItem, SegmentActionsListener actionsListener,
|
public BlockStatisticsAdapter(GpxDisplayItem displayItem, SegmentActionsListener actionsListener,
|
||||||
@ColorInt int activeColor, boolean nightMode) {
|
@ColorInt int activeColor, boolean nightMode) {
|
||||||
|
@ -214,6 +228,9 @@ public class GpxBlockStatisticsBuilder {
|
||||||
this.actionsListener = actionsListener;
|
this.actionsListener = actionsListener;
|
||||||
this.activeColor = activeColor;
|
this.activeColor = activeColor;
|
||||||
this.nightMode = nightMode;
|
this.nightMode = nightMode;
|
||||||
|
minWidthPx = AndroidUtils.dpToPx(app, 60f);
|
||||||
|
maxWidthPx = AndroidUtils.dpToPx(app, 120f);
|
||||||
|
textSize = app.getResources().getDimensionPixelSize(R.dimen.default_desc_text_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -268,17 +285,14 @@ public class GpxBlockStatisticsBuilder {
|
||||||
this.items.addAll(items);
|
this.items.addAll(items);
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int calculateWidthWithin(String... texts) {
|
||||||
|
int textWidth = AndroidUtils.getTextMaxWidth(textSize, Arrays.asList(texts));
|
||||||
|
return Math.min(maxWidthPx, Math.max(minWidthPx, textWidth));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int calculateWidthWithin(String... texts) {
|
private static class BlockStatisticsViewHolder extends RecyclerView.ViewHolder {
|
||||||
int textSize = app.getResources().getDimensionPixelSize(R.dimen.default_desc_text_size);
|
|
||||||
int textWidth = AndroidUtils.getTextMaxWidth(textSize, Arrays.asList(texts));
|
|
||||||
int minWidth = AndroidUtils.dpToPx(app, 60);
|
|
||||||
int maxWidth = AndroidUtils.dpToPx(app, 120);
|
|
||||||
return Math.min(maxWidth, Math.max(minWidth, textWidth));
|
|
||||||
}
|
|
||||||
|
|
||||||
private class BlockStatisticsViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
private final TextViewEx valueText;
|
private final TextViewEx valueText;
|
||||||
private final TextView titleText;
|
private final TextView titleText;
|
||||||
|
|
|
@ -332,8 +332,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
headerContainer.addView(overviewCard.build(getMapActivity()));
|
headerContainer.addView(overviewCard.build(getMapActivity()));
|
||||||
}
|
}
|
||||||
GpxBlockStatisticsBuilder blocksBuilder = overviewCard.getBlockStatisticsBuilder();
|
GpxBlockStatisticsBuilder blocksBuilder = overviewCard.getBlockStatisticsBuilder();
|
||||||
if (isCurrentRecordingTrack() && !blocksBuilder.isUpdateRunning()) {
|
if (isCurrentRecordingTrack()) {
|
||||||
blocksBuilder.runUpdatingStatBlocks();
|
blocksBuilder.runUpdatingStatBlocksIfNeeded();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (overviewCard != null && overviewCard.getView() != null) {
|
if (overviewCard != null && overviewCard.getView() != null) {
|
||||||
|
@ -551,8 +551,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
updateControlsVisibility(true);
|
updateControlsVisibility(true);
|
||||||
startLocationUpdate();
|
startLocationUpdate();
|
||||||
GpxBlockStatisticsBuilder blockStats = overviewCard.getBlockStatisticsBuilder();
|
GpxBlockStatisticsBuilder blockStats = overviewCard.getBlockStatisticsBuilder();
|
||||||
if (menuType == TrackMenuType.OVERVIEW && isCurrentRecordingTrack() && !blockStats.isUpdateRunning()) {
|
if (menuType == TrackMenuType.OVERVIEW && isCurrentRecordingTrack()) {
|
||||||
blockStats.runUpdatingStatBlocks();
|
blockStats.runUpdatingStatBlocksIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue