From 6e31431be4dfceab05d6cb9f03ea8a8422f2deeb Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Thu, 2 Feb 2023 15:18:19 +0100 Subject: [PATCH] android: move opening hours to own fragment Signed-off-by: Arnaud Vergnet --- android/res/layout/place_page_details.xml | 6 +- ... => place_page_opening_hours_fragment.xml} | 1 - .../PlacePageOpeningHoursFragment.java | 193 ++++++++++++++++++ .../widget/placepage/PlacePageView.java | 161 +++------------ 4 files changed, 224 insertions(+), 137 deletions(-) rename android/res/layout/{place_page_opening_hours.xml => place_page_opening_hours_fragment.xml} (98%) create mode 100644 android/src/app/organicmaps/widget/placepage/PlacePageOpeningHoursFragment.java diff --git a/android/res/layout/place_page_details.xml b/android/res/layout/place_page_details.xml index 1bf81f6941..d50113d60e 100644 --- a/android/res/layout/place_page_details.xml +++ b/android/res/layout/place_page_details.xml @@ -29,7 +29,11 @@ - + diff --git a/android/res/layout/place_page_opening_hours.xml b/android/res/layout/place_page_opening_hours_fragment.xml similarity index 98% rename from android/res/layout/place_page_opening_hours.xml rename to android/res/layout/place_page_opening_hours_fragment.xml index 6410318397..a744f94979 100644 --- a/android/res/layout/place_page_opening_hours.xml +++ b/android/res/layout/place_page_opening_hours_fragment.xml @@ -3,7 +3,6 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/ll__place_schedule" style="@style/PlacePageItemFrame" android:tag="schedule"> diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageOpeningHoursFragment.java b/android/src/app/organicmaps/widget/placepage/PlacePageOpeningHoursFragment.java new file mode 100644 index 0000000000..dfd0891b38 --- /dev/null +++ b/android/src/app/organicmaps/widget/placepage/PlacePageOpeningHoursFragment.java @@ -0,0 +1,193 @@ +package app.organicmaps.widget.placepage; + +import android.content.res.Resources; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.RecyclerView; +import app.organicmaps.R; +import app.organicmaps.bookmarks.data.MapObject; +import app.organicmaps.bookmarks.data.Metadata; +import app.organicmaps.editor.OpeningHours; +import app.organicmaps.editor.data.TimeFormatUtils; +import app.organicmaps.editor.data.Timespan; +import app.organicmaps.editor.data.Timetable; +import app.organicmaps.util.ThemeUtils; +import app.organicmaps.util.UiUtils; +import app.organicmaps.util.Utils; + +import java.util.Calendar; +import java.util.Locale; + +public class PlacePageOpeningHoursFragment extends Fragment implements Observer +{ + private View mFrame; + private TextView mTodayLabel; + private TextView mTodayOpenTime; + private TextView mTodayNonBusinessTime; + private RecyclerView mFullWeekOpeningHours; + private PlaceOpeningHoursAdapter mOpeningHoursAdapter; + + private PlacePageViewModel viewModel; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + { + return inflater.inflate(R.layout.place_page_opening_hours_fragment, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) + { + super.onViewCreated(view, savedInstanceState); + mFrame = view; + mTodayLabel = view.findViewById(R.id.oh_today_label); + mTodayOpenTime = view.findViewById(R.id.oh_today_open_time); + mTodayNonBusinessTime = view.findViewById(R.id.oh_nonbusiness_time); + mFullWeekOpeningHours = view.findViewById(R.id.rw__full_opening_hours); + mOpeningHoursAdapter = new PlaceOpeningHoursAdapter(); + mFullWeekOpeningHours.setAdapter(mOpeningHoursAdapter); + + viewModel = new ViewModelProvider(requireActivity()).get(PlacePageViewModel.class); + viewModel.getMapObject().observe(requireActivity(), this); + } + + private void refreshTodayNonBusinessTime(Timespan[] closedTimespans) + { + final String hoursClosedLabel = getResources().getString(R.string.editor_hours_closed); + if (closedTimespans == null || closedTimespans.length == 0) + UiUtils.clearTextAndHide(mTodayNonBusinessTime); + else + UiUtils.setTextAndShow(mTodayNonBusinessTime, TimeFormatUtils.formatNonBusinessTime(closedTimespans, hoursClosedLabel)); + } + + private void refreshTodayOpeningHours(String label, String openTime, @ColorInt int color) + { + UiUtils.setTextAndShow(mTodayLabel, label); + UiUtils.setTextAndShow(mTodayOpenTime, openTime); + + mTodayLabel.setTextColor(color); + mTodayOpenTime.setTextColor(color); + } + + private void refreshTodayOpeningHours(String label, @ColorInt int color) + { + UiUtils.setTextAndShow(mTodayLabel, label); + UiUtils.hide(mTodayOpenTime); + + mTodayLabel.setTextColor(color); + mTodayOpenTime.setTextColor(color); + } + + private void refreshOpeningHours() + { + final String ohStr = viewModel.getMapObject() + .getValue() + .getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS); + final Timetable[] timetables = OpeningHours.nativeTimetablesFromString(ohStr); + mFrame.setOnLongClickListener((v) -> { + PlacePageUtils.copyToClipboard(requireContext(), mFrame, TimeFormatUtils.formatTimetables(getResources(), ohStr, timetables)); + return true; + }); + + final boolean isEmptyTT = (timetables == null || timetables.length == 0); + final int color = ThemeUtils.getColor(requireContext(), android.R.attr.textColorPrimary); + + if (isEmptyTT) + { + // 'opening_hours' tag wasn't parsed either because it's empty or wrong format. + if (!ohStr.isEmpty()) + { + UiUtils.show(mFrame); + refreshTodayOpeningHours(ohStr, color); + UiUtils.hide(mTodayNonBusinessTime); + UiUtils.hide(mFullWeekOpeningHours); + } + else + UiUtils.hide(mFrame); + } + else + { + UiUtils.show(mFrame); + final Resources resources = getResources(); + if (timetables[0].isFullWeek()) + { + final Timetable tt = timetables[0]; + if (tt.isFullday) + { + refreshTodayOpeningHours(resources.getString(R.string.twentyfour_seven), color); + UiUtils.clearTextAndHide(mTodayNonBusinessTime); + UiUtils.hide(mTodayNonBusinessTime); + } + else + { + refreshTodayOpeningHours(resources.getString(R.string.daily), tt.workingTimespan.toWideString(), color); + refreshTodayNonBusinessTime(tt.closedTimespans); + } + UiUtils.hide(mFullWeekOpeningHours); + } + else + { + // Show whole week time table. + int firstDayOfWeek = Calendar.getInstance(Locale.getDefault()).getFirstDayOfWeek(); + mOpeningHoursAdapter.setTimetables(timetables, firstDayOfWeek); + UiUtils.show(mFullWeekOpeningHours); + + // Show today's open time + non-business time. + boolean containsCurrentWeekday = false; + final int currentDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK); + for (Timetable tt : timetables) + { + if (tt.containsWeekday(currentDay)) + { + containsCurrentWeekday = true; + String openTime; + + if (tt.isFullday) + { + String allDay = resources.getString(R.string.editor_time_allday); + openTime = Utils.unCapitalize(allDay); + } + else + openTime = tt.workingTimespan.toWideString(); + + refreshTodayOpeningHours(resources.getString(R.string.today), openTime, color); + refreshTodayNonBusinessTime(tt.closedTimespans); + + break; + } + } + + // Show that place is closed today. + if (!containsCurrentWeekday) + { + refreshTodayOpeningHours(resources.getString(R.string.day_off_today), resources.getColor(R.color.base_red)); + UiUtils.hide(mTodayNonBusinessTime); + } + } + } + } + + @Override + public void onDestroy() + { + super.onDestroy(); + viewModel.getMapObject().removeObserver(this); + } + + @Override + public void onChanged(MapObject mapObject) + { + refreshOpeningHours(); + } +} diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageView.java b/android/src/app/organicmaps/widget/placepage/PlacePageView.java index 3839722c74..3158e25085 100644 --- a/android/src/app/organicmaps/widget/placepage/PlacePageView.java +++ b/android/src/app/organicmaps/widget/placepage/PlacePageView.java @@ -80,6 +80,7 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private static final String BOOKMARK_FRAGMENT_TAG = "BOOKMARK_FRAGMENT_TAG"; private static final String WIKIPEDIA_FRAGMENT_TAG = "WIKIPEDIA_FRAGMENT_TAG"; private static final String PHONE_FRAGMENT_TAG = "PHONE_FRAGMENT_TAG"; + private static final String OPENING_HOURS_FRAGMENT_TAG = "OPENING_HOURS_FRAGMENT_TAG"; private static final List visibleCoordsFormat = Arrays.asList(CoordinatesFormat.LatLonDMS, @@ -112,12 +113,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private TextView mTvVkPage; private View mLinePage; private TextView mTvLinePage; - private View mOpeningHours; - private TextView mTodayLabel; - private TextView mTodayOpenTime; - private TextView mTodayNonBusinessTime; - private RecyclerView mFullWeekOpeningHours; - private PlaceOpeningHoursAdapter mOpeningHoursAdapter; private View mWifi; private TextView mTvWiFi; private View mEmail; @@ -324,13 +319,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, LinearLayout latlon = mFrame.findViewById(R.id.ll__place_latlon); latlon.setOnClickListener(this); mTvLatlon = mFrame.findViewById(R.id.tv__place_latlon); - mOpeningHours = mFrame.findViewById(R.id.ll__place_schedule); - mTodayLabel = mFrame.findViewById(R.id.oh_today_label); - mTodayOpenTime = mFrame.findViewById(R.id.oh_today_open_time); - mTodayNonBusinessTime = mFrame.findViewById(R.id.oh_nonbusiness_time); - mFullWeekOpeningHours = mFrame.findViewById(R.id.rw__full_opening_hours); - mOpeningHoursAdapter = new PlaceOpeningHoursAdapter(); - mFullWeekOpeningHours.setAdapter(mOpeningHoursAdapter); mWifi = mFrame.findViewById(R.id.ll__place_wifi); mTvWiFi = mFrame.findViewById(R.id.tv__place_wifi); mEmail = mFrame.findViewById(R.id.ll__place_email); @@ -356,7 +344,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, address.setOnLongClickListener(this); mWebsite.setOnLongClickListener(this); mWikimedia.setOnLongClickListener(this); - mOpeningHours.setOnLongClickListener(this); mEmail.setOnLongClickListener(this); mOperator.setOnLongClickListener(this); mLevel.setOnLongClickListener(this); @@ -565,6 +552,30 @@ public class PlacePageView extends Fragment implements View.OnClickListener, updateButtons(showBackButton, showRoutingButton); } + private void updateOpeningHoursView() + { + final FragmentManager fManager = getChildFragmentManager(); + final PlacePageOpeningHoursFragment fragment = (PlacePageOpeningHoursFragment) fManager.findFragmentByTag(OPENING_HOURS_FRAGMENT_TAG); + final String ohStr = viewModel.getMapObject() + .getValue() + .getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS); + final Timetable[] timetables = OpeningHours.nativeTimetablesFromString(ohStr); + final boolean isEmptyTT = (timetables == null || timetables.length == 0); + + if (!isEmptyTT && fragment == null) + { + fManager.beginTransaction() + .add(R.id.place_page_opening_hours_fragment, PlacePageOpeningHoursFragment.class, null, OPENING_HOURS_FRAGMENT_TAG) + .commit(); + } + else if (isEmptyTT && fragment != null) + { + fManager.beginTransaction() + .remove(fragment) + .commit(); + } + } + private void updatePhoneView() { final FragmentManager fManager = getChildFragmentManager(); @@ -667,7 +678,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, refreshMetadataOrHide(Framework.nativeGetActiveObjectFormattedCuisine(), mCuisine, mTvCuisine); refreshWiFi(); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_FLATS), mEntrance, mTvEntrance); - refreshOpeningHours(); refreshSocialLinks(); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_LEVEL), mLevel, mTvLevel); @@ -686,105 +696,10 @@ public class PlacePageView extends Fragment implements View.OnClickListener, || UiUtils.isVisible(mAddOrganisation) || UiUtils.isVisible(mAddPlace), mEditTopSpace); } + updateOpeningHoursView(); updateWikipediaView(); } - private void refreshOpeningHours() - { - final String ohStr = mMapObject.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS); - final Timetable[] timetables = OpeningHours.nativeTimetablesFromString(ohStr); - final boolean isEmptyTT = (timetables == null || timetables.length == 0); - final int color = ThemeUtils.getColor(requireContext(), android.R.attr.textColorPrimary); - - if (isEmptyTT) - { - // 'opening_hours' tag wasn't parsed either because it's empty or wrong format. - if (!ohStr.isEmpty()) - { - UiUtils.show(mOpeningHours); - refreshTodayOpeningHours(ohStr, color); - UiUtils.hide(mTodayNonBusinessTime); - UiUtils.hide(mFullWeekOpeningHours); - } - else - { - UiUtils.hide(mOpeningHours); - } - return; - } - - UiUtils.show(mOpeningHours); - - final Resources resources = getResources(); - - if (timetables[0].isFullWeek()) - { - final Timetable tt = timetables[0]; - if (tt.isFullday) - { - refreshTodayOpeningHours(resources.getString(R.string.twentyfour_seven), color); - UiUtils.clearTextAndHide(mTodayNonBusinessTime); - UiUtils.hide(mTodayNonBusinessTime); - } - else - { - refreshTodayOpeningHours(resources.getString(R.string.daily), tt.workingTimespan.toWideString(), color); - refreshTodayNonBusinessTime(tt.closedTimespans); - } - - UiUtils.hide(mFullWeekOpeningHours); - return; - } - - // Show whole week time table. - int firstDayOfWeek = Calendar.getInstance(Locale.getDefault()).getFirstDayOfWeek(); - mOpeningHoursAdapter.setTimetables(timetables, firstDayOfWeek); - UiUtils.show(mFullWeekOpeningHours); - - // Show today's open time + non-business time. - boolean containsCurrentWeekday = false; - final int currentDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK); - for (Timetable tt : timetables) - { - if (tt.containsWeekday(currentDay)) - { - containsCurrentWeekday = true; - String openTime; - - if (tt.isFullday) - { - String allDay = resources.getString(R.string.editor_time_allday); - openTime = Utils.unCapitalize(allDay); - } - else - { - openTime = tt.workingTimespan.toWideString(); - } - - refreshTodayOpeningHours(resources.getString(R.string.today), openTime, color); - refreshTodayNonBusinessTime(tt.closedTimespans); - - break; - } - } - - // Show that place is closed today. - if (!containsCurrentWeekday) - { - refreshTodayOpeningHours(resources.getString(R.string.day_off_today), resources.getColor(R.color.base_red)); - UiUtils.hide(mTodayNonBusinessTime); - } - } - - private void refreshTodayNonBusinessTime(Timespan[] closedTimespans) - { - final String hoursClosedLabel = getResources().getString(R.string.editor_hours_closed); - if (closedTimespans == null || closedTimespans.length == 0) - UiUtils.clearTextAndHide(mTodayNonBusinessTime); - else - UiUtils.setTextAndShow(mTodayNonBusinessTime, TimeFormatUtils.formatNonBusinessTime(closedTimespans, hoursClosedLabel)); - } - private void refreshWiFi() { final String inet = mMapObject.getMetadata(Metadata.MetadataType.FMD_INTERNET); @@ -846,24 +761,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, } } - private void refreshTodayOpeningHours(String label, String openTime, @ColorInt int color) - { - UiUtils.setTextAndShow(mTodayLabel, label); - UiUtils.setTextAndShow(mTodayOpenTime, openTime); - - mTodayLabel.setTextColor(color); - mTodayOpenTime.setTextColor(color); - } - - private void refreshTodayOpeningHours(String label, @ColorInt int color) - { - UiUtils.setTextAndShow(mTodayLabel, label); - UiUtils.hide(mTodayOpenTime); - - mTodayLabel.setTextColor(color); - mTodayOpenTime.setTextColor(color); - } - private void updateBookmarkButton() { final List currentButtons = viewModel.getCurrentButtons() @@ -1133,12 +1030,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, } else if (id == R.id.ll__place_email) items.add(mTvEmail.getText().toString()); - else if (id == R.id.ll__place_schedule) - { - final String ohStr = mMapObject.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS); - final Timetable[] timetables = OpeningHours.nativeTimetablesFromString(ohStr); - items.add(TimeFormatUtils.formatTimetables(getResources(), ohStr, timetables)); - } else if (id == R.id.ll__place_operator) items.add(mTvOperator.getText().toString()); else if (id == R.id.ll__place_level)