diff --git a/OsmAnd/res/layout/fragment_live_updates.xml b/OsmAnd/res/layout/fragment_live_updates.xml index e0fd41c95e..93c11c599f 100644 --- a/OsmAnd/res/layout/fragment_live_updates.xml +++ b/OsmAnd/res/layout/fragment_live_updates.xml @@ -1,5 +1,4 @@ - - - - - - - - - - - - + android:orientation="vertical" /> + android:paddingBottom="@dimen/bottom_sheet_list_item_height" + tools:context=".liveupdates.LiveUpdatesFragment" /> diff --git a/OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml b/OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml index 1f179b8178..c030d97625 100644 --- a/OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml +++ b/OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml @@ -84,12 +84,12 @@ \ No newline at end of file diff --git a/OsmAnd/res/layout/osm_live_banner_list_item.xml b/OsmAnd/res/layout/osm_live_banner_list_item.xml index 05d83d8da1..12f59c3ef0 100644 --- a/OsmAnd/res/layout/osm_live_banner_list_item.xml +++ b/OsmAnd/res/layout/osm_live_banner_list_item.xml @@ -29,13 +29,14 @@ android:layout_weight="1" android:orientation="vertical"> - + android:textSize="@dimen/default_list_text_size" + osmand:typeface="@string/font_roboto_medium" /> - + android:textSize="@dimen/default_desc_text_size" + osmand:typeface="@string/font_roboto_medium" /> + Update all maps added to %1$s? • OsmAnd Live updates moved to \"Downloads > Updates\"\n\n • Tracks now could be colorizing by altitude, speed, or slope.\n\n diff --git a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java index f6cf6b03cc..ae0ab9b560 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java @@ -38,8 +38,9 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates; -import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; +import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; +import net.osmand.plus.liveupdates.LiveUpdatesFragment; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.LiveUpdateListener; import net.osmand.plus.liveupdates.LoadLiveMapsTask; import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; import net.osmand.plus.chooseplan.ChoosePlanDialogFragment.ChoosePlanDialogType; @@ -58,10 +59,10 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.showUpdateDialog; -import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.updateCountEnabled; +import static net.osmand.plus.liveupdates.LiveUpdatesFragment.showUpdateDialog; +import static net.osmand.plus.liveupdates.LiveUpdatesFragment.updateCountEnabled; -public class UpdatesIndexFragment extends OsmAndListFragment implements DownloadEvents, RefreshLiveUpdates { +public class UpdatesIndexFragment extends OsmAndListFragment implements DownloadEvents, RefreshLiveUpdates, LiveUpdateListener { private static final int RELOAD_ID = 5; private UpdateIndexAdapter listAdapter; private String errorMessage; @@ -236,7 +237,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download DownloadActivity activity = getMyActivity(); if (activity != null) { if (!listAdapter.isShowOsmLivePurchaseBanner()) { - LiveUpdatesFragmentNew.showInstance(activity.getSupportFragmentManager(), this); + LiveUpdatesFragment.showInstance(activity.getSupportFragmentManager(), this); } } } else { @@ -397,8 +398,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download @Override public void onClick(View v) { if (!listAdapter.isShowOsmLivePurchaseBanner()) { - showUpdateDialog(getActivity(), getMyApplication().getSettings(), - listAdapter.mapsList, listAdapter.countEnabled, null); + showUpdateDialog(getActivity(), getFragmentManager(), UpdatesIndexFragment.this); } } }); @@ -416,9 +416,17 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download } } + @Override + public void processFinish() { + } + + @Override + public List getMapsToUpdate() { + return LiveUpdatesFragment.getMapsToUpdate(listAdapter.mapsList, settings); + } + @ColorRes public static int getDefaultIconColorId(boolean nightMode) { return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; } - } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesAlarmReceiver.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesAlarmReceiver.java index 78d84bf220..a51140fbab 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesAlarmReceiver.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesAlarmReceiver.java @@ -32,7 +32,8 @@ public class LiveUpdatesAlarmReceiver extends BroadcastReceiver { final OsmandSettings settings = application.getSettings(); if (!preferenceDownloadViaWiFi(localIndexInfoFile, settings).get() || wifi.isWifiEnabled()) { - new PerformLiveUpdateAsyncTask(context, localIndexInfoFile, false, null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fileName); + new PerformLiveUpdateAsyncTask(context, localIndexInfoFile, false) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fileName); } else { PerformLiveUpdateAsyncTask.tryRescheduleDownload(context, settings, localIndexInfoFile); } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearDialogFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearBottomSheet.java similarity index 93% rename from OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearDialogFragment.java rename to OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearBottomSheet.java index c54daada1a..dc199d61de 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearBottomSheet.java @@ -31,10 +31,10 @@ import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable; -public class LiveUpdatesClearDialogFragment extends MenuBottomSheetDialogFragment { +public class LiveUpdatesClearBottomSheet extends MenuBottomSheetDialogFragment { - public static final String TAG = LiveUpdatesClearDialogFragment.class.getSimpleName(); - private static final Log LOG = PlatformUtil.getLog(LiveUpdatesClearDialogFragment.class); + public static final String TAG = LiveUpdatesClearBottomSheet.class.getSimpleName(); + private static final Log LOG = PlatformUtil.getLog(LiveUpdatesClearBottomSheet.class); private static final String LOCAL_INDEX_FILE_NAME = "local_index_file_name"; private OsmandApplication app; @@ -44,7 +44,7 @@ public class LiveUpdatesClearDialogFragment extends MenuBottomSheetDialogFragmen public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, String fileName) { if (!fragmentManager.isStateSaved()) { - LiveUpdatesClearDialogFragment fragment = new LiveUpdatesClearDialogFragment(); + LiveUpdatesClearBottomSheet fragment = new LiveUpdatesClearBottomSheet(); fragment.setTargetFragment(target, 0); fragment.fileName = fileName; fragment.show(fragmentManager, TAG); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index f6c3bd4b66..23d963c4e5 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -4,149 +4,172 @@ import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; +import android.content.DialogInterface; +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; import android.widget.CompoundButton; import android.widget.ExpandableListView; -import android.widget.ImageButton; +import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.ProgressBar; import android.widget.TextView; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; -import net.osmand.plus.Version; -import net.osmand.plus.activities.LocalIndexHelper; -import net.osmand.plus.activities.LocalIndexInfo; -import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; -import net.osmand.plus.activities.OsmandInAppPurchaseActivity; -import net.osmand.plus.base.BaseOsmAndFragment; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment.ChoosePlanDialogType; -import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; -import net.osmand.plus.inapp.InAppPurchaseHelper; -import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; -import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType; -import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; -import net.osmand.plus.resources.IncrementalChangesManager; -import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.util.Algorithms; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import androidx.annotation.DrawableRes; +import androidx.annotation.ColorRes; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.appcompat.widget.AppCompatImageButton; +import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.SwitchCompat; +import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; -import androidx.fragment.app.FragmentActivity; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.showUpdateDialog; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.DEFAULT_LAST_CHECK; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatDateTime; +import com.google.android.material.appbar.AppBarLayout; + +import net.osmand.AndroidNetworkUtils; +import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.CompoundButtonType; +import net.osmand.plus.activities.LocalIndexInfo; +import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; +import net.osmand.plus.base.BaseOsmAndDialogFragment; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.helpers.FontCache; +import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; +import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.LiveUpdateListener; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; +import net.osmand.plus.liveupdates.LiveUpdatesSettingsBottomSheet.OnLiveUpdatesForLocalChange; +import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.widgets.TextViewEx; +import net.osmand.plus.wikipedia.WikipediaDialogFragment; +import net.osmand.util.Algorithms; + +import org.apache.commons.logging.Log; + +import java.lang.ref.WeakReference; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import static net.osmand.AndroidUtils.getSecondaryTextColorId; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatShortDateTime; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLiveUpdatesOn; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent; +import static net.osmand.plus.liveupdates.LiveUpdatesSettingsBottomSheet.getTertiaryTextColorId; +import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getActiveTextColorId; +import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getOsmandIconColorId; +import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getSecondaryIconColorId; -public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurchaseListener { - public static final int TITLE = R.string.live_updates; - private static final int SUBSCRIPTION_SETTINGS = 5; - public static final Comparator LOCAL_INDEX_INFO_COMPARATOR = new Comparator() { - @Override - public int compare(LocalIndexInfo lhs, LocalIndexInfo rhs) { - return lhs.getName().compareTo(rhs.getName()); - } - }; +public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnLiveUpdatesForLocalChange, LiveUpdateListener { + + public static final String URL = "https://osmand.net/api/osmlive_status"; + public static final String TAG = LiveUpdatesFragment.class.getSimpleName(); + private final static Log LOG = PlatformUtil.getLog(LiveUpdatesFragment.class); + private static final String SUBSCRIPTION_URL = "https://osmand.net/features/subscription"; private OsmandApplication app; - private View subscriptionHeader; + private OsmandSettings settings; + private boolean nightMode; + + private View toolbarSwitchContainer; private ExpandableListView listView; - private LocalIndexesAdapter adapter; - private AsyncTask> loadLocalIndexesTask; - private boolean showSettingsOnly; + private TextViewEx descriptionTime; + private LiveMapsAdapter adapter; - private ProgressBar progressBar; - private boolean processing; + private GetLastUpdateDateTask getLastUpdateDateTask; + private LoadLiveMapsTask loadLiveMapsTask; - @Nullable - public InAppPurchaseHelper getInAppPurchaseHelper() { - Activity activity = getActivity(); - if (activity instanceof OsmandInAppPurchaseActivity) { - return ((OsmandInAppPurchaseActivity) activity).getPurchaseHelper(); - } else { - return null; + public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target) { + if (!fragmentManager.isStateSaved()) { + LiveUpdatesFragment fragment = new LiveUpdatesFragment(); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, TAG); } } - private boolean isProcessing() { - return processing; + public static void showUpdateDialog(Activity context, FragmentManager fragmentManager, final LiveUpdateListener listener) { + List mapsToUpdate = listener.getMapsToUpdate(); + if (!Algorithms.isEmpty(mapsToUpdate)) { + int countEnabled = listener.getMapsToUpdate().size(); + if (countEnabled == 1) { + runLiveUpdate(context, mapsToUpdate.get(0).getFileName(), false, new Runnable() { + @Override + public void run() { + listener.processFinish(); + } + }); + } else if (countEnabled > 1) { + Fragment target = null; + if (listener instanceof Fragment) { + target = (Fragment) listener; + } + LiveUpdatesUpdateAllBottomSheet.showInstance(fragmentManager, target); + } + } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setHasOptionsMenu(true); app = getMyApplication(); - if (getActivity() instanceof OsmLiveActivity) { - showSettingsOnly = ((OsmLiveActivity) getActivity()).isShowSettingOnly(); - } + settings = getSettings(); + nightMode = isNightMode(false); + setHasOptionsMenu(true); } @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_live_updates, container, false); - listView = (ExpandableListView) view.findViewById(android.R.id.list); + createToolbar((ViewGroup) view.findViewById(R.id.app_bar)); - boolean nightMode = !app.getSettings().isLightContent(); - final SwipeRefreshLayout swipeRefresh = view.findViewById(R.id.swipe_refresh); - int swipeColor = ContextCompat.getColor(app, nightMode ? R.color.osmand_orange_dark : R.color.osmand_orange); - swipeRefresh.setColorSchemeColors(swipeColor); - swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - showUpdateDialog(getActivity(), getSettings(), adapter.dataShouldUpdate, adapter.dataShouldUpdate.size(), null); - swipeRefresh.setRefreshing(false); - } - }); + listView = (ExpandableListView) view.findViewById(android.R.id.list); + adapter = new LiveMapsAdapter(); + listView.setAdapter(adapter); + expandAllGroups(); View bottomShadowView = inflater.inflate(R.layout.card_bottom_divider, listView, false); - if (!showSettingsOnly) { - listView.addFooterView(bottomShadowView); - } - adapter = new LocalIndexesAdapter(this); + listView.addFooterView(bottomShadowView); listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - if (!processing && InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - final FragmentManager fragmentManager = getChildFragmentManager(); - LiveUpdatesSettingsDialogFragment - .createInstance(adapter.getChild(groupPosition, childPosition).getFileName()) - .show(fragmentManager, "settings"); + if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app) && settings.IS_LIVE_UPDATES_ON.get()) { + if (getFragmentManager() != null) { + LiveUpdatesSettingsBottomSheet + .showInstance(getFragmentManager(), LiveUpdatesFragment.this, + adapter.getChild(groupPosition, childPosition).getFileName()); + } return true; } else { return false; @@ -154,128 +177,519 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc } }); - progressBar = (ProgressBar) view.findViewById(R.id.progress); + final SwipeRefreshLayout swipeRefresh = view.findViewById(R.id.swipe_refresh); + int swipeColor = ContextCompat.getColor(app, nightMode ? R.color.osmand_orange_dark : R.color.osmand_orange); + swipeRefresh.setColorSchemeColors(swipeColor); + swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + if (settings.IS_LIVE_UPDATES_ON.get()) { + showUpdateDialog(getActivity(), getFragmentManager(), LiveUpdatesFragment.this); + startUpdateDateAsyncTask(); + } + swipeRefresh.setRefreshing(false); + } + }); - if (!Version.isDeveloperVersion(app)) { - subscriptionHeader = inflater.inflate(R.layout.live_updates_header, listView, false); - updateSubscriptionHeader(); - listView.addHeaderView(subscriptionHeader, "subscriptionHeader", false); + View headerView = inflater.inflate(R.layout.list_item_import, listView, false); + View timeContainer = headerView.findViewById(R.id.item_import_container); + AndroidUtils.setListItemBackground(app, timeContainer, nightMode); + AndroidUiHelper.setVisibility(View.VISIBLE, headerView.findViewById(R.id.bottom_divider)); + listView.addHeaderView(headerView); + + AppCompatImageView descriptionIcon = timeContainer.findViewById(R.id.icon); + Drawable icon = UiUtilities.createTintedDrawable(app, R.drawable.ic_action_time, + ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light)); + descriptionIcon.setImageDrawable(icon); + + TextViewEx title = timeContainer.findViewById(R.id.title); + AndroidUtils.setTextSecondaryColor(app, title, nightMode); + title.setText(R.string.latest_openstreetmap_update); + title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_desc_text_size)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + title.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing)); } - listView.setAdapter(adapter); - if (!showSettingsOnly) { - loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + descriptionTime = timeContainer.findViewById(R.id.sub_title); + AndroidUtils.setTextPrimaryColor(app, descriptionTime, nightMode); + Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium)); + descriptionTime.setTypeface(typeface); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + descriptionTime.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing)); } return view; } - public void updateSubscriptionHeader() { - if (getActivity() instanceof OsmLiveActivity && subscriptionHeader != null) { - View subscriptionBanner = subscriptionHeader.findViewById(R.id.subscription_banner); - View subscriptionInfo = subscriptionHeader.findViewById(R.id.subscription_info); - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - ImageView statusIcon = (ImageView) subscriptionHeader.findViewById(R.id.statusIcon); - TextView statusTextView = (TextView) subscriptionHeader.findViewById(R.id.statusTextView); - TextView regionNameHeaderTextView = (TextView) subscriptionHeader.findViewById(R.id.regionHeaderTextView); - TextView regionNameTextView = (TextView) subscriptionHeader.findViewById(R.id.regionTextView); - statusTextView.setText(getString(R.string.osm_live_active)); - statusIcon.setImageDrawable(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_done)); - - String countryName = getSupportRegionName(app, getInAppPurchaseHelper()); - String header = getSupportRegionHeader(app, countryName); - regionNameHeaderTextView.setText(header); - regionNameTextView.setText(countryName); - - View subscriptionsButton = subscriptionHeader.findViewById(R.id.button_subscriptions); - View settingsButtonContainer = subscriptionHeader.findViewById(R.id.button_settings_container); - View settingsButton = subscriptionHeader.findViewById(R.id.button_settings); - subscriptionsButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ChoosePlanDialogFragment.showDialogInstance(app, getActivity().getSupportFragmentManager(), ChoosePlanDialogType.OSM_LIVE); - } - }); - if (isDonationSupported()) { - settingsButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - showDonationSettings(); - } - }); - settingsButtonContainer.setVisibility(View.VISIBLE); - } else { - settingsButton.setOnClickListener(null); - settingsButtonContainer.setVisibility(View.GONE); - } - - subscriptionBanner.setVisibility(View.GONE); - subscriptionInfo.setVisibility(View.VISIBLE); - } else { - Button readMoreBtn = (Button) subscriptionHeader.findViewById(R.id.read_more_button); - readMoreBtn.setEnabled(!processing); - readMoreBtn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Uri uri = Uri.parse("https://osmand.net/osm_live"); - Intent goToOsmLive = new Intent(Intent.ACTION_VIEW, uri); - startActivity(goToOsmLive); - } - }); - Button subscriptionButton = (Button) subscriptionHeader.findViewById(R.id.subscription_button); - subscriptionButton.setEnabled(!processing); - subscriptionButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentActivity activity = getActivity(); - if (activity != null) { - ChoosePlanDialogFragment.showDialogInstance(app, activity.getSupportFragmentManager(), ChoosePlanDialogType.OSM_LIVE); - } - } - }); - - subscriptionBanner.setVisibility(View.VISIBLE); - subscriptionInfo.setVisibility(View.GONE); - } - } - } - @Override public void onResume() { super.onResume(); - InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper(); - if (purchaseHelper != null) { - if (purchaseHelper.getActiveTask() == InAppPurchaseTaskType.REQUEST_INVENTORY) { - enableProgress(); + startUpdateDateAsyncTask(); + startLoadLiveMapsAsyncTask(); + } + + @Override + public void onPause() { + super.onPause(); + stopUpdateDateAsyncTask(); + stopLoadLiveMapsAsyncTask(); + } + + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + super.onDismiss(dialog); + Fragment target = getTargetFragment(); + if (target instanceof RefreshLiveUpdates) { + ((RefreshLiveUpdates) target).onUpdateStates(app); + } + } + + private void startUpdateDateAsyncTask() { + getLastUpdateDateTask = new GetLastUpdateDateTask(this); + getLastUpdateDateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + private void stopUpdateDateAsyncTask() { + if (getLastUpdateDateTask != null) { + getLastUpdateDateTask.cancel(true); + } + } + + private void startLoadLiveMapsAsyncTask() { + if (loadLiveMapsTask == null) { + loadLiveMapsTask = new LoadLiveMapsTask(adapter, app); + loadLiveMapsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } + + private void stopLoadLiveMapsAsyncTask() { + if (loadLiveMapsTask != null && loadLiveMapsTask.getStatus() == AsyncTask.Status.RUNNING) { + loadLiveMapsTask.cancel(false); + } + } + + protected void createToolbar(ViewGroup appBar) { + AppBarLayout appBarLayout = (AppBarLayout) UiUtilities.getInflater(getActivity(), nightMode) + .inflate(R.layout.global_preferences_toolbar_with_switch, appBar); + + Toolbar toolbar = (Toolbar) appBarLayout.findViewById(R.id.toolbar); + TextViewEx toolbarTitle = (TextViewEx) toolbar.findViewById(R.id.toolbar_title); + toolbarTitle.setText(R.string.osm_live); + + View closeButton = toolbar.findViewById(R.id.close_button); + closeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + + FrameLayout iconHelpContainer = toolbar.findViewById(R.id.action_button); + int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; + AppCompatImageButton iconHelp = toolbar.findViewById(R.id.action_button_icon); + Drawable helpDrawable = app.getUIUtilities().getIcon(R.drawable.ic_action_help_online, iconColorResId); + iconHelp.setImageDrawable(helpDrawable); + iconHelpContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Activity activity = getActivity(); + if (activity != null) { + WikipediaDialogFragment.showFullArticle(activity, Uri.parse(SUBSCRIPTION_URL), nightMode); + } + } + }); + + toolbarSwitchContainer = appBarLayout.findViewById(R.id.toolbar_switch_container); + updateToolbarSwitch(settings.IS_LIVE_UPDATES_ON.get()); + } + + private void updateToolbarSwitch(final boolean isChecked) { + int switchColor = ContextCompat.getColor(app, + isChecked ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode)); + AndroidUtils.setBackground(toolbarSwitchContainer, new ColorDrawable(switchColor)); + + SwitchCompat switchView = toolbarSwitchContainer.findViewById(R.id.switchWidget); + switchView.setChecked(isChecked); + UiUtilities.setupCompoundButton(switchView, nightMode, CompoundButtonType.TOOLBAR); + + toolbarSwitchContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + boolean visible = !isChecked; + if (visible) { + if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { + switchOnLiveUpdates(); + updateToolbarSwitch(true); + } else { + app.showToastMessage(getString(R.string.osm_live_ask_for_purchase)); + updateToolbarSwitch(false); + } + } else { + settings.IS_LIVE_UPDATES_ON.set(false); + enableLiveUpdates(false); + updateToolbarSwitch(false); + } + updateList(); + } + }); + + TextView title = toolbarSwitchContainer.findViewById(R.id.switchButtonText); + title.setText(isChecked ? R.string.shared_string_enabled : R.string.shared_string_disabled); + } + + private void switchOnLiveUpdates() { + settings.IS_LIVE_UPDATES_ON.set(true); + enableLiveUpdates(true); + showUpdateDialog(getMyActivity(), getFragmentManager(), this); + startUpdateDateAsyncTask(); + } + + private void enableLiveUpdates(boolean enable) { + if (!Algorithms.isEmpty(adapter.mapsList)) { + AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); + List mapsToUpdate = getMapsToUpdate(adapter.mapsList, settings); + for (LocalIndexInfo li : mapsToUpdate) { + String fileName = li.getFileName(); + PendingIntent alarmIntent = getPendingIntent(app, fileName); + if (enable) { + final CommonPreference updateFrequencyPreference = + preferenceUpdateFrequency(fileName, settings); + final CommonPreference timeOfDayPreference = + preferenceTimeOfDayToUpdate(fileName, settings); + UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; + TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; + setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); + } else { + alarmMgr.cancel(alarmIntent); + } } } } + private void expandAllGroups() { + for (int i = 0; i < adapter.getGroupCount(); i++) { + listView.expandGroup(i); + } + } + + public static int updateCountEnabled(TextView countView, List mapsList, OsmandSettings settings) { + int countEnabled = getMapsToUpdate(mapsList, settings).size(); + if (countView != null) { + String countText = countEnabled + "/" + mapsList.size(); + countView.setText(countText); + } + return countEnabled; + } + + public static List getMapsToUpdate(List mapsList, OsmandSettings settings) { + List listToUpdate = new ArrayList<>(); + for (LocalIndexInfo mapToUpdate : mapsList) { + CommonPreference preference = preferenceForLocalIndex(mapToUpdate.getFileName(), settings); + if (preference.get()) { + listToUpdate.add(mapToUpdate); + } + } + return listToUpdate; + } + + protected class LiveMapsAdapter extends OsmandBaseExpandableListAdapter implements LocalIndexInfoAdapter { + private final ArrayList mapsList = new ArrayList<>(); + + @Override + public void addData(LocalIndexInfo info) { + mapsList.add(info); + } + + @Override + public void clearData() { + mapsList.clear(); + } + + @Override + public void onDataUpdated() { + sort(); + } + + public void sort() { + Collections.sort(mapsList, new Comparator() { + @Override + public int compare(LocalIndexInfo o1, LocalIndexInfo o2) { + CommonPreference preference1 = preferenceForLocalIndex(o1.getFileName(), getSettings()); + CommonPreference preference2 = preferenceForLocalIndex(o2.getFileName(), getSettings()); + return preference2.get().compareTo(preference1.get()); + } + }); + notifyDataSetInvalidated(); + } + + @Override + public LocalIndexInfo getChild(int groupPosition, int childPosition) { + return mapsList.get(childPosition); + } + + @Override + public long getChildId(int groupPosition, int childPosition) { + return groupPosition * 10000 + childPosition; // it would be unusable to have 10000 local indexes + } + + @Override + public View getChildView(final int groupPosition, final int childPosition, + boolean isLastChild, View convertView, ViewGroup parent) { + LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); + convertView = inflater.inflate(R.layout.list_item_triple_row_icon_and_menu, parent, false); + LiveMapsViewHolder viewHolder = new LiveMapsViewHolder(convertView); + convertView.setTag(viewHolder); + viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName()); + return convertView; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { + View view = convertView; + if (view == null) { + LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); + view = inflater.inflate(R.layout.list_group_title_with_right_descr, parent, false); + } + view.setOnClickListener(null); + View topShadowView = view.findViewById(R.id.bottomShadowView); + if (groupPosition == 0) { + topShadowView.setVisibility(View.GONE); + } else { + topShadowView.setVisibility(View.VISIBLE); + } + + TextViewEx titleView = ((TextViewEx) view.findViewById(R.id.title)); + titleView.setText(getGroup(groupPosition)); + + TextViewEx countView = ((TextViewEx) view.findViewById(R.id.description)); + AndroidUtils.setTextSecondaryColor(app, countView, nightMode); + + return view; + } + + @Override + public int getChildrenCount(int groupPosition) { + return mapsList.size(); + } + + @Override + public String getGroup(int groupPosition) { + return getString(R.string.available_maps); + } + + @Override + public int getGroupCount() { + return 1; + } + + @Override + public long getGroupId(int groupPosition) { + return groupPosition; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } + } + + private class LiveMapsViewHolder { + private final ImageView statusIcon; + private final TextView title; + private final TextView subTitle; + private final TextView description; + private final CompoundButton compoundButton; + + private LiveMapsViewHolder(View view) { + statusIcon = (AppCompatImageView) view.findViewById(R.id.icon); + title = (TextView) view.findViewById(R.id.title); + subTitle = (TextView) view.findViewById(R.id.sub_title); + description = (TextView) view.findViewById(R.id.description); + compoundButton = (CompoundButton) view.findViewById(R.id.compound_button); + } + + public void bindLocalIndexInfo(@NonNull final String item) { + boolean liveUpdateOn = settings.IS_LIVE_UPDATES_ON.get(); + CommonPreference localUpdateOn = preferenceForLocalIndex(item, settings); +// IncrementalChangesManager changesManager = app.getResourceManager().getChangesManager(); + compoundButton.setChecked(localUpdateOn.get()); + if (!liveUpdateOn && localUpdateOn.get()) { + UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app, getTertiaryTextColorId(nightMode)), compoundButton); + } else { + UiUtilities.setupCompoundButton(compoundButton, nightMode, CompoundButtonType.GLOBAL); + } + + title.setText(getNameToDisplay(item, app)); + + AndroidUiHelper.updateVisibility(subTitle, localUpdateOn.get()); + if (localUpdateOn.get()) { + int frequencyId = preferenceUpdateFrequency(item, settings).get(); + final UpdateFrequency frequency = UpdateFrequency.values()[frequencyId]; + String subTitleText = getString(frequency.getLocalizedId()); + /*int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(item, settings).get(); + final TimeOfDay timeOfDay = TimeOfDay.values()[timeOfDateToUpdateId]; + if (frequency != UpdateFrequency.HOURLY) { + subTitleText += " • " + getString(timeOfDay.getLocalizedId()); + }*/ + subTitle.setText(subTitleText); + subTitle.setTextColor(ContextCompat.getColor(app, liveUpdateOn + ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode))); + Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium)); + subTitle.setTypeface(typeface); + } + + Drawable statusDrawable = AppCompatResources.getDrawable(app, R.drawable.ic_map); + int resColorId = !localUpdateOn.get() ? getSecondaryIconColorId(nightMode) : + !liveUpdateOn ? getDefaultIconColorId(nightMode) : getOsmandIconColorId(nightMode); + int statusColor = ContextCompat.getColor(app, resColorId); + if (statusDrawable != null) { + DrawableCompat.setTint(statusDrawable, statusColor); + } + statusIcon.setImageDrawable(statusDrawable); + + description.setText(getLastCheckString(item, app)); + + if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { + compoundButton.setEnabled(liveUpdateOn); + compoundButton.setOnCheckedChangeListener(new SwitchCompat.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + onUpdateLocalIndex(item, isChecked, new Runnable() { + @Override + public void run() { + runSort(); + } + }); + } + }); + } else { + compoundButton.setEnabled(false); + } + } + } + + public static class GetLastUpdateDateTask extends AsyncTask { + + private final OsmandApplication app; + private final WeakReference fragment; + + GetLastUpdateDateTask(LiveUpdatesFragment fragment) { + this.fragment = new WeakReference<>(fragment); + app = fragment.getMyApplication(); + } + + @Override + protected String doInBackground(Void... params) { + try { + return AndroidNetworkUtils.sendRequest(app, URL, null, + "Requesting map updates info...", false, false); + } catch (Exception e) { + LOG.error("Error: " + "Requesting map updates info error", e); + return null; + } + } + + @Override + protected void onPostExecute(String response) { + LiveUpdatesFragment f = fragment.get(); + if (response != null && f != null) { + TextViewEx descriptionTime = f.descriptionTime; + if (descriptionTime != null) { + SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); + source.setTimeZone(TimeZone.getTimeZone("UTC")); + SimpleDateFormat dest = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); + dest.setTimeZone(TimeZone.getDefault()); + try { + LOG.debug("response = " + response); + Date parsed = source.parse(response); + if (parsed != null) { + long dateTime = parsed.getTime(); + LOG.debug("dateTime = " + dateTime); + descriptionTime.setText(dest.format(parsed)); + } + } catch (ParseException e) { + LOG.error(e.getMessage()); + } + } + } + } + } + + protected static String getLastCheckString(String fileName, OsmandApplication app) { + return getLastCheckString(fileName, app, false); + } + + protected static String getLastCheckString(String fileName, OsmandApplication app, boolean lastTimeChecked) { + OsmandSettings settings = app.getSettings(); + + final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get(); + String lastUpdateString = formatShortDateTime(app, lastUpdate); + String description = app.getString(R.string.updated, lastUpdateString); + + if (lastTimeChecked) { + final long lastCheck = preferenceLastCheck(fileName, settings).get(); + String lastCheckString = formatShortDateTime(app, lastCheck); + if (!lastUpdateString.equals(app.getString(R.string.shared_string_never))) { + description = description.concat("\n" + app.getString(R.string.last_time_checked, lastCheckString)); + } + } + return description; + } + @Override - public void onDestroyView() { - super.onDestroyView(); - if (loadLocalIndexesTask != null) { - loadLocalIndexesTask.cancel(true); + public void processFinish() { + adapter.notifyDataSetChanged(); + } + + @Override + public List getMapsToUpdate() { + return getMapsToUpdate(adapter.mapsList, settings); + } + + @Override + public boolean onUpdateLocalIndex(String fileName, boolean newValue, final Runnable callback) { + int frequencyId = preferenceUpdateFrequency(fileName, settings).get(); + int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(fileName, settings).get(); + final AlarmManager alarmManager = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); + final PendingIntent alarmIntent = getPendingIntent(app, fileName); + + final CommonPreference liveUpdatePreference = preferenceForLocalIndex(fileName, settings); + liveUpdatePreference.set(newValue); + if (settings.IS_LIVE_UPDATES_ON.get() && liveUpdatePreference.get()) { + runLiveUpdate(getActivity(), fileName, true, callback); + UpdateFrequency updateFrequency = UpdateFrequency.values()[frequencyId]; + TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDateToUpdateId]; + setAlarmForPendingIntent(alarmIntent, alarmManager, updateFrequency, timeOfDayToUpdate); + } else { + alarmManager.cancel(alarmIntent); + runSort(); + } + return true; + } + + @Override + public void forceUpdateLocal(String fileName, boolean userRequested, final Runnable callback) { + if (settings.IS_LIVE_UPDATES_ON.get()) { + runLiveUpdate(getActivity(), fileName, userRequested, callback); } } - public void notifyLiveUpdatesChanged() { - if (getActivity() != null && adapter != null) { - adapter.notifyLiveUpdatesChanged(); + @Override + public void runSort() { + if (adapter != null) { + adapter.onDataUpdated(); } } - private boolean isDonationSupported() { - InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper(); - if (purchaseHelper != null) { - InAppSubscription monthlyPurchased = purchaseHelper.getPurchasedMonthlyLiveUpdates(); - return monthlyPurchased != null && monthlyPurchased.isDonationSupported(); + @Override + public void updateList() { + if (adapter != null) { + adapter.notifyDataSetChanged(); } - return false; - } - - private void showDonationSettings() { - SubscriptionFragment subscriptionFragment = new SubscriptionFragment(); - subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG); } public static String getSupportRegionName(OsmandApplication app, InAppPurchaseHelper purchaseHelper) { @@ -313,438 +727,8 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc app.getString(R.string.osm_live_support_region); } - protected class LocalIndexesAdapter extends OsmandBaseExpandableListAdapter { - public static final int SHOULD_UPDATE_GROUP_POSITION = 0; - public static final int SHOULD_NOT_UPDATE_GROUP_POSITION = 1; - final ArrayList dataShouldUpdate = new ArrayList<>(); - final ArrayList dataShouldNotUpdate = new ArrayList<>(); - final LiveUpdatesFragment fragment; - final Context ctx; - - public LocalIndexesAdapter(LiveUpdatesFragment fragment) { - this.fragment = fragment; - ctx = fragment.getActivity(); - } - - public void add(LocalIndexInfo info) { - CommonPreference preference = preferenceLiveUpdatesOn( - info.getFileName(), app.getSettings()); - if (preference.get()) { - dataShouldUpdate.add(info); - } else { - dataShouldNotUpdate.add(info); - } - } - - public void notifyLiveUpdatesChanged() { - Set changedSet = new HashSet<>(); - for (LocalIndexInfo localIndexInfo : dataShouldUpdate) { - CommonPreference preference = - preferenceLiveUpdatesOn(localIndexInfo.getFileName(), getSettings()); - if (!preference.get()) { - changedSet.add(localIndexInfo); - } - } - dataShouldUpdate.removeAll(changedSet); - dataShouldNotUpdate.addAll(changedSet); - changedSet.clear(); - for (LocalIndexInfo localIndexInfo : dataShouldNotUpdate) { - CommonPreference preference = - preferenceLiveUpdatesOn(localIndexInfo.getFileName(), getSettings()); - if (preference.get()) { - changedSet.add(localIndexInfo); - } - } - dataShouldUpdate.addAll(changedSet); - dataShouldNotUpdate.removeAll(changedSet); - notifyDataSetChanged(); - expandAllGroups(); - } - - public void sort() { - Collections.sort(dataShouldUpdate, LOCAL_INDEX_INFO_COMPARATOR); - Collections.sort(dataShouldNotUpdate, LOCAL_INDEX_INFO_COMPARATOR); - } - - @Override - public LocalIndexInfo getChild(int groupPosition, int childPosition) { - if (groupPosition == 0) { - return dataShouldUpdate.get(childPosition); - } else if (groupPosition == 1) { - return dataShouldNotUpdate.get(childPosition); - } else { - throw new IllegalArgumentException("unexpected group position:" + groupPosition); - } - } - - @Override - public long getChildId(int groupPosition, int childPosition) { - // it would be unusable to have 10000 local indexes - return groupPosition * 10000 + childPosition; - } - - @Override - public View getChildView(final int groupPosition, final int childPosition, - boolean isLastChild, View convertView, ViewGroup parent) { - LocalFullMapsViewHolder viewHolder; - if (convertView == null) { - LayoutInflater inflater = LayoutInflater.from(ctx); - convertView = inflater.inflate(R.layout.local_index_live_updates_list_item, parent, false); - viewHolder = new LocalFullMapsViewHolder(convertView, fragment); - convertView.setTag(viewHolder); - } else { - viewHolder = (LocalFullMapsViewHolder) convertView.getTag(); - } - viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName(), isLastChild); - return convertView; - } - - @Override - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { - View view = convertView; - String group = getGroup(groupPosition); - if (view == null) { - LayoutInflater inflater = LayoutInflater.from(ctx); - view = inflater.inflate(R.layout.list_group_title_with_switch, parent, false); - } - TextView nameView = ((TextView) view.findViewById(R.id.title)); - nameView.setText(group); - - view.setOnClickListener(null); - - final SwitchCompat liveUpdatesSwitch = (SwitchCompat) view.findViewById(R.id.toggle_item); - View topShadowView = view.findViewById(R.id.bottomShadowView); - if (groupPosition == SHOULD_UPDATE_GROUP_POSITION) { - topShadowView.setVisibility(View.GONE); - liveUpdatesSwitch.setVisibility(View.VISIBLE); - OsmandApplication application = (OsmandApplication) ctx.getApplicationContext(); - final OsmandSettings settings = application.getSettings(); - liveUpdatesSwitch.setChecked(settings.IS_LIVE_UPDATES_ON.get()); - liveUpdatesSwitch.setEnabled(!processing); - liveUpdatesSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked) { - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - switchOnLiveUpdates(settings); - } else { - liveUpdatesSwitch.setChecked(false); - app.showToastMessage(getString(R.string.osm_live_ask_for_purchase)); - } - } else { - settings.IS_LIVE_UPDATES_ON.set(false); - enableLiveUpdates(false); - } - } - - - }); - } else { - topShadowView.setVisibility(View.VISIBLE); - liveUpdatesSwitch.setVisibility(View.GONE); - } - - View divider = view.findViewById(R.id.divider); - if (getChildrenCount(groupPosition) == 0) { - divider.setVisibility(View.GONE); - } else { - divider.setVisibility(View.VISIBLE); - } - return view; - } - - private void switchOnLiveUpdates(final OsmandSettings settings) { - settings.IS_LIVE_UPDATES_ON.set(true); - enableLiveUpdates(true); - showUpdateDialog(getActivity(), getSettings(), adapter.dataShouldUpdate, adapter.dataShouldUpdate.size(), null); - } - - private void enableLiveUpdates(boolean enable) { - AlarmManager alarmMgr = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE); - for (LocalIndexInfo li : dataShouldUpdate) { - String fileName = li.getFileName(); - PendingIntent alarmIntent = getPendingIntent(ctx, fileName); - if (enable) { - final CommonPreference updateFrequencyPreference = - preferenceUpdateFrequency(fileName, getSettings()); - final CommonPreference timeOfDayPreference = - preferenceTimeOfDayToUpdate(fileName, getSettings()); - UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; - setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); - } else { - alarmMgr.cancel(alarmIntent); - } - } - } - - @Override - public int getChildrenCount(int groupPosition) { - if (showSettingsOnly) { - return 0; - } else if (groupPosition == SHOULD_UPDATE_GROUP_POSITION) { - return dataShouldUpdate.size(); - } else if (groupPosition == SHOULD_NOT_UPDATE_GROUP_POSITION) { - return dataShouldNotUpdate.size(); - } else { - throw new IllegalArgumentException("unexpected group position:" + groupPosition); - } - } - - @Override - public String getGroup(int groupPosition) { - if (groupPosition == SHOULD_UPDATE_GROUP_POSITION) { - return getString(R.string.download_live_updates); - } else if (groupPosition == SHOULD_NOT_UPDATE_GROUP_POSITION) { - return getString(R.string.available_maps); - } else { - throw new IllegalArgumentException("unexpected group position:" + groupPosition); - } - } - - @Override - public int getGroupCount() { - if (showSettingsOnly) { - return 0; - } else { - return dataShouldNotUpdate.size() == 0 ? 1 : 2; - } - } - - @Override - public long getGroupId(int groupPosition) { - return groupPosition; - } - - @Override - public boolean hasStableIds() { - return false; - } - - @Override - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } - - - } - - private void expandAllGroups() { - for (int i = 0; i < adapter.getGroupCount(); i++) { - listView.expandGroup(i); - } - } - - private static class LocalFullMapsViewHolder { - private final ImageView icon; - private final TextView nameTextView; - private final TextView subheaderTextView; - private final TextView descriptionTextView; - private final ImageButton options; - private final LiveUpdatesFragment fragment; - private final int secondaryColor; - private final View divider; - - private LocalFullMapsViewHolder(View view, LiveUpdatesFragment context) { - icon = (ImageView) view.findViewById(R.id.icon); - nameTextView = (TextView) view.findViewById(R.id.nameTextView); - subheaderTextView = (TextView) view.findViewById(R.id.subheaderTextView); - descriptionTextView = (TextView) view.findViewById(R.id.descriptionTextView); - options = (ImageButton) view.findViewById(R.id.options); - this.fragment = context; - - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = context.getActivity().getTheme(); - theme.resolveAttribute(android.R.attr.textColorSecondary, typedValue, true); - secondaryColor = typedValue.data; - divider = view.findViewById(R.id.divider); - } - - public void bindLocalIndexInfo(@NonNull final String item, boolean isLastChild) { - OsmandApplication context = fragment.getMyActivity().getMyApplication(); - final CommonPreference shouldUpdatePreference = - preferenceLiveUpdatesOn(item, fragment.getSettings()); - IncrementalChangesManager changesManager = context.getResourceManager().getChangesManager(); - - nameTextView.setText(getNameToDisplay(item, context)); - if (shouldUpdatePreference.get()) { - final Integer frequencyId = preferenceUpdateFrequency(item, fragment.getSettings()).get(); - final Integer timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(item, fragment.getSettings()).get(); - final UpdateFrequency frequency = UpdateFrequency.values()[frequencyId]; - final TimeOfDay timeOfDay = TimeOfDay.values()[timeOfDateToUpdateId]; - subheaderTextView.setVisibility(View.VISIBLE); - String subheaderText = fragment.getString(frequency.getLocalizedId()); - if (frequency != UpdateFrequency.HOURLY) { - subheaderText += " • " + fragment.getString(timeOfDay.getLocalizedId()); - } - subheaderTextView.setText(subheaderText); - subheaderTextView.setTextColor(fragment.getActivity().getResources() - .getColor(R.color.osmand_orange)); - icon.setImageDrawable(fragment.getIcon(R.drawable.ic_map, R.color.osmand_orange)); - options.setImageDrawable(getSecondaryColorPaintedIcon(R.drawable.ic_overflow_menu_white)); - } else { - subheaderTextView.setVisibility(View.GONE); - icon.setImageDrawable(getSecondaryColorPaintedIcon(R.drawable.ic_map)); - options.setImageDrawable(getSecondaryColorPaintedIcon(R.drawable.ic_action_plus)); - } - - final String fileNameWithoutExtension = - Algorithms.getFileNameWithoutExtension(new File(item)); - final long timestamp = changesManager.getTimestamp(fileNameWithoutExtension); - final long lastCheck = preferenceLastCheck(item, fragment.getSettings()).get(); - CommonPreference liveUpdateOn = preferenceLiveUpdatesOn(item, fragment.getSettings()); - if (liveUpdateOn.get() && lastCheck != DEFAULT_LAST_CHECK) { - String lastCheckString = formatDateTime(fragment.getActivity(), lastCheck); - descriptionTextView.setText(context.getString(R.string.last_update, lastCheckString)); - } else { - String lastCheckString = formatDateTime(fragment.getActivity(), timestamp); - descriptionTextView.setText(context.getString(R.string.last_map_change, lastCheckString)); - } - - if (!fragment.isProcessing() && InAppPurchaseHelper.isSubscribedToLiveUpdates(context)) { - final View.OnClickListener clickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - final FragmentManager fragmentManager = fragment.getChildFragmentManager(); - LiveUpdatesSettingsDialogFragment.createInstance(item).show(fragmentManager, "settings"); - } - }; - options.setOnClickListener(clickListener); - options.setEnabled(true); - } else { - options.setEnabled(false); - } - - if (isLastChild) { - divider.setVisibility(View.GONE); - } else { - divider.setVisibility(View.VISIBLE); - } - } - - private Drawable getSecondaryColorPaintedIcon(@DrawableRes int drawable) { - return fragment.getMyActivity().getMyApplication().getUIUtilities() - .getPaintedIcon(drawable, secondaryColor); - } - } - - public static class LoadLocalIndexTask - extends AsyncTask> - implements AbstractLoadLocalIndexTask { - - //private List result; - private LocalIndexesAdapter adapter; - private LiveUpdatesFragment fragment; - private LocalIndexHelper helper; - - public LoadLocalIndexTask(LocalIndexesAdapter adapter, - LiveUpdatesFragment fragment) { - this.adapter = adapter; - this.fragment = fragment; - helper = new LocalIndexHelper(fragment.getMyActivity().getMyApplication()); - } - - @Override - protected List doInBackground(Void... params) { - return helper.getLocalFullMaps(this); - } - - @Override - public void loadFile(LocalIndexInfo... loaded) { - publishProgress(loaded); - } - - @Override - protected void onProgressUpdate(LocalIndexInfo... values) { - String fileNameL; - for (LocalIndexInfo localIndexInfo : values) { - fileNameL = localIndexInfo.getFileName().toLowerCase(); - if (localIndexInfo.getType() == LocalIndexHelper.LocalIndexType.MAP_DATA - && !fileNameL.contains("world") && !fileNameL.startsWith("depth_")) { - adapter.add(localIndexInfo); - } - } - adapter.notifyDataSetChanged(); - fragment.expandAllGroups(); - } - - @Override - protected void onPostExecute(List result) { - //this.result = result; - adapter.sort(); - adapter.notifyLiveUpdatesChanged(); - adapter.notifyDataSetInvalidated(); - } - } - - private void enableProgress() { - processing = true; - progressBar.setVisibility(View.VISIBLE); - updateSubscriptionHeader(); - adapter.notifyDataSetChanged(); - } - - private void disableProgress() { - processing = false; - progressBar.setVisibility(View.INVISIBLE); - updateSubscriptionHeader(); - adapter.notifyDataSetChanged(); - } - - @Override - public void onError(InAppPurchaseTaskType taskType, String error) { - disableProgress(); - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseErrorOnFragments(getChildFragmentManager(), taskType, error); - } - } - - @Override - public void onGetItems() { - if (!InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - app.getSettings().IS_LIVE_UPDATES_ON.set(false); - adapter.enableLiveUpdates(false); - } - disableProgress(); - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseGetItemsOnFragments(getChildFragmentManager()); - } - } - - @Override - public void onItemPurchased(String sku, boolean active) { - InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper(); - if (purchaseHelper != null && purchaseHelper.getLiveUpdates().containsSku(sku)) { - updateSubscriptionHeader(); - } - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseItemPurchasedOnFragments(getChildFragmentManager(), sku, active); - } - } - - @Override - public void showProgress(InAppPurchaseTaskType taskType) { - enableProgress(); - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseShowProgressOnFragments(getChildFragmentManager(), taskType); - } - } - - @Override - public void dismissProgress(InAppPurchaseTaskType taskType) { - disableProgress(); - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseDismissProgressOnFragments(getChildFragmentManager(), taskType); - } + @ColorRes + public static int getDefaultIconColorId(boolean nightMode) { + return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; } } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragmentNew.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragmentNew.java deleted file mode 100644 index 243362ea98..0000000000 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragmentNew.java +++ /dev/null @@ -1,706 +0,0 @@ -package net.osmand.plus.liveupdates; - -import android.app.Activity; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.graphics.Typeface; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; -import android.widget.ExpandableListView; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.ColorRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.content.res.AppCompatResources; -import androidx.appcompat.widget.AppCompatImageView; -import androidx.appcompat.widget.SwitchCompat; -import androidx.appcompat.widget.Toolbar; -import androidx.core.content.ContextCompat; -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import net.osmand.AndroidNetworkUtils; -import net.osmand.AndroidUtils; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; -import net.osmand.plus.UiUtilities; -import net.osmand.plus.UiUtilities.CompoundButtonType; -import net.osmand.plus.activities.LocalIndexInfo; -import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; -import net.osmand.plus.base.BaseOsmAndDialogFragment; -import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.helpers.FontCache; -import net.osmand.plus.inapp.InAppPurchaseHelper; -import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; -import net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.OnLiveUpdatesForLocalChange; -import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; -import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; -import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.widgets.TextViewEx; -import net.osmand.util.Algorithms; - -import org.apache.commons.logging.Log; - -import java.lang.ref.WeakReference; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; - -import static net.osmand.AndroidUtils.getSecondaryTextColorId; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatShortDateTime; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent; -import static net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.getTertiaryTextColorId; -import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getActiveTextColorId; -import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getOsmandIconColorId; -import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getSecondaryIconColorId; - -public class LiveUpdatesFragmentNew extends BaseOsmAndDialogFragment implements OnLiveUpdatesForLocalChange { - - public static final String URL = "https://osmand.net/api/osmlive_status"; - public static final String TAG = LiveUpdatesFragmentNew.class.getSimpleName(); - private final static Log LOG = PlatformUtil.getLog(LiveUpdatesFragmentNew.class); - private static final String SUBSCRIPTION_URL = "https://osmand.net/features/subscription"; - - private OsmandApplication app; - private OsmandSettings settings; - private boolean nightMode; - - private View toolbarSwitchContainer; - private ExpandableListView listView; - private TextViewEx descriptionTime; - private LiveMapsAdapter adapter; - - private GetLastUpdateDateTask getLastUpdateDateTask; - private LoadLiveMapsTask loadLiveMapsTask; - - private final LiveUpdateListener liveUpdateListener = new LiveUpdateListener() { - @Override - public void processFinish() { - adapter.notifyDataSetChanged(); - } - }; - - public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target) { - if (!fragmentManager.isStateSaved()) { - LiveUpdatesFragmentNew fragment = new LiveUpdatesFragmentNew(); - fragment.setTargetFragment(target, 0); - fragment.show(fragmentManager, TAG); - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - app = getMyApplication(); - settings = getSettings(); - nightMode = isNightMode(false); - setHasOptionsMenu(true); - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_live_updates, container, false); - - Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar); - toolbar.setTitle(R.string.osm_live); - int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; - Drawable icBack = app.getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(app), iconColorResId); - DrawableCompat.setTint(icBack, ContextCompat.getColor(app, iconColorResId)); - toolbar.setNavigationIcon(icBack); - toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - } - }); - ImageButton iconHelp = toolbar.findViewById(R.id.toolbar_action); - Drawable helpDrawable = app.getUIUtilities().getIcon(R.drawable.ic_action_help, iconColorResId); - iconHelp.setImageDrawable(helpDrawable); - iconHelp.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SUBSCRIPTION_URL)); - if (AndroidUtils.isIntentSafe(app, intent)) { - startActivity(intent); - } - } - }); - - listView = (ExpandableListView) view.findViewById(android.R.id.list); - adapter = new LiveMapsAdapter(); - listView.setAdapter(adapter); - expandAllGroups(); - - View bottomShadowView = inflater.inflate(R.layout.card_bottom_divider, listView, false); - listView.addFooterView(bottomShadowView); - listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { - @Override - public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app) && settings.IS_LIVE_UPDATES_ON.get()) { - if (getFragmentManager() != null) { - LiveUpdatesSettingsDialogFragmentNew - .showInstance(getFragmentManager(), LiveUpdatesFragmentNew.this, - adapter.getChild(groupPosition, childPosition).getFileName()); - } - return true; - } else { - return false; - } - } - }); - - final SwipeRefreshLayout swipeRefresh = view.findViewById(R.id.swipe_refresh); - int swipeColor = ContextCompat.getColor(app, nightMode ? R.color.osmand_orange_dark : R.color.osmand_orange); - swipeRefresh.setColorSchemeColors(swipeColor); - swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - if (settings.IS_LIVE_UPDATES_ON.get()) { - showUpdateDialog(getActivity(), settings, adapter.mapsList, adapter.countEnabled, liveUpdateListener); - startUpdateDateAsyncTask(); - } - swipeRefresh.setRefreshing(false); - } - }); - - toolbarSwitchContainer = view.findViewById(R.id.toolbar_switch_container); - updateToolbarSwitch(settings.IS_LIVE_UPDATES_ON.get()); - - View timeContainer = view.findViewById(R.id.item_import_container); - AndroidUtils.setListItemBackground(app, timeContainer, nightMode); - - AppCompatImageView descriptionIcon = timeContainer.findViewById(R.id.icon); - Drawable icon = UiUtilities.createTintedDrawable(app, R.drawable.ic_action_time, - ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light)); - descriptionIcon.setImageDrawable(icon); - - TextViewEx title = timeContainer.findViewById(R.id.title); - AndroidUtils.setTextSecondaryColor(app, title, nightMode); - title.setText(R.string.latest_openstreetmap_update); - title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_desc_text_size)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - title.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing)); - } - - descriptionTime = timeContainer.findViewById(R.id.sub_title); - AndroidUtils.setTextPrimaryColor(app, descriptionTime, nightMode); - Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium)); - descriptionTime.setTypeface(typeface); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - descriptionTime.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing)); - } - - return view; - } - - @Override - public void onResume() { - super.onResume(); - startUpdateDateAsyncTask(); - startLoadLiveMapsAsyncTask(); - } - - @Override - public void onPause() { - super.onPause(); - stopUpdateDateAsyncTask(); - stopLoadLiveMapsAsyncTask(); - } - - @Override - public void onDismiss(@NonNull DialogInterface dialog) { - super.onDismiss(dialog); - Fragment target = getTargetFragment(); - if (target instanceof RefreshLiveUpdates) { - ((RefreshLiveUpdates) target).onUpdateStates(app); - } - } - - private void startUpdateDateAsyncTask() { - getLastUpdateDateTask = new GetLastUpdateDateTask(this); - getLastUpdateDateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - private void stopUpdateDateAsyncTask() { - if (getLastUpdateDateTask != null) { - getLastUpdateDateTask.cancel(true); - } - } - - private void startLoadLiveMapsAsyncTask() { - if (loadLiveMapsTask == null) { - loadLiveMapsTask = new LoadLiveMapsTask(adapter, app); - loadLiveMapsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - } - - private void stopLoadLiveMapsAsyncTask() { - if (loadLiveMapsTask != null && loadLiveMapsTask.getStatus() == AsyncTask.Status.RUNNING) { - loadLiveMapsTask.cancel(false); - } - } - - private void updateToolbarSwitch(final boolean isChecked) { - int switchColor = ContextCompat.getColor(app, - isChecked ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode)); - AndroidUtils.setBackground(toolbarSwitchContainer, new ColorDrawable(switchColor)); - - SwitchCompat switchView = toolbarSwitchContainer.findViewById(R.id.switchWidget); - switchView.setChecked(isChecked); - UiUtilities.setupCompoundButton(switchView, nightMode, CompoundButtonType.TOOLBAR); - - toolbarSwitchContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - boolean visible = !isChecked; - if (visible) { - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - switchOnLiveUpdates(); - updateToolbarSwitch(true); - } else { - app.showToastMessage(getString(R.string.osm_live_ask_for_purchase)); - updateToolbarSwitch(false); - } - } else { - settings.IS_LIVE_UPDATES_ON.set(false); - enableLiveUpdates(false); - updateToolbarSwitch(false); - } - updateList(); - } - }); - - TextView title = toolbarSwitchContainer.findViewById(R.id.switchButtonText); - title.setText(isChecked ? R.string.shared_string_enabled : R.string.shared_string_disabled); - } - - private void switchOnLiveUpdates() { - settings.IS_LIVE_UPDATES_ON.set(true); - enableLiveUpdates(true); - showUpdateDialog(getMyActivity(), settings, adapter.mapsList, adapter.countEnabled, liveUpdateListener); - startUpdateDateAsyncTask(); - } - - public static void showUpdateDialog(final Activity context, final OsmandSettings settings, - final ArrayList mapsList, int countEnabled, - @Nullable final LiveUpdateListener listener) { - if (!Algorithms.isEmpty(mapsList)) { - if (countEnabled == 1) { - LocalIndexInfo li = mapsList.get(0); - runLiveUpdate(context, li.getFileName(), false, listener); - } else if (countEnabled > 1) { - AlertDialog.Builder bld = new AlertDialog.Builder(context); - bld.setMessage(R.string.update_all_maps_now); - bld.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - for (LocalIndexInfo li : mapsList) { - CommonPreference localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings); - if (localUpdateOn.get()) { - runLiveUpdate(context, li.getFileName(), false, listener); - } - } - } - }); - bld.setNegativeButton(R.string.shared_string_no, null); - bld.show(); - } - } - } - - private void enableLiveUpdates(boolean enable) { - if (!Algorithms.isEmpty(adapter.mapsList)) { - AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); - for (LocalIndexInfo li : adapter.mapsList) { - CommonPreference localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings); - if (localUpdateOn.get()) { - String fileName = li.getFileName(); - PendingIntent alarmIntent = getPendingIntent(app, fileName); - if (enable) { - final CommonPreference updateFrequencyPreference = - preferenceUpdateFrequency(fileName, settings); - final CommonPreference timeOfDayPreference = - preferenceTimeOfDayToUpdate(fileName, settings); - UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; - setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); - } else { - alarmMgr.cancel(alarmIntent); - } - } - } - } - } - - private void expandAllGroups() { - for (int i = 0; i < adapter.getGroupCount(); i++) { - listView.expandGroup(i); - } - } - - public static int updateCountEnabled(TextView countView, ArrayList mapsList, OsmandSettings settings) { - int countEnabled = 0; - if (countView != null) { - for (LocalIndexInfo map : mapsList) { - CommonPreference preference = preferenceForLocalIndex(map.getFileName(), settings); - if (preference.get()) { - countEnabled++; - } - } - String countText = countEnabled + "/" + mapsList.size(); - countView.setText(countText); - } - return countEnabled; - } - - protected class LiveMapsAdapter extends OsmandBaseExpandableListAdapter implements LocalIndexInfoAdapter { - private final ArrayList mapsList = new ArrayList<>(); - private int countEnabled = 0; - private TextViewEx countView; - - @Override - public void addData(LocalIndexInfo info) { - mapsList.add(info); - } - - @Override - public void clearData() { - mapsList.clear(); - } - - @Override - public void onDataUpdated() { - sort(); - countEnabled = updateCountEnabled(countView, mapsList, settings); - } - - public void sort() { - Collections.sort(mapsList); - Collections.sort(mapsList, new Comparator() { - @Override - public int compare(LocalIndexInfo o1, LocalIndexInfo o2) { - CommonPreference preference1 = preferenceForLocalIndex(o1.getFileName(), getSettings()); - CommonPreference preference2 = preferenceForLocalIndex(o2.getFileName(), getSettings()); - return preference2.get().compareTo(preference1.get()); - } - }); - notifyDataSetInvalidated(); - } - - @Override - public LocalIndexInfo getChild(int groupPosition, int childPosition) { - return mapsList.get(childPosition); - } - - @Override - public long getChildId(int groupPosition, int childPosition) { - return groupPosition * 10000 + childPosition; // it would be unusable to have 10000 local indexes - } - - @Override - public View getChildView(final int groupPosition, final int childPosition, - boolean isLastChild, View convertView, ViewGroup parent) { - LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); - convertView = inflater.inflate(R.layout.list_item_triple_row_icon_and_menu, parent, false); - LiveMapsViewHolder viewHolder = new LiveMapsViewHolder(convertView); - convertView.setTag(viewHolder); - viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName()); - return convertView; - } - - @Override - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { - View view = convertView; - if (view == null) { - LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); - view = inflater.inflate(R.layout.list_group_title_with_right_descr, parent, false); - } - view.setOnClickListener(null); - View topShadowView = view.findViewById(R.id.bottomShadowView); - if (groupPosition == 0) { - topShadowView.setVisibility(View.GONE); - } else { - topShadowView.setVisibility(View.VISIBLE); - } - - TextViewEx titleView = ((TextViewEx) view.findViewById(R.id.title)); - titleView.setText(getGroup(groupPosition)); - - countView = ((TextViewEx) view.findViewById(R.id.description)); - AndroidUtils.setTextSecondaryColor(app, countView, nightMode); - - return view; - } - - @Override - public int getChildrenCount(int groupPosition) { - return mapsList.size(); - } - - @Override - public String getGroup(int groupPosition) { - return getString(R.string.available_maps); - } - - @Override - public int getGroupCount() { - return 1; - } - - @Override - public long getGroupId(int groupPosition) { - return groupPosition; - } - - @Override - public boolean hasStableIds() { - return false; - } - - @Override - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } - } - - private class LiveMapsViewHolder { - private final ImageView statusIcon; - private final TextView title; - private final TextView subTitle; - private final TextView description; - private final CompoundButton option; - - private LiveMapsViewHolder(View view) { - statusIcon = (AppCompatImageView) view.findViewById(R.id.icon); - title = (TextView) view.findViewById(R.id.title); - subTitle = (TextView) view.findViewById(R.id.sub_title); - description = (TextView) view.findViewById(R.id.description); - option = (CompoundButton) view.findViewById(R.id.compound_button); - } - - public void bindLocalIndexInfo(@NonNull final String item) { - boolean liveUpdateOn = settings.IS_LIVE_UPDATES_ON.get(); - CommonPreference localUpdateOn = preferenceForLocalIndex(item, settings); -// IncrementalChangesManager changesManager = app.getResourceManager().getChangesManager(); - option.setChecked(localUpdateOn.get()); - if (!liveUpdateOn && localUpdateOn.get()) { - UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app, getTertiaryTextColorId(nightMode)), option); - } else { - UiUtilities.setupCompoundButton(option, nightMode, CompoundButtonType.GLOBAL); - } - - title.setText(getNameToDisplay(item, app)); - - AndroidUiHelper.updateVisibility(subTitle, localUpdateOn.get()); - if (localUpdateOn.get()) { - int frequencyId = preferenceUpdateFrequency(item, settings).get(); - final UpdateFrequency frequency = UpdateFrequency.values()[frequencyId]; - String subTitleText = getString(frequency.getLocalizedId()); - /*int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(item, settings).get(); - final TimeOfDay timeOfDay = TimeOfDay.values()[timeOfDateToUpdateId]; - if (frequency != UpdateFrequency.HOURLY) { - subTitleText += " • " + getString(timeOfDay.getLocalizedId()); - }*/ - subTitle.setText(subTitleText); - subTitle.setTextColor(ContextCompat.getColor(app, liveUpdateOn - ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode))); - Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium)); - subTitle.setTypeface(typeface); - } - - Drawable statusDrawable = AppCompatResources.getDrawable(app, R.drawable.ic_map); - int resColorId = !localUpdateOn.get() ? getSecondaryIconColorId(nightMode) : - !liveUpdateOn ? getDefaultIconColorId(nightMode) : getOsmandIconColorId(nightMode); - int statusColor = ContextCompat.getColor(app, resColorId); - if (statusDrawable != null) { - DrawableCompat.setTint(statusDrawable, statusColor); - } - statusIcon.setImageDrawable(statusDrawable); - - description.setText(getLastCheckString(item, app)); - - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - option.setEnabled(liveUpdateOn); - option.setOnCheckedChangeListener(new SwitchCompat.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - onUpdateLocalIndex(item, isChecked, null); - } - }); - } else { - option.setEnabled(false); - } - } - } - - public static class GetLastUpdateDateTask extends AsyncTask { - - private final OsmandApplication app; - private final WeakReference fragment; - - GetLastUpdateDateTask(LiveUpdatesFragmentNew fragment) { - this.fragment = new WeakReference<>(fragment); - app = fragment.getMyApplication(); - } - - @Override - protected String doInBackground(Void... params) { - try { - return AndroidNetworkUtils.sendRequest(app, URL, null, - "Requesting map updates info...", false, false); - } catch (Exception e) { - LOG.error("Error: " + "Requesting map updates info error", e); - return null; - } - } - - @Override - protected void onPostExecute(String response) { - LiveUpdatesFragmentNew f = fragment.get(); - if (response != null && f != null) { - TextViewEx descriptionTime = f.descriptionTime; - if (descriptionTime != null) { - SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); - source.setTimeZone(TimeZone.getTimeZone("UTC")); - SimpleDateFormat dest = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); - dest.setTimeZone(TimeZone.getDefault()); - try { - LOG.debug("response = " + response); - Date parsed = source.parse(response); - if (parsed != null) { - long dateTime = parsed.getTime(); - LOG.debug("dateTime = " + dateTime); - descriptionTime.setText(dest.format(parsed)); - } - } catch (ParseException e) { - LOG.error(e.getMessage()); - } - } - } - } - } - - protected static String getLastCheckString(String fileName, OsmandApplication app) { - return getLastCheckString(fileName, app, false); - } - - protected static String getLastCheckString(String fileName, OsmandApplication app, boolean lastTimeChecked) { - OsmandSettings settings = app.getSettings(); - - final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get(); - String lastUpdateString = formatShortDateTime(app, lastUpdate); - String description = app.getString(R.string.updated, lastUpdateString); - - if (lastTimeChecked) { - final long lastCheck = preferenceLastCheck(fileName, settings).get(); - String lastCheckString = formatShortDateTime(app, lastCheck); - if (!lastUpdateString.equals(app.getString(R.string.shared_string_never))) { - description = description.concat("\n" + app.getString(R.string.last_time_checked, lastCheckString)); - } - } - return description; - } - - @Override - public boolean onUpdateLocalIndex(String fileName, boolean newValue, final Runnable callback) { - - int frequencyId = preferenceUpdateFrequency(fileName, settings).get(); - int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(fileName, settings).get(); - final AlarmManager alarmManager = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); - final PendingIntent alarmIntent = getPendingIntent(app, fileName); - - final CommonPreference liveUpdatePreference = preferenceForLocalIndex(fileName, settings); - liveUpdatePreference.set(newValue); - if (settings.IS_LIVE_UPDATES_ON.get() && liveUpdatePreference.get()) { - runLiveUpdate(getActivity(), fileName, true, new LiveUpdateListener() { - @Override - public void processFinish() { - runSort(); - if (callback != null) { - callback.run(); - } - } - }); - UpdateFrequency updateFrequency = UpdateFrequency.values()[frequencyId]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDateToUpdateId]; - setAlarmForPendingIntent(alarmIntent, alarmManager, updateFrequency, timeOfDayToUpdate); - } else { - alarmManager.cancel(alarmIntent); - runSort(); - } - - return true; - } - - @Override - public void forceUpdateLocal(String fileName, boolean userRequested, final Runnable callback) { - if (settings.IS_LIVE_UPDATES_ON.get()) { - runLiveUpdate(getActivity(), fileName, userRequested, new LiveUpdateListener() { - @Override - public void processFinish() { - updateList(); - if (callback != null) { - callback.run(); - } - } - }); - } - } - - @Override - public void runSort() { - if (adapter != null) { - adapter.onDataUpdated(); - } - } - - @Override - public void updateList() { - if (adapter != null) { - adapter.notifyDataSetChanged(); - } - } - - @ColorRes - public static int getDefaultIconColorId(boolean nightMode) { - return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; - } - -} diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java index afcb313217..1833cd397c 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java @@ -9,9 +9,10 @@ import android.text.format.DateUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; +import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; @@ -20,6 +21,7 @@ import net.osmand.util.Algorithms; import java.io.File; import java.util.Calendar; +import java.util.List; import java.util.concurrent.TimeUnit; public class LiveUpdatesHelper { @@ -254,8 +256,27 @@ public class LiveUpdatesHelper { } } - public static void runLiveUpdate(Context context, final String fileName, boolean userRequested, @Nullable final LiveUpdateListener listener) { + public static void runLiveUpdate(Context context, final String fileName, boolean userRequested, @Nullable final Runnable runOnSuccess) { final String fnExt = Algorithms.getFileNameWithoutExtension(new File(fileName)); - new PerformLiveUpdateAsyncTask(context, fileName, userRequested, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fnExt); + PerformLiveUpdateAsyncTask task = new PerformLiveUpdateAsyncTask(context, fileName, userRequested); + task.setRunOnSuccess(runOnSuccess); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fnExt); + } + + public static void runLiveUpdate(Context context, boolean userRequested, final LiveUpdateListener listener) { + for (LocalIndexInfo mapToUpdate : listener.getMapsToUpdate()) { + runLiveUpdate(context, mapToUpdate.getFileName(), userRequested, new Runnable() { + @Override + public void run() { + listener.processFinish(); + } + }); + } + } + + public interface LiveUpdateListener { + void processFinish(); + + List getMapsToUpdate(); } } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragmentNew.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java similarity index 72% rename from OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragmentNew.java rename to OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java index 776368e6a7..a40d0e956c 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java @@ -36,7 +36,7 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.FontCache; -import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates; +import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; import net.osmand.plus.resources.IncrementalChangesManager; @@ -68,28 +68,30 @@ import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFreq import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.getCustomButtonView; import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.updateCustomButtonView; -public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogFragment implements RefreshLiveUpdates { +public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragment implements RefreshLiveUpdates { - public static final String TAG = LiveUpdatesSettingsDialogFragmentNew.class.getSimpleName(); - private static final Log LOG = PlatformUtil.getLog(LiveUpdatesSettingsDialogFragmentNew.class); + public static final String TAG = LiveUpdatesSettingsBottomSheet.class.getSimpleName(); + private static final Log LOG = PlatformUtil.getLog(LiveUpdatesSettingsBottomSheet.class); private static final String LOCAL_INDEX_FILE_NAME = "local_index_file_name"; private OsmandApplication app; private OsmandSettings settings; - private OnLiveUpdatesForLocalChange onLiveUpdatesForLocalChange; + + private BaseBottomSheetItem itemTitle; + private BaseBottomSheetItem itemLastCheck; + private BaseBottomSheetItem itemSwitchLiveUpdate; + private BaseBottomSheetItem itemFrequencyHelpMessage; + private BaseBottomSheetItem itemClear; + private BaseBottomSheetItem itemViaWiFi; private MultiStateToggleButton frequencyToggleButton; private MultiStateToggleButton timeOfDayToggleButton; private String fileName; - private int indexLastCheckItem = -1; - private int indexSwitchLiveUpdateItem = -1; - private int indexFrequencyHelpMessageItem = -1; - private int indexClearItem = -1; - private int indexViaWiFiItem = -1; + private OnLiveUpdatesForLocalChange onLiveUpdatesForLocalChange; public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, String fileName) { if (!fragmentManager.isStateSaved()) { - LiveUpdatesSettingsDialogFragmentNew fragment = new LiveUpdatesSettingsDialogFragmentNew(); + LiveUpdatesSettingsBottomSheet fragment = new LiveUpdatesSettingsBottomSheet(); fragment.setTargetFragment(target, 0); fragment.fileName = fileName; fragment.show(fragmentManager, TAG); @@ -111,31 +113,33 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF CommonPreference downloadViaWiFiPreference = preferenceDownloadViaWiFi(fileName, settings); CommonPreference frequencyPreference = preferenceUpdateFrequency(fileName, settings); CommonPreference timeOfDayPreference = preferenceTimeOfDayToUpdate(fileName, settings); + int dp4 = getDimen(R.dimen.list_item_button_padding); int dp12 = getDimen(R.dimen.content_padding_small); int dp16 = getDimen(R.dimen.content_padding); - int dp40 = getDimen(R.dimen.list_header_height); + int dp36 = getDimen(R.dimen.dialog_button_height); int dp48 = getDimen(R.dimen.context_menu_buttons_bottom_height); - items.add(new SimpleBottomSheetItem.Builder() + itemTitle = new SimpleBottomSheetItem.Builder() .setTitle(getNameToDisplay(fileName, app)) .setTitleColorId(getPrimaryTextColorId(nightMode)) .setLayoutId(R.layout.bottom_sheet_item_title_big) - .create()); + .create(); + items.add(itemTitle); - items.add(new ShortDescriptionItem.Builder() + itemLastCheck = new ShortDescriptionItem.Builder() .setDescription(getLastCheckString()) .setDescriptionColorId(getSecondaryTextColorId(nightMode)) .setDescriptionMaxLines(2) .setLayoutId(R.layout.bottom_sheet_item_description) - .create()); - indexLastCheckItem = items.size() - 1; + .create(); + items.add(itemLastCheck); View itemLiveUpdate = getCustomButtonView(app, null, localUpdatePreference.get(), nightMode); View itemLiveUpdateButton = itemLiveUpdate.findViewById(R.id.button_container); CompoundButton button = (CompoundButton) itemLiveUpdateButton.findViewById(R.id.compound_button); UiUtilities.setupCompoundButton(button, nightMode, TOOLBAR); itemLiveUpdateButton.setMinimumHeight(getDimen(R.dimen.bottom_sheet_selected_item_title_height)); - items.add(new BottomSheetItemWithCompoundButton.Builder() + itemSwitchLiveUpdate = new BottomSheetItemWithCompoundButton.Builder() .setChecked(localUpdatePreference.get()) .setTitle(getStateText(localUpdatePreference.get())) .setTitleColorId(getActiveTabTextColorId(nightMode)) @@ -143,45 +147,84 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (indexSwitchLiveUpdateItem != -1) { - BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexSwitchLiveUpdateItem); - button.setChecked(!button.isChecked()); - if (onLiveUpdatesForLocalChange != null - && onLiveUpdatesForLocalChange.onUpdateLocalIndex(fileName, button.isChecked(), new Runnable() { - @Override - public void run() { - updateLastCheck(); - updateFrequencyHelpMessage(); - updateFileSize(); + BottomSheetItemWithCompoundButton item = (BottomSheetItemWithCompoundButton) itemSwitchLiveUpdate; + boolean checked = item.isChecked(); + item.setChecked(!checked); + if (onLiveUpdatesForLocalChange != null + && onLiveUpdatesForLocalChange.onUpdateLocalIndex(fileName, !checked, new Runnable() { + @Override + public void run() { + updateLastCheck(); + updateFrequencyHelpMessage(); + updateFileSize(); + Fragment target = getTargetFragment(); + if (target instanceof LiveUpdatesFragment) { + ((LiveUpdatesFragment) target).runSort(); } - })) { - if (indexSwitchLiveUpdateItem != -1 && items.size() > 0) { - button.setTitle(getStateText(button.isChecked())); - updateCustomButtonView(app, null, button.getView(), button.isChecked(), nightMode); - } - CommonPreference localUpdatePreference = preferenceForLocalIndex(fileName, settings); - frequencyToggleButton.updateView(localUpdatePreference.get()); - timeOfDayToggleButton.updateView(localUpdatePreference.get()); - setStateViaWiFiButton(localUpdatePreference); } + })) { + item.setTitle(getStateText(!checked)); + updateCustomButtonView(app, null, item.getView(), !checked, nightMode); + CommonPreference localUpdatePreference = preferenceForLocalIndex(fileName, settings); + frequencyToggleButton.updateView(localUpdatePreference.get()); + timeOfDayToggleButton.updateView(localUpdatePreference.get()); + setStateViaWiFiButton(localUpdatePreference); } } }) + .create(); + items.add(itemSwitchLiveUpdate); + + Typeface typefaceRegular = FontCache.getRobotoRegular(app); + TextViewEx timeOfDayTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null); + timeOfDayTitle.setHeight(dp48); + timeOfDayTitle.setMinimumHeight(dp48); + timeOfDayTitle.setText(R.string.update_time); + timeOfDayTitle.setTypeface(typefaceRegular); + AndroidUtils.setPadding(timeOfDayTitle, timeOfDayTitle.getPaddingLeft(), dp4, timeOfDayTitle.getPaddingRight(), dp4); + AndroidUtils.setTextPrimaryColor(app, timeOfDayTitle, nightMode); + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(timeOfDayTitle) .create()); - indexSwitchLiveUpdateItem = items.size() - 1; + + LinearLayout itemTimeOfDayButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null); + LinearLayout.MarginLayoutParams itemTimeOfDayParams = new LinearLayout.MarginLayoutParams( + LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); + AndroidUtils.setMargins(itemTimeOfDayParams, dp16, 0, dp16, 0); + itemTimeOfDayButtons.setLayoutParams(itemTimeOfDayParams); + + String morning = getString(R.string.morning); + String night = getString(R.string.night); + RadioItem morningButton = new RadioItem(morning); + RadioItem nightButton = new RadioItem(night); + timeOfDayToggleButton = new MultiStateToggleButton(app, itemTimeOfDayButtons, nightMode); + timeOfDayToggleButton.setItems(morningButton, nightButton); + setSelectedRadioItem(timeOfDayToggleButton, timeOfDayPreference.get(), morningButton, nightButton); + timeOfDayToggleButton.updateView(localUpdatePreference.get()); + refreshTimeOfDayLayout(frequencyPreference.get(), itemTimeOfDayButtons, timeOfDayTitle); + + morningButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.MORNING)); + nightButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.NIGHT)); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(itemTimeOfDayButtons) + .create() + ); TextViewEx frequencyTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null); frequencyTitle.setHeight(dp48); frequencyTitle.setMinimumHeight(dp48); frequencyTitle.setText(R.string.update_frequency); - AndroidUtils.setPadding(frequencyTitle, frequencyTitle.getPaddingLeft(), 0, frequencyTitle.getPaddingRight(), 0); + frequencyTitle.setTypeface(typefaceRegular); + AndroidUtils.setPadding(frequencyTitle, frequencyTitle.getPaddingLeft(), dp4, frequencyTitle.getPaddingRight(), dp4); AndroidUtils.setTextPrimaryColor(app, frequencyTitle, nightMode); items.add(new BaseBottomSheetItem.Builder() .setCustomView(frequencyTitle) .create()); LinearLayout itemFrequencyButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null); - LinearLayout.MarginLayoutParams itemFrequencyParams = new LinearLayout.MarginLayoutParams(LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); + LinearLayout.MarginLayoutParams itemFrequencyParams = new LinearLayout.MarginLayoutParams( + LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); AndroidUtils.setMargins(itemFrequencyParams, dp16, 0, dp16, dp12); itemFrequencyButtons.setLayoutParams(itemFrequencyParams); @@ -200,58 +243,27 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF .setCustomView(itemFrequencyButtons) .create()); - TextViewEx timeOfDayTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null); - timeOfDayTitle.setHeight(dp40); - timeOfDayTitle.setMinimumHeight(dp40); - timeOfDayTitle.setText(R.string.update_time); - AndroidUtils.setPadding(timeOfDayTitle, timeOfDayTitle.getPaddingLeft(), 0, timeOfDayTitle.getPaddingRight(), 0); - AndroidUtils.setTextPrimaryColor(app, timeOfDayTitle, nightMode); - items.add(new BaseBottomSheetItem.Builder() - .setCustomView(timeOfDayTitle) - .create()); - - LinearLayout itemTimeOfDayButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null); - LinearLayout.MarginLayoutParams itemTimeOfDayParams = new LinearLayout.MarginLayoutParams(LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); - AndroidUtils.setMargins(itemTimeOfDayParams, dp16, 0, dp16, getDimen(R.dimen.context_menu_padding_margin_medium)); - itemTimeOfDayButtons.setLayoutParams(itemTimeOfDayParams); - - String morning = getString(R.string.morning); - String night = getString(R.string.night); - RadioItem morningButton = new RadioItem(morning); - RadioItem nightButton = new RadioItem(night); - timeOfDayToggleButton = new MultiStateToggleButton(app, itemTimeOfDayButtons, nightMode); - timeOfDayToggleButton.setItems(morningButton, nightButton); - setSelectedRadioItem(timeOfDayToggleButton, timeOfDayPreference.get(), morningButton, nightButton); - timeOfDayToggleButton.updateView(localUpdatePreference.get()); - refreshTimeOfDayLayout(frequencyPreference.get(), itemTimeOfDayButtons, timeOfDayTitle); - hourlyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.HOURLY, itemTimeOfDayButtons, timeOfDayTitle)); dailyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.DAILY, itemTimeOfDayButtons, timeOfDayTitle)); weeklyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.WEEKLY, itemTimeOfDayButtons, timeOfDayTitle)); - morningButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.MORNING)); - nightButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.NIGHT)); - items.add(new BaseBottomSheetItem.Builder() - .setCustomView(itemTimeOfDayButtons) - .create() - ); - - items.add(new ShortDescriptionItem.Builder() + itemFrequencyHelpMessage = new ShortDescriptionItem.Builder() .setDescription(getFrequencyHelpMessage()) .setDescriptionColorId(getSecondaryTextColorId(nightMode)) .setLayoutId(R.layout.bottom_sheet_item_description) - .create()); - indexFrequencyHelpMessageItem = items.size() - 1; + .create(); + items.add(itemFrequencyHelpMessage); - LinearLayout itemUpdateNowButton = (LinearLayout) inflater.inflate(R.layout.bottom_sheet_button_with_icon_center, null); + LinearLayout itemUpdateNowButton = + (LinearLayout) inflater.inflate(R.layout.bottom_sheet_button_with_icon_center, null); LinearLayout.MarginLayoutParams itemUpdateNowParams = new LinearLayout.MarginLayoutParams( - LinearLayout.MarginLayoutParams.MATCH_PARENT, getDimen(R.dimen.measurement_tool_button_height)); - AndroidUtils.setMargins(itemUpdateNowParams, dp12, dp12, dp16, dp12); + LinearLayout.MarginLayoutParams.MATCH_PARENT, dp36); + AndroidUtils.setMargins(itemUpdateNowParams, dp12, 0, dp16, dp12); itemUpdateNowButton.setLayoutParams(itemUpdateNowParams); ((AppCompatImageView) itemUpdateNowButton.findViewById(R.id.button_icon)).setImageDrawable( AppCompatResources.getDrawable(app, R.drawable.ic_action_update)); UiUtilities.setupDialogButton(nightMode, itemUpdateNowButton, UiUtilities.DialogButtonType.SECONDARY, getString(R.string.update_now)); - itemUpdateNowButton.setMinimumHeight(AndroidUtils.dpToPx(app, app.getResources().getDimension(R.dimen.dialog_button_height))); + itemUpdateNowButton.setMinimumHeight(AndroidUtils.dpToPx(app, dp36)); items.add(new BaseBottomSheetItem.Builder() .setCustomView(itemUpdateNowButton) @@ -268,6 +280,10 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF updateLastCheck(); updateFrequencyHelpMessage(); updateFileSize(); + Fragment target = getTargetFragment(); + if (target instanceof LiveUpdatesFragment) { + ((LiveUpdatesFragment) target).updateList(); + } } }); } @@ -281,51 +297,47 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF int iconDeleteColor = ContextCompat.getColor(app, R.color.color_osm_edit_delete); Drawable iconDelete = AppCompatResources.getDrawable(app, R.drawable.ic_action_delete_dark); - items.add( - new BottomSheetItemWithDescription.Builder() - .setDescription(getUpdatesSizeStr()) - .setIcon(UiUtilities.tintDrawable(iconDelete, iconDeleteColor)) - .setTitle(getString(R.string.updates_size)) - .setLayoutId(R.layout.bottom_sheet_item_with_descr_icon_right) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getUpdatesSize() > 0) { - if (getFragmentManager() != null) { - LiveUpdatesClearDialogFragment - .showInstance(getFragmentManager(), - LiveUpdatesSettingsDialogFragmentNew.this, fileName); - } - } + itemClear = new BottomSheetItemWithDescription.Builder() + .setDescription(getUpdatesSizeStr()) + .setIcon(UiUtilities.tintDrawable(iconDelete, iconDeleteColor)) + .setTitle(getString(R.string.updates_size)) + .setLayoutId(R.layout.bottom_sheet_item_with_descr_icon_right) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getUpdatesSize() > 0) { + if (getFragmentManager() != null) { + LiveUpdatesClearBottomSheet.showInstance(getFragmentManager(), + LiveUpdatesSettingsBottomSheet.this, fileName); } - }) - .create() - ); - indexClearItem = items.size() - 1; + } + } + }) + .create(); + items.add(itemClear); items.add(createDividerItem()); - items.add( - new BottomSheetItemWithCompoundButton.Builder() - .setChecked(downloadViaWiFiPreference.get()) - .setDescription(getStateText(downloadViaWiFiPreference.get())) - .setIconHidden(true) - .setTitle(getString(R.string.only_download_over_wifi)) - .setLayoutId(R.layout.bottom_sheet_item_with_descr_and_switch_56dp) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (preferenceForLocalIndex(fileName, settings).get() && indexViaWiFiItem != -1 && items.size() > 0) { - BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexViaWiFiItem); - button.setChecked(!button.isChecked()); - button.setDescription(getStateText(button.isChecked())); - preferenceDownloadViaWiFi(fileName, settings).set(button.isChecked()); - } - } - }) - .create() - ); - indexViaWiFiItem = items.size() - 1; + itemViaWiFi = new BottomSheetItemWithCompoundButton.Builder() + .setChecked(downloadViaWiFiPreference.get()) + .setDescription(getStateText(downloadViaWiFiPreference.get())) + .setIconHidden(true) + .setTitle(getString(R.string.only_download_over_wifi)) + .setLayoutId(R.layout.bottom_sheet_item_with_descr_and_switch_56dp) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (preferenceForLocalIndex(fileName, settings).get()) { + BottomSheetItemWithCompoundButton item = (BottomSheetItemWithCompoundButton) itemViaWiFi; + boolean checked = item.isChecked(); + item.setChecked(!checked); + item.setDescription(getStateText(!checked)); + preferenceDownloadViaWiFi(fileName, settings).set(!checked); + } + } + }) + .create(); + items.add(itemViaWiFi); items.add(new DividerSpaceItem(app, getDimen(R.dimen.context_menu_padding_margin_large))); } @@ -334,6 +346,24 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { View view = super.onCreateView(inflater, parent, savedInstanceState); + + int titleHeight = getDimen(R.dimen.bottom_sheet_descr_height); + TextViewEx titleView = (TextViewEx) itemTitle.getView(); + titleView.setMinimumHeight(titleHeight); + titleView.getLayoutParams().height = titleHeight; + titleView.setPadding(titleView.getPaddingLeft(), getDimen(R.dimen.content_padding_small), + titleView.getPaddingRight(), getDimen(R.dimen.list_item_button_padding)); + + int descriptionHeight = getDimen(R.dimen.bottom_sheet_title_height); + TextView descriptionView = (TextView) itemLastCheck.getView(); + descriptionView.setMinimumHeight(descriptionHeight); + descriptionView.getLayoutParams().height = descriptionHeight; + + int frequencyHelpMessageHeight = getDimen(R.dimen.context_menu_progress_min_height); + TextView frequencyHelpMessageView = (TextView) itemFrequencyHelpMessage.getView(); + frequencyHelpMessageView.setMinimumHeight(frequencyHelpMessageHeight); + frequencyHelpMessageView.getLayoutParams().height = frequencyHelpMessageHeight; + CommonPreference localUpdatePreference = preferenceForLocalIndex(fileName, settings); setStateViaWiFiButton(localUpdatePreference); return view; @@ -346,12 +376,12 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF } private void setStateViaWiFiButton(CommonPreference localUpdatePreference) { - if (indexViaWiFiItem != -1 && items.size() > 0) { - BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexViaWiFiItem); - if (button.getView() != null) { - TextView title = button.getView().findViewById(R.id.title); - TextView description = button.getView().findViewById(R.id.description); - CompoundButton compoundButton = button.getView().findViewById(R.id.compound_button); + if (itemViaWiFi != null) { + BottomSheetItemWithCompoundButton item = (BottomSheetItemWithCompoundButton) itemViaWiFi; + if (item.getView() != null) { + TextView title = item.getView().findViewById(R.id.title); + TextView description = item.getView().findViewById(R.id.description); + CompoundButton compoundButton = item.getView().findViewById(R.id.compound_button); if (localUpdatePreference.get()) { AndroidUtils.setTextPrimaryColor(app, title, nightMode); AndroidUtils.setTextSecondaryColor(app, description, nightMode); @@ -366,23 +396,20 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF } private void updateLastCheck() { - if (indexLastCheckItem != -1 && items.size() > 0) { - ((BottomSheetItemWithDescription) items.get(indexLastCheckItem)) - .setDescription(getLastCheckString()); + if (itemLastCheck != null) { + ((BottomSheetItemWithDescription) itemLastCheck).setDescription(getLastCheckString()); } } private void updateFrequencyHelpMessage() { - if (indexFrequencyHelpMessageItem != -1 && items.size() > 0) { - ((BottomSheetItemWithDescription) items.get(indexFrequencyHelpMessageItem)) - .setDescription(getFrequencyHelpMessage()); + if (itemFrequencyHelpMessage != null) { + ((BottomSheetItemWithDescription) itemFrequencyHelpMessage).setDescription(getFrequencyHelpMessage()); } } private void updateFileSize() { - if (indexClearItem != -1 && items.size() > 0) { - ((BottomSheetItemWithDescription) items.get(indexClearItem)) - .setDescription(getUpdatesSizeStr()); + if (itemClear != null) { + ((BottomSheetItemWithDescription) itemClear).setDescription(getUpdatesSizeStr()); } } @@ -414,7 +441,8 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF CommonPreference updateFrequency = preferenceUpdateFrequency(fileName, settings); CommonPreference timeOfDayToUpdate = preferenceTimeOfDayToUpdate(fileName, settings); final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get(); - return formatHelpDateTime(app, UpdateFrequency.values()[updateFrequency.get()], TimeOfDay.values()[timeOfDayToUpdate.get()], lastUpdate); + return formatHelpDateTime(app, UpdateFrequency.values()[updateFrequency.get()], + TimeOfDay.values()[timeOfDayToUpdate.get()], lastUpdate); } private long getUpdatesSize() { @@ -433,8 +461,8 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF private BaseBottomSheetItem createDividerItem() { DividerItem dividerItem = new DividerItem(app); - int start = app.getResources().getDimensionPixelSize(R.dimen.content_padding); - int vertical = getResources().getDimensionPixelSize(R.dimen.content_padding_small_half); + int start = getDimen(R.dimen.content_padding); + int vertical = getDimen(R.dimen.content_padding_small_half); dividerItem.setMargins(start, vertical, 0, vertical); return dividerItem; } @@ -459,7 +487,8 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF } } - private OnRadioItemClickListener getFrequencyButtonListener(@NonNull final UpdateFrequency type, final View... timeOfDayLayouts) { + private OnRadioItemClickListener getFrequencyButtonListener( + @NonNull final UpdateFrequency type, final View... timeOfDayLayouts) { return new OnRadioItemClickListener() { @Override public boolean onRadioItemClick(RadioItem radioItem, View view) { @@ -544,5 +573,4 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF protected int getDismissButtonTextId() { return R.string.shared_string_close; } - } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java deleted file mode 100644 index 242f44f83a..0000000000 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java +++ /dev/null @@ -1,288 +0,0 @@ -package net.osmand.plus.liveupdates; - -import android.app.AlarmManager; -import android.app.Dialog; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.Spinner; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.SwitchCompat; -import androidx.fragment.app.DialogFragment; - -import net.osmand.AndroidUtils; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.R; -import net.osmand.plus.download.AbstractDownloadActivity; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; -import net.osmand.plus.resources.IncrementalChangesManager; -import net.osmand.util.Algorithms; - -import org.apache.commons.logging.Log; - -import java.io.File; - -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.DEFAULT_LAST_CHECK; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatDateTime; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceDownloadViaWiFi; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLiveUpdatesOn; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent; - -public class LiveUpdatesSettingsDialogFragment extends DialogFragment { - private static final Log LOG = PlatformUtil.getLog(LiveUpdatesSettingsDialogFragment.class); - private static final String LOCAL_INDEX_FILE_NAME = "local_index_file_name"; - - private TextView sizeTextView; - - private String fileName; - private String fileNameWithoutExtension; - - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - fileName = getArguments().getString(LOCAL_INDEX_FILE_NAME); - assert fileName != null; - - View view = LayoutInflater.from(getActivity()) - .inflate(R.layout.dialog_live_updates_item_settings, null); - final TextView regionNameTextView = (TextView) view.findViewById(R.id.regionNameTextView); - final TextView lastMapChangeTextView = (TextView) view.findViewById(R.id.lastMapChangeTextView); - final TextView lastUpdateTextView = (TextView) view.findViewById(R.id.lastUpdateTextView); - final SwitchCompat liveUpdatesSwitch = (SwitchCompat) view.findViewById(R.id.toggle_item); - final CheckBox downloadOverWiFiCheckBox = (CheckBox) view.findViewById(R.id.downloadOverWiFiSwitch); - final Spinner updateFrequencySpinner = (Spinner) view.findViewById(R.id.updateFrequencySpinner); - final Spinner updateTimesOfDaySpinner = (Spinner) view.findViewById(R.id.updateTimesOfDaySpinner); - final View updateTimesOfDayLayout = view.findViewById(R.id.updateTimesOfDayLayout); - sizeTextView = (TextView) view.findViewById(R.id.sizeTextView); - - regionNameTextView.setText(getNameToDisplay(fileName, getMyActivity().getMyApplication())); - fileNameWithoutExtension = Algorithms.getFileNameWithoutExtension(new File(fileName)); - final IncrementalChangesManager changesManager = getMyApplication().getResourceManager().getChangesManager(); - final long timestamp = changesManager.getTimestamp(fileNameWithoutExtension); - String lastUpdateDate = formatDateTime(getActivity(), timestamp); - lastMapChangeTextView.setText(getString(R.string.last_map_change, lastUpdateDate)); - final long lastCheck = preferenceLastCheck(fileName, getSettings()).get(); - - - CommonPreference preference = preferenceLiveUpdatesOn(fileName, - getSettings()); - if (preference.get() && lastCheck != DEFAULT_LAST_CHECK) { - String lastCheckString = formatDateTime(getActivity(), lastCheck); - lastUpdateTextView.setText(getString(R.string.last_update, lastCheckString)); - } else { - lastUpdateTextView.setVisibility(View.GONE); - } - - final CommonPreference liveUpdatePreference = - preferenceForLocalIndex(fileName, getSettings()); - final CommonPreference downloadViaWiFiPreference = - preferenceDownloadViaWiFi(fileName, getSettings()); - final CommonPreference updateFrequencyPreference = - preferenceUpdateFrequency(fileName, getSettings()); - final CommonPreference timeOfDayPreference = - preferenceTimeOfDayToUpdate(fileName, getSettings()); - - downloadOverWiFiCheckBox.setChecked(!liveUpdatePreference.get() || downloadViaWiFiPreference.get()); - - sizeTextView.setText(getUpdatesSize(getMyActivity(), fileNameWithoutExtension, changesManager)); - - TimeOfDay[] timeOfDays = TimeOfDay.values(); - String[] timeOfDaysStrings = new String[timeOfDays.length]; - for (int i = 0; i < timeOfDays.length; i++) { - timeOfDaysStrings[i] = getString(timeOfDays[i].getLocalizedId()); - } - updateTimesOfDaySpinner.setAdapter(new ArrayAdapter<>(getActivity(), - R.layout.action_spinner_item, timeOfDaysStrings)); - updateTimesOfDaySpinner.setSelection(timeOfDayPreference.get()); - - UpdateFrequency[] updateFrequencies = UpdateFrequency.values(); - String[] updateFrequenciesStrings = new String[updateFrequencies.length]; - for (int i = 0; i < updateFrequencies.length; i++) { - updateFrequenciesStrings[i] = getString(updateFrequencies[i].getLocalizedId()); - } - - refreshTimeOfDayLayout(UpdateFrequency.values()[updateFrequencyPreference.get()], - updateTimesOfDayLayout); - updateFrequencySpinner.setAdapter(new ArrayAdapter<>(getActivity(), - R.layout.action_spinner_item, updateFrequenciesStrings)); - updateFrequencySpinner.setSelection(updateFrequencyPreference.get()); - updateFrequencySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - refreshTimeOfDayLayout(UpdateFrequency.values()[position], updateTimesOfDayLayout); - } - - @Override - public void onNothingSelected(AdapterView parent) { - - } - }); - - builder.setView(view) - .setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (liveUpdatePreference.get() != liveUpdatesSwitch.isChecked()) { - liveUpdatePreference.set(liveUpdatesSwitch.isChecked()); - if (!liveUpdatesSwitch.isChecked()) { - long updatesSize = changesManager.getUpdatesSize(fileNameWithoutExtension); - if (updatesSize != 0) { - ClearUpdatesDialogFragment.createInstance(fileName) - .show(getParentFragment().getChildFragmentManager(), null); - } - } - } - downloadViaWiFiPreference.set(downloadOverWiFiCheckBox.isChecked()); - - final int updateFrequencyInt = updateFrequencySpinner.getSelectedItemPosition(); - updateFrequencyPreference.set(updateFrequencyInt); - - AlarmManager alarmMgr = (AlarmManager) getActivity() - .getSystemService(Context.ALARM_SERVICE); - PendingIntent alarmIntent = getPendingIntent(getActivity(), fileName); - - final int timeOfDayInt = updateTimesOfDaySpinner.getSelectedItemPosition(); - timeOfDayPreference.set(timeOfDayInt); - - if (liveUpdatesSwitch.isChecked() && getSettings().IS_LIVE_UPDATES_ON.get()) { - runLiveUpdate(getActivity(), fileName, false, null); - UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyInt]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayInt]; - setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); - } else { - alarmMgr.cancel(alarmIntent); - } - getLiveUpdatesFragment().notifyLiveUpdatesChanged(); - } - }) - .setNegativeButton(R.string.shared_string_cancel, null) - .setNeutralButton(R.string.update_now, null); - return builder.create(); - } - - @Override - public void onResume() { - super.onResume(); - final AlertDialog dialog = (AlertDialog) getDialog(); - if (dialog != null) { - Button neutralButton = (Button) dialog.getButton(Dialog.BUTTON_NEUTRAL); - neutralButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (!getSettings().isInternetConnectionAvailable()) { - getMyApplication().showShortToastMessage(R.string.no_internet_connection); - } else { - runLiveUpdate(getActivity(), fileName, true, null); - final IncrementalChangesManager changesManager = getMyApplication().getResourceManager().getChangesManager(); - sizeTextView.setText(getUpdatesSize(getMyActivity(), fileNameWithoutExtension, changesManager)); - dialog.dismiss(); - } - } - }); - } - } - - private void refreshTimeOfDayLayout(UpdateFrequency updateFrequency, View updateTimesOfDayLayout) { - switch (updateFrequency) { - case HOURLY: - updateTimesOfDayLayout.setVisibility(View.GONE); - break; - case DAILY: - case WEEKLY: - updateTimesOfDayLayout.setVisibility(View.VISIBLE); - break; - } - } - - private static String getUpdatesSize(Context ctx, String fileNameWithoutExtension, - IncrementalChangesManager changesManager) { - long updatesSize = changesManager.getUpdatesSize(fileNameWithoutExtension); - return AndroidUtils.formatSize(ctx, updatesSize); - } - - private LiveUpdatesFragment getLiveUpdatesFragment() { - return (LiveUpdatesFragment) getParentFragment(); - } - - private OsmandSettings getSettings() { - return getMyApplication().getSettings(); - } - - private OsmandApplication getMyApplication() { - return getMyActivity().getMyApplication(); - } - - private AbstractDownloadActivity getMyActivity() { - return (AbstractDownloadActivity) this.getActivity(); - } - - public static LiveUpdatesSettingsDialogFragment createInstance(String fileName) { - LiveUpdatesSettingsDialogFragment fragment = new LiveUpdatesSettingsDialogFragment(); - Bundle args = new Bundle(); - args.putString(LOCAL_INDEX_FILE_NAME, fileName); - fragment.setArguments(args); - return fragment; - } - - public static class ClearUpdatesDialogFragment extends DialogFragment { - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final String localIndexInfo = getArguments().getString(LOCAL_INDEX_FILE_NAME); - assert localIndexInfo != null; - - final IncrementalChangesManager changesManager = - getMyApplication().getResourceManager().getChangesManager(); - final String fileNameWithoutExtension = - Algorithms.getFileNameWithoutExtension(new File(localIndexInfo)); - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage( - getString(R.string.ltr_or_rtl_combine_via_space, - getString(R.string.clear_updates_proposition_message), - getUpdatesSize(getContext(), fileNameWithoutExtension, changesManager))) - .setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - changesManager.deleteUpdates(fileNameWithoutExtension); - preferenceLastCheck(localIndexInfo, getMyApplication().getSettings()).resetToDefault(); - } - }) - .setNegativeButton(R.string.shared_string_cancel, null); - return builder.create(); - } - - private OsmandApplication getMyApplication() { - return (OsmandApplication) getActivity().getApplication(); - } - - public static ClearUpdatesDialogFragment createInstance(String fileName) { - ClearUpdatesDialogFragment fragment = new ClearUpdatesDialogFragment(); - Bundle args = new Bundle(); - args.putString(LOCAL_INDEX_FILE_NAME, fileName); - fragment.setArguments(args); - return fragment; - } - } -} diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java new file mode 100644 index 0000000000..a8adc5e9ce --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java @@ -0,0 +1,103 @@ +package net.osmand.plus.liveupdates; + +import android.os.Bundle; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +import net.osmand.PlatformUtil; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.LiveUpdateListener; +import net.osmand.plus.widgets.TextViewEx; + +import org.apache.commons.logging.Log; + +import static net.osmand.AndroidUtils.getPrimaryTextColorId; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; + +public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = LiveUpdatesUpdateAllBottomSheet.class.getSimpleName(); + private static final Log LOG = PlatformUtil.getLog(LiveUpdatesUpdateAllBottomSheet.class); + + private BaseBottomSheetItem itemTitle; + private BaseBottomSheetItem itemDescription; + + public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target) { + if (!fragmentManager.isStateSaved()) { + LiveUpdatesUpdateAllBottomSheet fragment = new LiveUpdatesUpdateAllBottomSheet(); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, TAG); + } + } + + @Override + public void createMenuItems(Bundle savedInstanceState) { + updateBottomButtons(); + + itemTitle = new SimpleBottomSheetItem.Builder() + .setTitle(getString(R.string.update_all_maps_now)) + .setTitleColorId(getPrimaryTextColorId(nightMode)) + .setLayoutId(R.layout.bottom_sheet_item_title) + .create(); + items.add(itemTitle); + + String osmAndLive = "\"" + getString(R.string.osm_live) + "\""; + itemDescription = new LongDescriptionItem.Builder() + .setDescription(getString(R.string.update_all_maps_added, osmAndLive)) + .setDescriptionMaxLines(5) + .setDescriptionColorId(getPrimaryTextColorId(nightMode)) + .setLayoutId(R.layout.bottom_sheet_item_description_long) + .create(); + items.add(itemDescription); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + View view = super.onCreateView(inflater, parent, savedInstanceState); + ((TextViewEx) itemTitle.getView()).setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_list_text_size)); + TextView textDescription = (TextView) itemDescription.getView(); + textDescription.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_list_text_size)); + textDescription.setMinHeight(getResources().getDimensionPixelSize(R.dimen.context_menu_sub_info_height)); + return view; + } + + private void updateAll() { + Fragment target = getTargetFragment(); + if (target instanceof LiveUpdateListener) { + runLiveUpdate(getActivity(), false, (LiveUpdateListener) target); + } + } + + @Override + protected void onRightBottomButtonClick() { + updateAll(); + dismiss(); + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + @Override + protected int getRightBottomButtonTextId() { + return R.string.update_now; + } + + @Override + protected DialogButtonType getRightBottomButtonType() { + return DialogButtonType.PRIMARY; + } +} diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java index d148e8c697..9729cd9b3a 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java @@ -6,7 +6,6 @@ import android.content.Context; import android.os.AsyncTask; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils.OnRequestResultListener; @@ -46,20 +45,18 @@ public class PerformLiveUpdateAsyncTask @NonNull private final String localIndexFileName; private final boolean userRequested; - private final LiveUpdateListener listener; - - public interface LiveUpdateListener { - void processFinish(); - } + private Runnable runOnSuccess; public PerformLiveUpdateAsyncTask(@NonNull Context context, @NonNull String localIndexFileName, - boolean userRequested, - @Nullable LiveUpdateListener listener) { + boolean userRequested) { this.context = context; this.localIndexFileName = localIndexFileName; this.userRequested = userRequested; - this.listener = listener; + } + + public void setRunOnSuccess(Runnable runOnSuccess) { + this.runOnSuccess = runOnSuccess; } @Override @@ -149,9 +146,6 @@ public class PerformLiveUpdateAsyncTask ((DownloadIndexesThread.DownloadEvents) context).downloadInProgress(); } updateLatestAvailability(application, localIndexFileName); - if (listener != null) { - listener.processFinish(); - } } else { LOG.debug("onPostExecute: Not enough space for updates"); } @@ -163,9 +157,6 @@ public class PerformLiveUpdateAsyncTask ((DownloadIndexesThread.DownloadEvents) context).downloadInProgress(); if (userRequested && context instanceof DownloadActivity) { updateLatestAvailability(application, localIndexFileName); - if (listener != null) { - listener.processFinish(); - } application.showShortToastMessage(R.string.no_updates_available); } } @@ -201,7 +192,7 @@ public class PerformLiveUpdateAsyncTask private void updateLatestAvailability(OsmandApplication app, @NonNull final String localIndexFileName) { final OsmandSettings settings = app.getSettings(); AndroidNetworkUtils.sendRequestAsync( - app, LiveUpdatesFragmentNew.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() { + app, LiveUpdatesFragment.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() { @Override public void onResult(String result) { if (!Algorithms.isEmpty(result)) { @@ -213,6 +204,9 @@ public class PerformLiveUpdateAsyncTask long dateTime = parsed.getTime(); preferenceLatestUpdateAvailable(settings).set(dateTime); preferenceLatestUpdateAvailable(localIndexFileName, settings).set(dateTime); + if (runOnSuccess != null) { + runOnSuccess.run(); + } } } catch (ParseException e) { long dateTime = preferenceLatestUpdateAvailable(settings).get(); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java index b73bf20c6e..ba8990f64f 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java @@ -228,12 +228,6 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In } String preferredCountry = obj.getString("preferredCountry"); app.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(preferredCountry); - - Fragment parent = getParentFragment(); - if (parent instanceof LiveUpdatesFragment) { - ((LiveUpdatesFragment) parent).updateSubscriptionHeader(); - } - dismiss(); } else { app.showToastMessage("Error: " + obj.getString("error")); diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java index 2f4ca39f84..858e32c962 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java @@ -33,7 +33,7 @@ import net.osmand.plus.settings.preferences.SwitchPreferenceEx; import org.apache.commons.logging.Log; -import static net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.getActivePrimaryColorId; +import static net.osmand.plus.liveupdates.LiveUpdatesSettingsBottomSheet.getActivePrimaryColorId; import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getSecondaryIconColorId; public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java index 3b5e537196..6b7ba26980 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java @@ -14,7 +14,6 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.liveupdates.CountrySelectionFragment; import net.osmand.plus.liveupdates.LiveUpdatesFragment; -import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; import net.osmand.plus.liveupdates.OsmLiveActivity; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.OsmandSettings; @@ -71,7 +70,7 @@ public class SubscriptionsCard extends BaseCard { liveUpdatesContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - LiveUpdatesFragmentNew.showInstance(mapActivity.getSupportFragmentManager(), target); + LiveUpdatesFragment.showInstance(mapActivity.getSupportFragmentManager(), target); } }); diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index f62ce6a82a..35ee1e08bb 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -44,7 +44,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; -import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.getDefaultIconColorId; +import static net.osmand.plus.liveupdates.LiveUpdatesFragment.getDefaultIconColorId; import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_SPEED; public class GpxBlockStatisticsBuilder {