commit
387d3385aa
18 changed files with 104 additions and 82 deletions
|
@ -11,6 +11,7 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="gpx_parse_error">OsmAnd GPX is not well formed, please contact support team to investigate further</string>
|
||||
<string name="unsupported_type_error">Unsupported type</string>
|
||||
<string name="index_item_world_basemap_detailed">World overview map (detailed)</string>
|
||||
<string name="profiles_for_action_not_found">Could not find any such profiles.</string>
|
||||
|
|
|
@ -553,7 +553,8 @@ public class AppInitializer implements IProgress {
|
|||
|
||||
customConfigs.put(fileName, builder);
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
Algorithms.removeAllFiles(f);
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ public class OsmAndLocationSimulation {
|
|||
@Override
|
||||
public boolean processResult(GPXUtilities.GPXFile[] result) {
|
||||
GPXRouteParamsBuilder builder = new GPXRouteParamsBuilder(result[0], app.getSettings());
|
||||
startAnimationThread(app, builder.getPoints(), true, speedup.getValue() + 1);
|
||||
startAnimationThread(app, builder.getPoints(app), true, speedup.getValue() + 1);
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
|
|
|
@ -514,7 +514,7 @@ public class MapActivityActions implements DialogProvider {
|
|||
params.setCalculateOsmAndRouteParts(settings.GPX_ROUTE_CALC_OSMAND_PARTS.get());
|
||||
params.setUseIntermediatePointsRTE(settings.GPX_CALCULATE_RTEPT.get());
|
||||
params.setCalculateOsmAndRoute(settings.GPX_ROUTE_CALC.get());
|
||||
List<Location> ps = params.getPoints();
|
||||
List<Location> ps = params.getPoints(settings.getContext());
|
||||
mapActivity.getRoutingHelper().setGpxParams(params);
|
||||
settings.FOLLOW_THE_GPX_ROUTE.set(result.path);
|
||||
if (!ps.isEmpty()) {
|
||||
|
|
|
@ -166,17 +166,18 @@ public class OsmandInAppPurchaseActivity extends AppCompatActivity implements In
|
|||
|
||||
@Override
|
||||
public void onItemPurchased(String sku, boolean active) {
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
if (purchaseHelper != null && purchaseHelper.getLiveUpdates().containsSku(sku)) {
|
||||
getMyApplication().logEvent("live_osm_subscription_purchased");
|
||||
|
||||
if (!active) {
|
||||
if (!active && !fragmentManager.isStateSaved()) {
|
||||
OsmLiveRestartBottomSheetDialogFragment fragment = new OsmLiveRestartBottomSheetDialogFragment();
|
||||
fragment.setUsedOnMap(this instanceof MapActivity);
|
||||
fragment.show(getSupportFragmentManager(), OsmLiveRestartBottomSheetDialogFragment.TAG);
|
||||
fragment.show(fragmentManager, OsmLiveRestartBottomSheetDialogFragment.TAG);
|
||||
}
|
||||
}
|
||||
onInAppPurchaseItemPurchased(sku);
|
||||
fireInAppPurchaseItemPurchasedOnFragments(getSupportFragmentManager(), sku, active);
|
||||
fireInAppPurchaseItemPurchasedOnFragments(fragmentManager, sku, active);
|
||||
}
|
||||
|
||||
public void fireInAppPurchaseItemPurchasedOnFragments(@NonNull FragmentManager fragmentManager,
|
||||
|
|
|
@ -215,7 +215,7 @@ public class SettingsDevelopmentActivity extends SettingsBaseActivity {
|
|||
SunriseSunset sunriseSunset = getMyApplication().getDaynightHelper().getSunriseSunset();
|
||||
pref = new Preference(this);
|
||||
pref.setTitle(R.string.day_night_info);
|
||||
if (sunriseSunset != null) {
|
||||
if (sunriseSunset != null && sunriseSunset.getSunrise() != null && sunriseSunset.getSunset() != null) {
|
||||
SimpleDateFormat prt = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
pref.setSummary(getString(R.string.day_night_info_description, prt.format(sunriseSunset.getSunrise()),
|
||||
prt.format(sunriseSunset.getSunset())));
|
||||
|
|
|
@ -504,7 +504,7 @@ public class ConfigureMapMenu {
|
|||
|
||||
String description = "";
|
||||
SunriseSunset sunriseSunset = activity.getMyApplication().getDaynightHelper().getSunriseSunset();
|
||||
if (sunriseSunset != null) {
|
||||
if (sunriseSunset != null && sunriseSunset.getSunrise() != null && sunriseSunset.getSunset() != null) {
|
||||
DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
|
||||
String sunriseTime = dateFormat.format(sunriseSunset.getSunrise());
|
||||
String sunsetTime = dateFormat.format(sunriseSunset.getSunset());
|
||||
|
|
|
@ -768,7 +768,8 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (optionsMenuAdapter != null) {
|
||||
int itemId = item.getItemId();
|
||||
for (int i = 0; i < optionsMenuAdapter.length(); i++) {
|
||||
ContextMenuItem contextMenuItem = optionsMenuAdapter.getItem(i);
|
||||
|
@ -777,6 +778,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
|
|||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,11 +17,8 @@ import net.osmand.data.LocationPoint;
|
|||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.WptLocationPoint;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
|
@ -33,6 +30,9 @@ import net.osmand.plus.routing.AlarmInfo;
|
|||
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
|
||||
import net.osmand.plus.routing.RouteCalculationResult;
|
||||
import net.osmand.plus.routing.VoiceRouter;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -627,19 +627,20 @@ public class WaypointHelper {
|
|||
amenities.addAll(pf.searchAmenitiesOnThePath(locs, poiSearchDeviationRadius));
|
||||
}
|
||||
for (Amenity a : amenities) {
|
||||
AmenityRoutePoint rp = a.getRoutePoint();
|
||||
int i = locs.indexOf(rp.pointA);
|
||||
AmenityRoutePoint routePoint = a.getRoutePoint();
|
||||
if (routePoint != null) {
|
||||
int i = locs.indexOf(routePoint.pointA);
|
||||
if (i >= 0) {
|
||||
LocationPointWrapper lwp = new LocationPointWrapper(route, POI, new AmenityLocationPoint(a),
|
||||
(float) rp.deviateDistance, i);
|
||||
lwp.deviationDirectionRight = rp.deviationDirectionRight;
|
||||
(float) routePoint.deviateDistance, i);
|
||||
lwp.deviationDirectionRight = routePoint.deviationDirectionRight;
|
||||
lwp.setAnnounce(announcePOI);
|
||||
locationPoints.add(lwp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void calculateAlarms(RouteCalculationResult route, List<LocationPointWrapper> array, ApplicationMode mode) {
|
||||
AlarmInfo prevSpeedCam = null;
|
||||
|
|
|
@ -25,19 +25,19 @@ import com.google.android.material.slider.Slider;
|
|||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.ValueHolder;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.NavigationService;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmAndTaskManager.OsmAndTaskRunnable;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.SavingTrackHelper;
|
||||
import net.osmand.plus.activities.SavingTrackHelper.SaveGpxResult;
|
||||
import net.osmand.plus.dashboard.tools.DashFragmentData;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
|
||||
import net.osmand.plus.views.MapInfoLayer;
|
||||
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
|
||||
|
@ -333,6 +333,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin {
|
|||
startGPXMonitoring(activity, showTrackSelection);
|
||||
}
|
||||
} else if (item == R.string.clear_recorded_data) {
|
||||
if (AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(UiUtilities.getThemedContext(activity, nightMode));
|
||||
builder.setTitle(R.string.clear_recorded_data);
|
||||
builder.setMessage(R.string.are_you_sure);
|
||||
|
@ -345,6 +346,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin {
|
|||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
} else if(item == R.string.gpx_monitoring_stop) {
|
||||
stopRecording();
|
||||
} else if(item == R.string.gpx_start_new_segment) {
|
||||
|
@ -481,19 +483,21 @@ public class OsmandMonitoringPlugin extends OsmandPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static void showIntervalChooseDialog(final Context uiCtx, final String patternMsg,
|
||||
public static void showIntervalChooseDialog(final Activity activity, final String patternMsg,
|
||||
String title, final int[] seconds, final int[] minutes,
|
||||
final ValueHolder<Boolean> choice, final ValueHolder<Integer> v,
|
||||
final boolean showTrackSelection, OnClickListener onclick) {
|
||||
final OsmandApplication app = (OsmandApplication) uiCtx.getApplicationContext();
|
||||
if (!AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||
return;
|
||||
}
|
||||
final OsmandApplication app = (OsmandApplication) activity.getApplicationContext();
|
||||
boolean nightMode;
|
||||
if (uiCtx instanceof MapActivity) {
|
||||
if (activity instanceof MapActivity) {
|
||||
nightMode = app.getDaynightHelper().isNightModeForMapControls();
|
||||
} else {
|
||||
nightMode = !app.getSettings().isLightContent();
|
||||
}
|
||||
Context themedContext = UiUtilities.getThemedContext(uiCtx, nightMode);
|
||||
Context themedContext = UiUtilities.getThemedContext(activity, nightMode);
|
||||
AlertDialog.Builder dlg = new AlertDialog.Builder(themedContext);
|
||||
dlg.setTitle(title);
|
||||
LinearLayout ll = createIntervalChooseLayout(app, themedContext, patternMsg, seconds, minutes, choice, v, showTrackSelection, nightMode);
|
||||
|
|
|
@ -237,7 +237,7 @@ public class RoutingOptionsHelper {
|
|||
if (gpxParam.id == R.string.gpx_option_reverse_route) {
|
||||
rp.setReverse(selected);
|
||||
TargetPointsHelper tg = app.getTargetPointsHelper();
|
||||
List<Location> ps = rp.getPoints();
|
||||
List<Location> ps = rp.getPoints(app);
|
||||
if (ps.size() > 0) {
|
||||
Location first = ps.get(0);
|
||||
Location end = ps.get(ps.size() - 1);
|
||||
|
|
|
@ -19,15 +19,15 @@ import net.osmand.data.LatLon;
|
|||
import net.osmand.data.LocationPoint;
|
||||
import net.osmand.data.WptLocationPoint;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.TargetPointsHelper;
|
||||
import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
||||
import net.osmand.plus.Version;
|
||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference;
|
||||
import net.osmand.router.GeneralRouter;
|
||||
import net.osmand.router.GeneralRouter.RoutingParameter;
|
||||
import net.osmand.router.GeneralRouter.RoutingParameterType;
|
||||
|
@ -173,12 +173,14 @@ public class RouteProvider {
|
|||
return passWholeRoute;
|
||||
}
|
||||
|
||||
public GPXRouteParams build(Location start, OsmandSettings settings) {
|
||||
public GPXRouteParams build(OsmandApplication app) {
|
||||
GPXRouteParams res = new GPXRouteParams();
|
||||
try {
|
||||
res.prepareGPXFile(this);
|
||||
// if (passWholeRoute && start != null) {
|
||||
// res.points.add(0, start);
|
||||
// }
|
||||
} catch (RuntimeException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
app.showShortToastMessage(app.getString(R.string.gpx_parse_error) + " " + e.getMessage());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -190,9 +192,8 @@ public class RouteProvider {
|
|||
return file;
|
||||
}
|
||||
|
||||
public List<Location> getPoints() {
|
||||
GPXRouteParams copy = new GPXRouteParams();
|
||||
copy.prepareGPXFile(this);
|
||||
public List<Location> getPoints(OsmandApplication app) {
|
||||
GPXRouteParams copy = build(app);
|
||||
return copy.getPoints();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1172,7 +1172,7 @@ public class RoutingHelper {
|
|||
params.start = start;
|
||||
params.end = end;
|
||||
params.intermediates = intermediates;
|
||||
params.gpxRoute = gpxRoute == null ? null : gpxRoute.build(start, settings);
|
||||
params.gpxRoute = gpxRoute == null ? null : gpxRoute.build(app);
|
||||
params.onlyStartPointChanged = onlyStartPointChanged;
|
||||
if (recalculateCountInInterval < RECALCULATE_THRESHOLD_COUNT_CAUSING_FULL_RECALCULATE
|
||||
|| (gpxRoute != null && gpxRoute.isPassWholeRoute() && isDeviatedFromRoute)) {
|
||||
|
|
|
@ -7,13 +7,13 @@ import android.widget.ImageView;
|
|||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.SettingsBaseActivity;
|
||||
import net.osmand.plus.routing.RouteProvider.RouteService;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.preferences.ListPreferenceEx;
|
||||
import net.osmand.router.GeneralRouter;
|
||||
|
||||
|
@ -123,7 +123,8 @@ public class VehicleParametersFragment extends BaseSettingsFragment implements O
|
|||
public boolean onPreferenceClick(Preference preference) {
|
||||
if (preference.getKey().equals(GeneralRouter.DEFAULT_SPEED)) {
|
||||
RouteService routeService = getSelectedAppMode().getRouteService();
|
||||
showSeekbarSettingsDialog(getActivity(), routeService == RouteService.STRAIGHT, getSelectedAppMode());
|
||||
boolean defaultSpeedOnly = routeService == RouteService.STRAIGHT || routeService == RouteService.DIRECT_TO;
|
||||
showSeekbarSettingsDialog(getActivity(), defaultSpeedOnly, getSelectedAppMode());
|
||||
return true;
|
||||
}
|
||||
return super.onPreferenceClick(preference);
|
||||
|
|
|
@ -35,8 +35,6 @@ import net.osmand.plus.ContextMenuAdapter;
|
|||
import net.osmand.plus.ContextMenuItem;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings.TerrainMode;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
|
@ -46,6 +44,8 @@ import net.osmand.plus.download.DownloadResources;
|
|||
import net.osmand.plus.download.DownloadValidationManager;
|
||||
import net.osmand.plus.download.IndexItem;
|
||||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings.TerrainMode;
|
||||
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -53,10 +53,10 @@ import org.apache.commons.logging.Log;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.plus.settings.backend.OsmandSettings.TerrainMode.HILLSHADE;
|
||||
import static net.osmand.plus.settings.backend.OsmandSettings.TerrainMode.SLOPE;
|
||||
import static net.osmand.plus.download.DownloadActivityType.HILLSHADE_FILE;
|
||||
import static net.osmand.plus.download.DownloadActivityType.SLOPE_FILE;
|
||||
import static net.osmand.plus.settings.backend.OsmandSettings.TerrainMode.HILLSHADE;
|
||||
import static net.osmand.plus.settings.backend.OsmandSettings.TerrainMode.SLOPE;
|
||||
import static net.osmand.plus.srtmplugin.SRTMPlugin.TERRAIN_MAX_ZOOM;
|
||||
import static net.osmand.plus.srtmplugin.SRTMPlugin.TERRAIN_MIN_ZOOM;
|
||||
|
||||
|
@ -528,7 +528,7 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL
|
|||
public void downloadInProgress() {
|
||||
DownloadIndexesThread downloadThread = app.getDownloadThread();
|
||||
IndexItem downloadIndexItem = downloadThread.getCurrentDownloadingItem();
|
||||
if (downloadIndexItem != null) {
|
||||
if (downloadIndexItem != null && listAdapter != null) {
|
||||
int downloadProgress = downloadThread.getCurrentDownloadingItemProgress();
|
||||
ArrayAdapter<ContextMenuItem> adapter = (ArrayAdapter<ContextMenuItem>) listAdapter;
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
|
|
|
@ -395,7 +395,11 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe
|
|||
}
|
||||
if (this.nightMode != nightMode) {
|
||||
this.nightMode = nightMode;
|
||||
updateQuickActionButton(currentWidgetState != null && currentWidgetState);
|
||||
boolean widgetVisible = false;
|
||||
if (currentWidgetState != null) {
|
||||
widgetVisible = currentWidgetState;
|
||||
}
|
||||
updateQuickActionButton(widgetVisible);
|
||||
}
|
||||
setupQuickActionBtnVisibility();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.webkit.WebViewClient;
|
|||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.data.Amenity;
|
||||
|
||||
import static net.osmand.plus.wikipedia.WikiArticleHelper.WIKI_DOMAIN;
|
||||
|
@ -41,8 +42,10 @@ public class WikipediaWebViewClient extends WebViewClient {
|
|||
WikiArticleHelper.warnAboutExternalLoad(url, context, nightMode);
|
||||
} else {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
if (AndroidUtils.isIntentSafe(context, i)) {
|
||||
context.startActivity(i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,13 @@ import androidx.annotation.Nullable;
|
|||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.wikipedia.WikiArticleHelper;
|
||||
import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment;
|
||||
import net.osmand.plus.wikivoyage.data.TravelArticle;
|
||||
|
@ -124,8 +125,10 @@ public class WikivoyageWebViewClient extends WebViewClient {
|
|||
}
|
||||
} else {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
if (AndroidUtils.isIntentSafe(activity, i)) {
|
||||
activity.startActivity(i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue