diff --git a/GPX.md b/GPX.md index 8ab3640620..b3f1e441e4 100644 --- a/GPX.md +++ b/GPX.md @@ -1,11 +1,11 @@ -The OsmAnd's GPX file format conforms to GPX 1.1 specification with additional data written as extensions. There are few sections of such data: +The OsmAnd's GPX file format conforms to the GPX 1.1 specification with additional data written as extensions. There are several sections of such data: ## Track appearance -These parameters are used to customize the appearance of a track on the map. Used inside "gpx" tag and applies to all tracks inside gpx. +The following parameters are used to customize the appearance of a track on the map. They are used inside the "gpx" tag and apply to all tracks contained in the gpx. #### Parameters * **show_arrows** [*true, false*] - show / hide arrows along the path line. -* **width** [*thin, medium, bold, 1-24*] - width of a track line on the map. The thin, medium and bold are style depended values (should be defined as currentTrackWidth attribute). -* **color** [*#AARRGGBB, #RRGGBB*] - color of a track line on the map. Hex values. +* **width** [*thin, medium, bold, 1-24*] - width of the track line on the map. The thin, medium, and bold are style depended values (should be defined as currentTrackWidth attribute). +* **color** [*#AARRGGBB, #RRGGBB*] - color of a track line on the map. Hex value. * **split_type** [*no_split, distance, time*] - split type for a track. * **split_interval** [*double*] - split interval for a track. Distance (meters), time (seconds). @@ -41,11 +41,10 @@ Written to a gpx file while recording a track. ``` ## Calculated route(s) -This data contains information about a route built with **OsmAnd** (route segments, turns, road names and types, restrictions, etc.). With their help, route can be restored completely as if it had just been built even without the currently installed offline maps. - -There can be several routes in one gpx file. Each of them is contained in a specific segment (**trkseg** / **extensions**). In this form, a gpx file is saved when exporting a constructed route or when saving a track that consists of several separate segments via the **Plan route**. -When using the **Plan route** tool, route key points (**rtept**) are additionally written to the gpx file. There can also be several **rte** blocks (according to a number of separate segments / tracks in a gpx file). +This data contains all details of a route built with **OsmAnd** (route segments, turns, road names, road types, restrictions, etc.). The route can be completely restored as if just built, even in the absence of the respective offline maps. +A gpx file may contain several routes. Each of them is contained in a specific segment under **trkseg** / **extensions**. A gpx file is saved in this form when exporting a constructed route or when saving a track that consists of several separate segments via the **Plan a route** functionality. +**Plan a route** also adds one (or several, in accordance with the number of contained separate segments / tracks) **rte** blocks to the gpx file, containing route key points (**rtept**). #### Gpx structure: ```xml diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java index 18ebc9b688..c2b961646e 100644 --- a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java @@ -71,6 +71,7 @@ public class GPXUtilities { WHITE(0xFFFFFFFF), RED(0xFFFF0000), GREEN(0xFF00FF00), + DARKGREEN(0xFF006400), BLUE(0xFF0000FF), YELLOW(0xFFFFFF00), CYAN(0xFF00FFFF), diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt index 4ff84ca542..ee05034cb7 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt @@ -18,7 +18,6 @@ import net.osmand.telegram.helpers.TelegramHelper import net.osmand.telegram.helpers.TelegramHelper.* import net.osmand.telegram.notifications.TelegramNotification.NotificationType import net.osmand.telegram.utils.AndroidUtils -import net.osmand.telegram.utils.OsmandLocationUtils import org.drinkless.td.libcore.telegram.TdApi import java.util.* @@ -377,7 +376,10 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis Log.d(PlatformUtil.TAG, "Send live location error: $code - $message") when (messageType) { TelegramHelper.MESSAGE_TYPE_TEXT -> shareInfo.pendingTdLibText-- - TelegramHelper.MESSAGE_TYPE_MAP -> shareInfo.pendingTdLibMap-- + TelegramHelper.MESSAGE_TYPE_MAP -> { + shareInfo.pendingTdLibMap-- + shareInfo.currentMapMessageId = -1L + } } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index d9ec335a0e..a6a2377118 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -304,27 +304,18 @@ class TelegramSettings(private val app: TelegramApplication) { fun prepareForSharingNewMessages() { shareChatsInfo.forEach { (_, shareInfo) -> - prepareForSharingNewMessages(shareInfo) + shareInfo.resetMessagesInfo() } } fun prepareForSharingNewMessages(chatsIds: List) { chatsIds.forEach { shareChatsInfo[it]?.also { shareInfo -> - prepareForSharingNewMessages(shareInfo) + shareInfo.resetMessagesInfo() } } } - fun prepareForSharingNewMessages(shareInfo: ShareChatInfo) { - shareInfo.pendingTdLibText = 0 - shareInfo.pendingTdLibMap = 0 - shareInfo.currentTextMessageId = -1L - shareInfo.currentMapMessageId = -1L - shareInfo.pendingTextMessage = false - shareInfo.pendingMapMessage = false - } - fun getChatLivePeriod(chatId: Long) = shareChatsInfo[chatId]?.livePeriod fun getChatsShareInfo() = shareChatsInfo @@ -1497,6 +1488,27 @@ class TelegramSettings(private val app: TelegramApplication) { fun isPendingMapMessagesLimitReached() = pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT + fun resetMessagesInfo() { + resetTextMessageInfo() + resetMapMessageInfo() + } + + fun resetTextMessageInfo() { + pendingTdLibText = 0 + currentTextMessageId = -1L + pendingTextMessage = false + } + + fun resetMapMessageInfo() { + pendingTdLibMap = 0 + currentMapMessageId = -1L + pendingMapMessage = false + } + + fun isTextMessageIdPresent() = currentTextMessageId != -1L + + fun isMapMessageIdPresent() = currentMapMessageId != -1L + companion object { internal const val CHAT_ID_KEY = "chatId" diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt index 8aa7d29856..35a397f4f5 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt @@ -138,7 +138,7 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } if (pendingMessagesLimitReached && checkNetworkTypeAllowed) { - checkNetworkType() + updateNetworkType() } } @@ -167,7 +167,7 @@ class ShareLocationHelper(private val app: TelegramApplication) { app.locationMessages.getBufferedTextMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach { if (!shareInfo.isPendingTextMessagesLimitReached()) { if (it.deviceName.isEmpty()) { - if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) { + if (!shareInfo.pendingTextMessage && shareInfo.isTextMessageIdPresent()) { val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, it, app) app.telegramHelper.editTextLocation(shareInfo, content) app.locationMessages.removeBufferedMessage(it) @@ -180,8 +180,12 @@ class ShareLocationHelper(private val app: TelegramApplication) { app.locationMessages.getBufferedMapMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach { if (!shareInfo.isPendingMapMessagesLimitReached()) { if (it.deviceName.isEmpty()) { - if (!shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) { - app.telegramHelper.editMapLocation(shareInfo, it) + if (!shareInfo.pendingMapMessage) { + if (shareInfo.isMapMessageIdPresent()) { + app.telegramHelper.editMapLocation(shareInfo, it) + } else { + app.telegramHelper.sendNewMapLocation(shareInfo, it) + } app.locationMessages.removeBufferedMessage(it) } } else { @@ -279,7 +283,7 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } if (pendingMessagesLimitReached) { - checkNetworkType() + updateNetworkType() } } @@ -347,7 +351,7 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } - fun checkNetworkType(){ + fun updateNetworkType(){ if (app.isInternetConnectionAvailable) { val networkType = when { app.isWifiConnected -> TdApi.NetworkTypeWiFi() diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt index 704a797af2..941e4a8aa4 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt @@ -840,7 +840,7 @@ class TelegramHelper private constructor() { } fun stopSendingLiveLocationToChat(shareInfo: ShareChatInfo) { - if (shareInfo.currentMapMessageId != -1L && shareInfo.chatId != -1L) { + if (!shareInfo.isMapMessageIdPresent() && shareInfo.chatId != -1L) { shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt() client?.send( TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMapMessageId, null, null)) { obj -> diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt index f3391246b4..fbc3725ec1 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt @@ -15,7 +15,6 @@ import android.widget.TextView import androidx.appcompat.widget.ListPopupWindow import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import net.osmand.Location import net.osmand.data.LatLon import net.osmand.telegram.R @@ -99,7 +98,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage mainView.findViewById(R.id.swipe_refresh).apply { setOnRefreshListener { - app.shareLocationHelper.checkNetworkType() + app.shareLocationHelper.updateNetworkType() app.telegramHelper.scanChatsHistory() updateList() isRefreshing = false diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt index ef080fe40d..3dd9968f1c 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt @@ -72,7 +72,7 @@ class SharingStatusBottomSheet : DialogFragment() { if (sharingStatusType.canResendLocation) { if (i == 0) { setOnClickListener { - app.shareLocationHelper.checkNetworkType() + app.shareLocationHelper.updateNetworkType() app.settings.prepareForSharingNewMessages(sharingStatus.chatsIds) app.shareLocationHelper.checkAndSendBufferMessages() app.forceUpdateMyLocation() diff --git a/OsmAnd/res/layout/bottom_sheet_dialog_button.xml b/OsmAnd/res/layout/bottom_sheet_dialog_button.xml index ee757eba8f..6ce7d34fc3 100644 --- a/OsmAnd/res/layout/bottom_sheet_dialog_button.xml +++ b/OsmAnd/res/layout/bottom_sheet_dialog_button.xml @@ -7,7 +7,7 @@ android:layout_height="@dimen/dialog_button_height" android:layout_weight="1"> - - + \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_login.xml b/OsmAnd/res/layout/bottom_sheet_login.xml new file mode 100644 index 0000000000..85915a72cc --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_login.xml @@ -0,0 +1,50 @@ + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/osm_login_data.xml b/OsmAnd/res/layout/osm_login_data.xml index 4ae3173c18..4679608265 100644 --- a/OsmAnd/res/layout/osm_login_data.xml +++ b/OsmAnd/res/layout/osm_login_data.xml @@ -4,67 +4,54 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:paddingStart="@dimen/content_padding" android:paddingLeft="@dimen/content_padding" - android:paddingRight="@dimen/content_padding" - android:paddingBottom="@dimen/dialog_button_height" + android:paddingTop="@dimen/bottom_sheet_content_margin" android:paddingEnd="@dimen/content_padding" - android:paddingStart="@dimen/content_padding"> + android:paddingRight="@dimen/content_padding" + android:paddingBottom="@dimen/bottom_sheet_content_margin"> - - - + android:layout_marginBottom="@dimen/bottom_sheet_content_margin" + android:hint="@string/user_login"> - + android:imeOptions="actionDone" /> - + - + android:hint="@string/user_password"> - + android:inputType="textPassword" /> - + \ No newline at end of file diff --git a/OsmAnd/res/layout/preference_login.xml b/OsmAnd/res/layout/preference_login.xml new file mode 100644 index 0000000000..14ecba71af --- /dev/null +++ b/OsmAnd/res/layout/preference_login.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 68791492fc..dc262a8b1b 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -16,6 +16,16 @@ OsmAnd Live subscription has been expired There is a problem with your subscription. Click the button to go to the Google Play subscription settings to fix your payment method. Manage subscription + Login + Password + Account + Use login and password + You need to login to upload new or modified changes. \n\nYou can log in using the safe OAuth method or use your login and password. + You can view all your unloaded edits or OSM bugs in %1$s. Uploaded points don’t show in OsmAnd. + Sing in with OpenStreetMap + Login to OpenStreetMap.org + Login to OpenStreetMap + These plugin setting are global, and apply to all profiles You must add at least two points. Travel Emergency @@ -487,9 +497,7 @@ Route recalculation Announce Username and password - These settings apply to all profiles. OSM editing - View your edits or OSM bugs not yet uploaded in %1$s. Uploaded points will not show any more. OSM Icon shown while navigating or moving. Icon shown at rest. @@ -2426,7 +2434,6 @@ French Georgian German - German (casual) Greek Hebrew Hebrew @@ -3202,7 +3209,6 @@ Global app settings Your OSM username Needed for openstreetmap.org submissions. - Your OSM password Background mode OsmAnd runs in the background with the screen off. There is not enough free space to download %1$s MB (free: %2$s). diff --git a/OsmAnd/res/xml/osm_editing.xml b/OsmAnd/res/xml/osm_editing.xml index 990a15349c..469e841c36 100644 --- a/OsmAnd/res/xml/osm_editing.xml +++ b/OsmAnd/res/xml/osm_editing.xml @@ -16,9 +16,13 @@ android:key="osm_login_data" android:layout="@layout/preference_with_descr" android:persistent="false" - android:title="@string/login_and_pass" - tools:icon="@drawable/ic_action_openstreetmap_logo" - tools:summary="@string/open_street_map_login_descr" /> + android:title="@string/login_open_street_map" /> + + mTabs, Intent intent) { } - protected void contextMenuFragment(Activity activity, Fragment fragment, Object info, ContextMenuAdapter adapter) { + protected void contextMenuFragment(FragmentActivity activity, Fragment fragment, Object info, ContextMenuAdapter adapter) { } - protected void optionsMenuFragment(Activity activity, Fragment fragment, ContextMenuAdapter optionsMenuAdapter) { + protected void optionsMenuFragment(FragmentActivity activity, Fragment fragment, ContextMenuAdapter optionsMenuAdapter) { } protected boolean searchFinished(QuickSearchDialogFragment searchFragment, SearchPhrase phrase, boolean isResultEmpty) { @@ -815,14 +815,13 @@ public abstract class OsmandPlugin { } } - public static void onContextMenuActivity(Activity activity, Fragment fragment, Object info, ContextMenuAdapter adapter) { + public static void onContextMenuActivity(FragmentActivity activity, Fragment fragment, Object info, ContextMenuAdapter adapter) { for (OsmandPlugin plugin : getEnabledPlugins()) { plugin.contextMenuFragment(activity, fragment, info, adapter); } } - - public static void onOptionsMenuActivity(Activity activity, Fragment fragment, ContextMenuAdapter optionsMenuAdapter) { + public static void onOptionsMenuActivity(FragmentActivity activity, Fragment fragment, ContextMenuAdapter optionsMenuAdapter) { for (OsmandPlugin plugin : getEnabledPlugins()) { plugin.optionsMenuFragment(activity, fragment, optionsMenuAdapter); } diff --git a/OsmAnd/src/net/osmand/plus/Version.java b/OsmAnd/src/net/osmand/plus/Version.java index 8e23518613..48dd9b1feb 100644 --- a/OsmAnd/src/net/osmand/plus/Version.java +++ b/OsmAnd/src/net/osmand/plus/Version.java @@ -134,11 +134,11 @@ public class Version { } public static boolean isDeveloperVersion(OsmandApplication ctx){ - return false;//getAppName(ctx).contains("~") || ctx.getPackageName().equals(FREE_DEV_VERSION_NAME); + return getAppName(ctx).contains("~") || ctx.getPackageName().equals(FREE_DEV_VERSION_NAME); } public static boolean isDeveloperBuild(OsmandApplication ctx){ - return false;//getAppName(ctx).contains("~"); + return getAppName(ctx).contains("~"); } public static String getVersionForTracker(OsmandApplication ctx) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 2d33be5f82..80a7ae8c4f 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -115,10 +115,10 @@ import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu; import net.osmand.plus.mapmarkers.PlanRouteFragment; import net.osmand.plus.measurementtool.GpxApproximationFragment; import net.osmand.plus.measurementtool.GpxData; +import net.osmand.plus.measurementtool.LoginBottomSheetFragment; import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementToolFragment; import net.osmand.plus.measurementtool.SnapTrackWarningFragment; -import net.osmand.plus.osmedit.OsmEditingFragment; import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.routepreparationmenu.ChooseRouteFragment; @@ -2215,8 +2215,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven return getFragment(GpxApproximationFragment.TAG); } - public OsmEditingFragment getOsmEditingFragment() { - return getFragment(SettingsScreenType.OPEN_STREET_MAP_EDITING.fragmentName); + public LoginBottomSheetFragment getLoginBottomSheetFragment() { + return getFragment(LoginBottomSheetFragment.TAG); } public SnapTrackWarningFragment getSnapTrackWarningBottomSheet() { diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java index f073e18076..84bd292aa5 100644 --- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java @@ -377,7 +377,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra return getResources().getDimensionPixelSize(R.dimen.content_padding); } - private void setupThirdButton() { + protected void setupThirdButton() { thirdButton = buttonsContainer.findViewById(R.id.third_button); int buttonTextId = getThirdBottomButtonTextId(); if (buttonTextId != DEFAULT_VALUE) { diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java index 8219cc5a23..54cb7ba447 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/RasterMapMenu.java @@ -79,13 +79,6 @@ public class RasterMapMenu { new OnMapSelectedCallback() { @Override public void onMapSelected(boolean canceled) { - if (type == RasterMapType.UNDERLAY && !canceled && !selected) { - hidePolygonsPref.set(true); - refreshMapComplete(mapActivity); - } else if (type == RasterMapType.UNDERLAY && !canceled && mapTypePreference.get() == null) { - hidePolygonsPref.set(false); - refreshMapComplete(mapActivity); - } mapActivity.getDashboard().refreshContent(true); } }; diff --git a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java index 19748b100c..9e5aaa5254 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java @@ -19,7 +19,7 @@ import net.osmand.plus.activities.PluginsFragment; import net.osmand.plus.dashboard.DashboardOnMap.DashboardType; import net.osmand.plus.mapmarkers.MapMarkersDialogFragment; import net.osmand.plus.mapsource.EditMapSourceDialogFragment; -import net.osmand.plus.osmedit.OsmEditingFragment; +import net.osmand.plus.measurementtool.LoginBottomSheetFragment; import net.osmand.plus.search.QuickSearchDialogFragment; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; @@ -293,7 +293,7 @@ public class IntentHelper { if (intent != null && intent.getData() != null) { Uri uri = intent.getData(); if (uri.toString().startsWith("osmand-oauth")) { - OsmEditingFragment fragment = mapActivity.getOsmEditingFragment(); + LoginBottomSheetFragment fragment = mapActivity.getLoginBottomSheetFragment(); if (fragment != null) { String oauthVerifier = uri.getQueryParameter("oauth_verifier"); fragment.authorize(oauthVerifier); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/LoginBottomSheetFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/LoginBottomSheetFragment.java new file mode 100644 index 0000000000..44547815ce --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/measurementtool/LoginBottomSheetFragment.java @@ -0,0 +1,142 @@ +package net.osmand.plus.measurementtool; + +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.settings.bottomsheets.OsmLoginDataBottomSheet; + +import org.apache.commons.logging.Log; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class LoginBottomSheetFragment extends MenuBottomSheetDialogFragment { + + public static final String TAG = LoginBottomSheetFragment.class.getSimpleName(); + private static final Log log = PlatformUtil.getLog(LoginBottomSheetFragment.class); + private static final String OSM_LOGIN_DATA = "osm_login_data"; + + private OsmOAuthAuthorizationAdapter authorizationAdapter; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + OsmandApplication app = requiredMyApplication(); + authorizationAdapter = new OsmOAuthAuthorizationAdapter(app); + items.add(new SimpleBottomSheetItem.Builder().setLayoutId(R.layout.bottom_sheet_login).create()); + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + @Override + protected int getRightBottomButtonTextId() { + return R.string.use_login_password; + } + + @Override + protected void setupThirdButton() { + super.setupThirdButton(); + OsmandApplication app = getMyApplication(); + if (app != null) { + Drawable icon = app.getUIUtilities().getIcon(R.drawable.ic_action_openstreetmap_logo, R.color.popup_text_color); + TextView buttonText = thirdButton.findViewById(R.id.button_text); + AndroidUtils.setCompoundDrawablesWithIntrinsicBounds(buttonText, icon, null, null, null); + } + } + + @Override + protected int getThirdBottomButtonTextId() { + return R.string.sing_in_with_open_street_map; + } + + @Override + public int getFirstDividerHeight() { + return getResources().getDimensionPixelSize(R.dimen.card_content_padding_large); + } + + @Override + protected void onRightBottomButtonClick() { + FragmentManager fragmentManager = getFragmentManager(); + if (fragmentManager != null) { + OsmLoginDataBottomSheet.showInstance(fragmentManager, OSM_LOGIN_DATA, getTargetFragment(), usedOnMap, null); + } + dismiss(); + } + + @Override + protected void onThirdBottomButtonClick() { + View view = getView(); + if (view != null) { + authorizationAdapter.startOAuth((ViewGroup) view); + } + } + + @Override + protected DialogButtonType getRightBottomButtonType() { + return (DialogButtonType.SECONDARY); + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, @Nullable Fragment targetFragment) { + if (!fragmentManager.isStateSaved()) { + LoginBottomSheetFragment fragment = new LoginBottomSheetFragment(); + fragment.setTargetFragment(targetFragment, 0); + fragment.show(fragmentManager, TAG); + } + } + + public void authorize(String oauthVerifier) { + if (authorizationAdapter != null) { + authorizationAdapter.authorize(oauthVerifier); + updateUserName(); + } + Fragment target = getTargetFragment(); + if (target instanceof OsmAuthorizationListener) { + ((OsmAuthorizationListener) target).authorizationCompleted(); + } + dismiss(); + } + + private void updateUserName() { + OsmandApplication app = getMyApplication(); + if (app != null) { + String userName = ""; + try { + userName = authorizationAdapter.getUserName(); + } catch (InterruptedException e) { + log.error(e); + } catch (ExecutionException e) { + log.error(e); + } catch (IOException e) { + log.error(e); + } catch (XmlPullParserException e) { + log.error(e); + } + app.getSettings().USER_DISPLAY_NAME.set(userName); + } + } + + public interface OsmAuthorizationListener { + void authorizationCompleted(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index 5d18f52669..3563ab77a6 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -92,7 +92,7 @@ public class MeasurementEditingContext { private final WptPt end; private final List points; private final List segments; - private double distance; + private final double distance; public RoadSegmentData(@NonNull ApplicationMode appMode, @NonNull WptPt start, @NonNull WptPt end, @Nullable List points, @Nullable List segments) { @@ -101,20 +101,18 @@ public class MeasurementEditingContext { this.end = end; this.points = points; this.segments = segments; - if (segments != null) { - double distance = 0; - for (RouteSegmentResult segment : segments) { - distance += segment.getDistance(); - } - this.distance = distance; - } else if (points != null && points.size() > 1) { - double distance = 0; + double distance = 0; + if (points != null && points.size() > 1) { for (int i = 1; i < points.size(); i++) { distance += MapUtils.getDistance(points.get(i - 1).lat, points.get(i - 1).lon, points.get(i).lat, points.get(i).lon); } - this.distance = distance; + } else if (segments != null) { + for (RouteSegmentResult segment : segments) { + distance += segment.getDistance(); + } } + this.distance = distance; } public ApplicationMode getAppMode() { @@ -259,14 +257,8 @@ public class MeasurementEditingContext { RoadSegmentData data = this.roadSegmentData.get(pair); if (data == null) { if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE || !pair.first.lastPoint || !pair.second.firstPoint) { - double localDist = MapUtils.getDistance(pair.first.getLatitude(), pair.first.getLongitude(), + distance += MapUtils.getDistance(pair.first.getLatitude(), pair.first.getLongitude(), pair.second.getLatitude(), pair.second.getLongitude()); - if (!Double.isNaN(pair.first.ele) && !Double.isNaN(pair.second.ele) && - pair.first.ele != 0 && pair.second.ele != 0) { - double h = Math.abs(pair.first.ele - pair.second.ele); - localDist = Math.sqrt(localDist * localDist + h * h); - } - distance += localDist; } } else { distance += data.getDistance(); @@ -1069,7 +1061,7 @@ public class MeasurementEditingContext { return new RouteExporter("", route, locations, null).generateRouteSegment(); } else if (endPointIndex - startPointIndex >= 0) { TrkSegment segment = new TrkSegment(); - segment.points = before.points.subList(startPointIndex, endPointIndex + 1); + segment.points = new ArrayList<>(before.points.subList(startPointIndex, endPointIndex + 1)); return segment; } return null; diff --git a/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java b/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java index 8134e5a3be..1d8a4e4aa6 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/EditPOIMenuController.java @@ -2,18 +2,23 @@ package net.osmand.plus.osmedit; import android.content.DialogInterface; import android.graphics.drawable.Drawable; + import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; + import net.osmand.data.PointDescription; import net.osmand.osm.PoiType; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MenuController; +import net.osmand.plus.measurementtool.LoginBottomSheetFragment; import net.osmand.plus.osmedit.OsmPoint.Action; -import net.osmand.plus.osmedit.dialogs.SendPoiDialogFragment; +import net.osmand.plus.osmedit.dialogs.SendPoiDialogFragment.SimpleProgressDialogPoiUploader; import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; import net.osmand.plus.render.RenderingIcons; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; import java.util.Map; @@ -40,15 +45,16 @@ public class EditPOIMenuController extends MenuController { public void buttonPressed() { MapActivity activity = getMapActivity(); if (plugin != null && activity != null) { - OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(activity.getMyApplication()); - if (client.isValidToken()){ - new SendPoiDialogFragment.SimpleProgressDialogPoiUploader(activity). - showProgressDialog(new OsmPoint[] { getOsmPoint() }, false, false); - } - else { - SendPoiDialogFragment sendPoiDialogFragment = - SendPoiDialogFragment.createInstance(new OsmPoint[]{getOsmPoint()}, SendPoiDialogFragment.PoiUploaderType.SIMPLE); - sendPoiDialogFragment.show(activity.getSupportFragmentManager(), SendPoiDialogFragment.TAG); + OsmandApplication app = activity.getMyApplication(); + OsmandSettings settings = app.getSettings(); + OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(app); + if (client.isValidToken() + || !Algorithms.isEmpty(settings.USER_NAME.get()) + && !Algorithms.isEmpty(settings.USER_PASSWORD.get())) { + SimpleProgressDialogPoiUploader poiDialogUploader = new SimpleProgressDialogPoiUploader(activity); + poiDialogUploader.showProgressDialog(new OsmPoint[] {getOsmPoint()}, false, false); + } else { + LoginBottomSheetFragment.showInstance(activity.getSupportFragmentManager(), null); } } } @@ -205,7 +211,7 @@ public class EditPOIMenuController extends MenuController { return null; } } - + @Override public int getAdditionalInfoIconRes() { if (osmPoint.getAction() == Action.DELETE) { diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingFragment.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingFragment.java index daaeb6d034..3435ad1561 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingFragment.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingFragment.java @@ -1,6 +1,5 @@ package net.osmand.plus.osmedit; -import android.content.Context; import android.content.Intent; import android.graphics.Typeface; import android.graphics.drawable.Drawable; @@ -8,12 +7,10 @@ import android.os.Bundle; import android.text.SpannableString; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.TextView; import androidx.fragment.app.FragmentManager; import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; import net.osmand.PlatformUtil; @@ -21,36 +18,37 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.FontCache; +import net.osmand.plus.measurementtool.LoginBottomSheetFragment; +import net.osmand.plus.measurementtool.LoginBottomSheetFragment.OsmAuthorizationListener; +import net.osmand.plus.osmedit.ValidateOsmLoginDetailsTask.ValidateOsmLoginListener; import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; import net.osmand.plus.settings.backend.OsmAndAppCustomization; -import net.osmand.plus.settings.bottomsheets.OsmLoginDataBottomSheet; import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.plus.settings.fragments.OnPreferenceChanged; import net.osmand.plus.settings.preferences.SwitchPreferenceEx; import net.osmand.plus.widgets.style.CustomTypefaceSpan; +import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; import static net.osmand.plus.osmedit.OsmEditingPlugin.OSM_EDIT_TAB; -public class OsmEditingFragment extends BaseSettingsFragment implements OnPreferenceChanged { +public class OsmEditingFragment extends BaseSettingsFragment implements OnPreferenceChanged, ValidateOsmLoginListener, OsmAuthorizationListener { private static final Log log = PlatformUtil.getLog(OsmEditingFragment.class); - private static final String OSM_EDITING_INFO = "osm_editing_info"; + private static final String OSM_LOGOUT = "osm_logout"; private static final String OPEN_OSM_EDITS = "open_osm_edits"; private static final String OSM_LOGIN_DATA = "osm_login_data"; - private static final String OSM_OAUTH_SUCCESS = "osm_oauth_success"; - private static final String OSM_OAUTH_CLEAR = "osm_oauth_clear"; - private static final String OSM_OAUTH_LOGIN = "osm_oauth_login"; + private static final String OSM_EDITING_INFO = "osm_editing_info"; - private OsmOAuthAuthorizationAdapter client; + private OsmOAuthAuthorizationAdapter authorizationAdapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - client = new OsmOAuthAuthorizationAdapter(app); + authorizationAdapter = new OsmOAuthAuthorizationAdapter(app); } @Override @@ -58,11 +56,12 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer Preference osmEditingInfo = findPreference(OSM_EDITING_INFO); osmEditingInfo.setIcon(getContentIcon(R.drawable.ic_action_info_dark)); - setupNameAndPasswordPref(); + setupLoginPref(); + setupLogoutPref(); + setupOfflineEditingPref(); setupOsmEditsDescrPref(); setupOsmEditsPref(); - setupOAuthPrefs(); } @Override @@ -83,10 +82,40 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer } } - private void setupNameAndPasswordPref() { + @Override + public void loginValidationFinished(String warning) { + updateAllSettings(); + } + + private void setupLoginPref() { Preference nameAndPasswordPref = findPreference(OSM_LOGIN_DATA); - nameAndPasswordPref.setSummary(settings.USER_NAME.get()); - nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_openstreetmap_logo)); + if (!isValidToken() && !isLoginExists()) { + nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_user_account)); + nameAndPasswordPref.setVisible(true); + } else { + nameAndPasswordPref.setVisible(false); + } + } + + private void setupLogoutPref() { + boolean validToken = isValidToken(); + Preference nameAndPasswordPref = findPreference(OSM_LOGOUT); + if (validToken || isLoginExists()) { + String userName = validToken ? settings.USER_DISPLAY_NAME.get() : settings.USER_NAME.get(); + nameAndPasswordPref.setVisible(true); + nameAndPasswordPref.setSummary(userName); + nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_user_account)); + } else { + nameAndPasswordPref.setVisible(false); + } + } + + private boolean isValidToken() { + return authorizationAdapter.isValidToken(); + } + + private boolean isLoginExists() { + return !Algorithms.isEmpty(settings.USER_NAME.get()) && !Algorithms.isEmpty(settings.USER_PASSWORD.get()); } private void setupOfflineEditingPref() { @@ -122,33 +151,6 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer createProfile.setIcon(getActiveIcon(R.drawable.ic_action_folder)); } - private void setupOAuthPrefs() { - Context ctx = getContext(); - if (ctx != null) { - PreferenceScreen screen = getPreferenceScreen(); - if (client.isValidToken()) { - Preference prefOAuth = new Preference(ctx); - prefOAuth.setTitle(R.string.osm_authorization_success); - prefOAuth.setSummary(R.string.osm_authorization_success); - prefOAuth.setKey(OSM_OAUTH_SUCCESS); - - Preference prefClearToken = new Preference(ctx); - prefClearToken.setTitle(R.string.shared_string_logoff); - prefClearToken.setSummary(R.string.clear_osm_token); - prefClearToken.setKey(OSM_OAUTH_CLEAR); - - screen.addPreference(prefOAuth); - screen.addPreference(prefClearToken); - } else { - Preference prefOAuth = new Preference(ctx); - prefOAuth.setTitle(R.string.perform_oauth_authorization); - prefOAuth.setSummary(R.string.perform_oauth_authorization_description); - prefOAuth.setKey(OSM_OAUTH_LOGIN); - screen.addPreference(prefOAuth); - } - } - } - @Override public boolean onPreferenceClick(Preference preference) { String prefId = preference.getKey(); @@ -165,42 +167,35 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer } else if (OSM_LOGIN_DATA.equals(prefId)) { FragmentManager fragmentManager = getFragmentManager(); if (fragmentManager != null) { - OsmLoginDataBottomSheet.showInstance(fragmentManager, OSM_LOGIN_DATA, this, false, getSelectedAppMode()); + LoginBottomSheetFragment.showInstance(fragmentManager, this); return true; } - } else if (OSM_OAUTH_CLEAR.equals(prefId)) { - settings.USER_ACCESS_TOKEN.set(""); - settings.USER_ACCESS_TOKEN_SECRET.set(""); - - client.resetToken(); - client = new OsmOAuthAuthorizationAdapter(app); + } else if (OSM_LOGOUT.equals(prefId)) { + if (isValidToken()) { + settings.USER_ACCESS_TOKEN.resetToDefault(); + settings.USER_ACCESS_TOKEN_SECRET.resetToDefault(); + authorizationAdapter.resetToken(); + authorizationAdapter = new OsmOAuthAuthorizationAdapter(app); + } else { + settings.USER_NAME.resetToDefault(); + settings.USER_PASSWORD.resetToDefault(); + } app.showShortToastMessage(R.string.osm_edit_logout_success); updateAllSettings(); return true; - } else if (OSM_OAUTH_LOGIN.equals(prefId)) { - View view = getView(); - if (view != null) { - ViewGroup appBarLayout = view.findViewById(R.id.appbar); - client.startOAuth(appBarLayout); - } - return true; } return super.onPreferenceClick(preference); } @Override public void onPreferenceChanged(String prefId) { - if (OSM_LOGIN_DATA.equals(prefId)) { - Preference nameAndPasswordPref = findPreference(OSM_LOGIN_DATA); - nameAndPasswordPref.setSummary(settings.USER_NAME.get()); - } + updateAllSettings(); } - public void authorize(String oauthVerifier) { - if (client != null) { - client.authorize(oauthVerifier); - } + @Override + public void authorizationCompleted() { + authorizationAdapter = new OsmOAuthAuthorizationAdapter(app); updateAllSettings(); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java index 285e323867..71da65bf20 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java @@ -1,6 +1,5 @@ package net.osmand.plus.osmedit; -import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; @@ -16,11 +15,11 @@ import android.view.View; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; @@ -41,6 +40,7 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TabActivity; import net.osmand.plus.dashboard.DashboardOnMap.DashboardType; import net.osmand.plus.dashboard.tools.DashFragmentData; +import net.osmand.plus.measurementtool.LoginBottomSheetFragment; import net.osmand.plus.myplaces.AvailableGPXFragment; import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo; import net.osmand.plus.myplaces.FavoritesActivity; @@ -395,15 +395,15 @@ public class OsmEditingPlugin extends OsmandPlugin { } @Override - public void contextMenuFragment(final Activity la, final Fragment fragment, final Object info, ContextMenuAdapter adapter) { + public void contextMenuFragment(final FragmentActivity activity, final Fragment fragment, final Object info, ContextMenuAdapter adapter) { if (fragment instanceof AvailableGPXFragment) { - adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.local_index_mi_upload_gpx, la) + adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.local_index_mi_upload_gpx, activity) .setIcon(R.drawable.ic_action_export) .setListener(new ContextMenuAdapter.ItemClickListener() { @Override public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { - sendGPXFiles(la, (AvailableGPXFragment) fragment, (GpxInfo) info); + sendGPXFiles(activity, (AvailableGPXFragment) fragment, (GpxInfo) info); return true; } }).createItem()); @@ -411,7 +411,7 @@ public class OsmEditingPlugin extends OsmandPlugin { } @Override - public void optionsMenuFragment(final Activity activity, final Fragment fragment, ContextMenuAdapter optionsMenuAdapter) { + public void optionsMenuFragment(final FragmentActivity activity, final Fragment fragment, ContextMenuAdapter optionsMenuAdapter) { if (fragment instanceof AvailableGPXFragment) { final AvailableGPXFragment f = ((AvailableGPXFragment) fragment); optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.local_index_mi_upload_gpx, activity) @@ -437,7 +437,6 @@ public class OsmEditingPlugin extends OsmandPlugin { } } - public enum UploadVisibility implements IEnumWithResource { Public(R.string.gpxup_public), Identifiable(R.string.gpxup_identifiable), @@ -459,16 +458,16 @@ public class OsmEditingPlugin extends OsmandPlugin { } } - public boolean sendGPXFiles(final Activity la, AvailableGPXFragment f, final GpxInfo... info) { + public boolean sendGPXFiles(final FragmentActivity activity, AvailableGPXFragment fragment, final GpxInfo... info) { String name = settings.USER_NAME.get(); String pwd = settings.USER_PASSWORD.get(); String authToken = settings.USER_ACCESS_TOKEN.get(); if ((Algorithms.isEmpty(name) || Algorithms.isEmpty(pwd)) && Algorithms.isEmpty(authToken)) { - Toast.makeText(la, R.string.validate_gpx_upload_name_pwd, Toast.LENGTH_LONG).show(); + LoginBottomSheetFragment.showInstance(activity.getSupportFragmentManager(), fragment.getTargetFragment()); return false; } - AlertDialog.Builder bldr = new AlertDialog.Builder(la); - LayoutInflater inflater = (LayoutInflater) la.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View view = inflater.inflate(R.layout.send_gpx_osm, null); final EditText descr = (EditText) view.findViewById(R.id.memory_size); if (info.length > 0 && info[0].getFileName() != null) { @@ -477,23 +476,23 @@ public class OsmEditingPlugin extends OsmandPlugin { } final EditText tags = (EditText) view.findViewById(R.id.TagsText); final Spinner visibility = ((Spinner) view.findViewById(R.id.Visibility)); - EnumAdapter adapter = new EnumAdapter<>(la, android.R.layout.simple_spinner_item, UploadVisibility.values()); + EnumAdapter adapter = new EnumAdapter<>(activity, android.R.layout.simple_spinner_item, UploadVisibility.values()); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); visibility.setAdapter(adapter); visibility.setSelection(0); - bldr.setView(view); - bldr.setNegativeButton(R.string.shared_string_no, null); - bldr.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { + builder.setView(view); + builder.setNegativeButton(R.string.shared_string_no, null); + builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - new UploadGPXFilesTask(la, descr.getText().toString(), tags.getText().toString(), + new UploadGPXFilesTask(activity, descr.getText().toString(), tags.getText().toString(), (UploadVisibility) visibility.getItemAtPosition(visibility.getSelectedItemPosition()) ).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, info); } }); - bldr.show(); + builder.show(); return true; } diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditsFragment.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditsFragment.java index 40f62e55b6..0a4cc5d7ff 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditsFragment.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditsFragment.java @@ -29,6 +29,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ActionMode; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; @@ -41,6 +42,8 @@ import net.osmand.osm.edit.Entity; import net.osmand.osm.edit.Node; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.measurementtool.LoginBottomSheetFragment; +import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -624,10 +627,20 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo } private void uploadItems(final OsmPoint[] items) { - SendPoiDialogFragment.createInstance(items, PoiUploaderType.FRAGMENT) - .show(getChildFragmentManager(), SendPoiDialogFragment.TAG); -// UploadOsmEditsConfirmDialogFragment.createInstancee(items).show(getChildFragmentManager(), -// UploadOsmEditsConfirmDialogFragment.TAG); + FragmentActivity activity = getActivity(); + if (activity != null) { + OsmandApplication app = getMyApplication(); + OsmandSettings settings = app.getSettings(); + OsmOAuthAuthorizationAdapter authorizationAdapter = new OsmOAuthAuthorizationAdapter(app); + if (authorizationAdapter.isValidToken() + || !Algorithms.isEmpty(settings.USER_NAME.get()) + && !Algorithms.isEmpty(settings.USER_PASSWORD.get())) { + SendPoiDialogFragment.createInstance(items, PoiUploaderType.FRAGMENT) + .show(getChildFragmentManager(), SendPoiDialogFragment.TAG); + } else { + LoginBottomSheetFragment.showInstance(activity.getSupportFragmentManager(), this); + } + } } public void showProgressDialog(OsmPoint[] points, boolean closeChangeSet, boolean anonymously) { diff --git a/OsmAnd/src/net/osmand/plus/osmedit/ValidateOsmLoginDetailsTask.java b/OsmAnd/src/net/osmand/plus/osmedit/ValidateOsmLoginDetailsTask.java index 722f104c51..5dabe123b4 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/ValidateOsmLoginDetailsTask.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/ValidateOsmLoginDetailsTask.java @@ -2,6 +2,8 @@ package net.osmand.plus.osmedit; import android.os.AsyncTask; +import androidx.annotation.NonNull; + import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; @@ -10,9 +12,11 @@ import net.osmand.plus.osmedit.OsmBugsUtil.OsmBugResult; public class ValidateOsmLoginDetailsTask extends AsyncTask { private OsmandApplication app; + private ValidateOsmLoginListener validateListener; - public ValidateOsmLoginDetailsTask(OsmandApplication app) { + public ValidateOsmLoginDetailsTask(@NonNull OsmandApplication app, ValidateOsmLoginListener validateListener) { this.app = app; + this.validateListener = validateListener; } @Override @@ -26,9 +30,20 @@ public class ValidateOsmLoginDetailsTask extends AsyncTask hidePolygonsPref = - mapActivity.getMyApplication().getSettings().getCustomRenderBooleanProperty("noPolygons"); - hidePolygonsPref.set(hasUnderlayDescription); RasterMapMenu.refreshMapComplete(mapActivity); } } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index d24dd23ee6..a574e0d0fd 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -1088,6 +1088,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference USER_NAME = new StringPreference(this, "user_name", "").makeGlobal().makeShared(); + public final OsmandPreference USER_DISPLAY_NAME = new StringPreference(this, "user_display_name", "").makeGlobal().makeShared(); public static final String BILLING_USER_DONATION_WORLD_PARAMETER = ""; public static final String BILLING_USER_DONATION_NONE_PARAMETER = "none"; diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/OsmLoginDataBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/OsmLoginDataBottomSheet.java index 2b7494f0a4..9863c0ee92 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/OsmLoginDataBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/OsmLoginDataBottomSheet.java @@ -10,16 +10,17 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; -import androidx.preference.Preference; -import net.osmand.plus.osmedit.ValidateOsmLoginDetailsTask; -import net.osmand.plus.settings.backend.ApplicationMode; +import com.google.android.material.textfield.TextInputLayout; + import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; -import net.osmand.plus.settings.fragments.OnPreferenceChanged; +import net.osmand.plus.osmedit.ValidateOsmLoginDetailsTask; +import net.osmand.plus.osmedit.ValidateOsmLoginDetailsTask.ValidateOsmLoginListener; +import net.osmand.plus.settings.backend.ApplicationMode; public class OsmLoginDataBottomSheet extends BasePreferenceBottomSheet { @@ -55,6 +56,14 @@ public class OsmLoginDataBottomSheet extends BasePreferenceBottomSheet { userNameEditText.setText(name); passwordEditText.setText(password); + TextInputLayout loginBox = view.findViewById(R.id.name_text_box); + TextInputLayout passwordBox = view.findViewById(R.id.password_text_box); + + passwordBox.setStartIconDrawable(R.drawable.ic_action_lock); + loginBox.setStartIconDrawable(R.drawable.ic_action_user_account); + loginBox.setEndIconMode(TextInputLayout.END_ICON_CLEAR_TEXT); + passwordBox.setEndIconMode(TextInputLayout.END_ICON_PASSWORD_TOGGLE); + BaseBottomSheetItem titleItem = new SimpleBottomSheetItem.Builder() .setCustomView(view) .create(); @@ -75,7 +84,7 @@ public class OsmLoginDataBottomSheet extends BasePreferenceBottomSheet { @Override protected int getRightBottomButtonTextId() { - return R.string.shared_string_apply; + return R.string.user_login; } @Override @@ -84,12 +93,11 @@ public class OsmLoginDataBottomSheet extends BasePreferenceBottomSheet { app.getSettings().USER_NAME.set(userNameEditText.getText().toString()); app.getSettings().USER_PASSWORD.set(passwordEditText.getText().toString()); - new ValidateOsmLoginDetailsTask(app).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - Fragment target = getTargetFragment(); - Preference preference = getPreference(); - if (target instanceof OnPreferenceChanged && preference != null) { - ((OnPreferenceChanged) target).onPreferenceChanged(preference.getKey()); + Fragment targetFragment = getTargetFragment(); + if (targetFragment instanceof ValidateOsmLoginListener) { + ValidateOsmLoginDetailsTask validateTask = new ValidateOsmLoginDetailsTask(app, (ValidateOsmLoginListener) targetFragment); + validateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } dismiss(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java index 34e57bbf12..94d711a89b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java @@ -84,7 +84,7 @@ public class ImportCompleteFragment extends BaseOsmAndFragment { View root = inflater.inflate(R.layout.fragment_import_complete, container, false); TextView description = root.findViewById(R.id.description); TextView btnClose = root.findViewById(R.id.button_close); - final LinearLayout buttonContainer = root.findViewById(R.id.button_container); + final ViewGroup buttonContainer = root.findViewById(R.id.button_container); recyclerView = root.findViewById(R.id.list); description.setText(UiUtilities.createSpannableString( String.format(getString(R.string.import_complete_description), fileName), diff --git a/OsmAnd/src/net/osmand/plus/views/AnimateDraggingMapThread.java b/OsmAnd/src/net/osmand/plus/views/AnimateDraggingMapThread.java index 0323498479..3df649ea2b 100644 --- a/OsmAnd/src/net/osmand/plus/views/AnimateDraggingMapThread.java +++ b/OsmAnd/src/net/osmand/plus/views/AnimateDraggingMapThread.java @@ -225,6 +225,13 @@ public class AnimateDraggingMapThread { if (!stopped) { animatingMoveInThread(mMoveX, mMoveY, animationTime, notifyListener, finishAnimationCallback); + } else if (finishAnimationCallback != null) { + tileView.getApplication().runInUIThread(new Runnable() { + @Override + public void run() { + finishAnimationCallback.run(); + } + }); } if (!stopped) { tileView.setLatLonAnimate(finalLat, finalLon, notifyListener);