[android] Add support for check_date & check_date:opening_hours

Signed-off-by: Harry Bond <me@hbond.xyz>
This commit is contained in:
Harry Bond
2025-08-23 22:44:42 +01:00
committed by x7z4w
parent ef9f4ceb1e
commit 08abddc7fc
7 changed files with 98 additions and 4 deletions

View File

@@ -106,7 +106,6 @@ public class PlacePageView extends Fragment
Arrays.asList(CoordinatesFormat.LatLonDMS, CoordinatesFormat.LatLonDecimal, CoordinatesFormat.OLCFull,
CoordinatesFormat.UTM, CoordinatesFormat.MGRS, CoordinatesFormat.OSMLink);
private View mFrame;
private Context mContext;
// Preview.
private ViewGroup mPreview;
@@ -144,6 +143,7 @@ public class PlacePageView extends Fragment
private MaterialTextView mTvOutdoorSeating;
private View mEntrance;
private MaterialTextView mTvEntrance;
private MaterialTextView mTvLastChecked;
private View mEditPlace;
private View mAddOrganisation;
private View mAddPlace;
@@ -308,6 +308,7 @@ public class PlacePageView extends Fragment
mTvCuisine = mFrame.findViewById(R.id.tv__place_cuisine);
mEntrance = mFrame.findViewById(R.id.ll__place_entrance);
mTvEntrance = mEntrance.findViewById(R.id.tv__place_entrance);
mTvLastChecked = mFrame.findViewById(R.id.place_page_last_checked);
mEditPlace = mFrame.findViewById(R.id.ll__place_editor);
mEditPlace.setOnClickListener(this);
mAddOrganisation = mFrame.findViewById(R.id.ll__add_organisation);
@@ -662,7 +663,14 @@ public class PlacePageView extends Fragment
refreshMetadataOrHide(outdoorSeating.equals("yes") ? getString(R.string.outdoor_seating) : "", mOutdoorSeating,
mTvOutdoorSeating);
// showTaxiOffer(mapObject);
final String lastChecked = mMapObject.getMetadata(Metadata.MetadataType.FMD_CHECK_DATE);
if (!lastChecked.isEmpty())
{
String periodSinceCheck = DateUtils.getRelativePeriodString(getResources(), lastChecked);
UiUtils.setTextAndShow(mTvLastChecked, requireContext().getString(R.string.existence_confirmed_time_ago, periodSinceCheck));
}
else
UiUtils.hide(mTvLastChecked);
if (RoutingController.get().isNavigating() || RoutingController.get().isPlanning())
{

View File

@@ -5,6 +5,7 @@ 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;
@@ -20,6 +21,8 @@ import app.organicmaps.sdk.bookmarks.data.Metadata;
import app.organicmaps.sdk.editor.OpeningHours;
import app.organicmaps.sdk.editor.data.Timespan;
import app.organicmaps.sdk.editor.data.Timetable;
import app.organicmaps.sdk.util.DateUtils;
import app.organicmaps.sdk.util.UiUtils;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
@@ -36,6 +39,7 @@ public class PlacePageOpeningHoursFragment extends Fragment implements Observer<
private MaterialTextView mTodayOpenTime;
private MaterialTextView mTodayNonBusinessTime;
private RecyclerView mFullWeekOpeningHours;
private MaterialTextView mLastCheckedDate;
private PlaceOpeningHoursAdapter mOpeningHoursAdapter;
private PlacePageViewModel mViewModel;
@@ -58,10 +62,23 @@ public class PlacePageOpeningHoursFragment extends Fragment implements Observer<
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);
mLastCheckedDate = view.findViewById(R.id.oh_check_date);
mOpeningHoursAdapter = new PlaceOpeningHoursAdapter();
mFullWeekOpeningHours.setAdapter(mOpeningHoursAdapter);
}
private static void setOrHideLastCheckedDate(MapObject mapObject, Resources resources, TextView checkDateView)
{
final String checkDate = mapObject.getMetadata(Metadata.MetadataType.FMD_CHECK_DATE_OPEN_HOURS);
if (!checkDate.isEmpty())
{
String periodSinceCheck = DateUtils.getRelativePeriodString(resources, checkDate);
UiUtils.setTextAndShow(checkDateView, resources.getString(R.string.hours_confirmed_time_ago, periodSinceCheck));
}
else
UiUtils.hide(checkDateView);
}
private void refreshTodayNonBusinessTime(Timespan[] closedTimespans)
{
final String hoursClosedLabel = getResources().getString(R.string.editor_hours_closed);
@@ -102,6 +119,9 @@ public class PlacePageOpeningHoursFragment extends Fragment implements Observer<
final boolean isEmptyTT = (timetables == null || timetables.length == 0);
final int color = ThemeUtils.getColor(requireContext(), android.R.attr.textColorPrimary);
final Resources resources = getResources();
setOrHideLastCheckedDate(mapObject, resources, mLastCheckedDate);
if (isEmptyTT)
{
@@ -119,7 +139,6 @@ public class PlacePageOpeningHoursFragment extends Fragment implements Observer<
else
{
UiUtils.show(mFrame);
final Resources resources = getResources();
if (timetables[0].isFullWeek())
{
final Timetable tt = timetables[0];

View File

@@ -74,6 +74,15 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/place_page_last_checked"
style="?fontCaption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/margin_half"
android:paddingHorizontal="@dimen/margin_base"
tools:text="Existence confirmed 1 month ago"/>
<include android:visibility="gone" layout="@layout/place_page_editor"/>
<include android:visibility="gone" layout="@layout/place_page_add_business"/>

View File

@@ -63,4 +63,17 @@
tools:listitem="@layout/place_page_opening_hours_item"
android:layout_marginTop="8dp"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/oh_check_date"
style="?fontCaption"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignStart="@id/oh_today_label"
android:layout_below="@id/rw__full_opening_hours"
android:textAppearance="@style/MwmTextAppearance.Body4"
android:textAlignment="viewStart"
android:visibility="gone"
tools:visibility="visible"
tools:text="Confirmed 2 months ago"/>
</RelativeLayout>

View File

@@ -466,6 +466,18 @@
<string name="opens_in">Opens in %s</string>
<string name="closes_in">Closes in %s</string>
<string name="closed">Closed</string>
<!-- Used in the opening_hours fragment for the last checked date, eg. "Confirmed two weeks ago" -->
<string name="hours_confirmed_time_ago">Confirmed %s</string>
<!-- Used on the place page for the last checked date, eg. "Existence confirmed two weeks ago" -->
<string name="existence_confirmed_time_ago">Existence confirmed %s</string>
<string name="yesterday">Yesterday</string>
<string name="days_ago">%s days ago</string>
<string name="week_ago">%s week ago</string>
<string name="weeks_ago">%s weeks ago</string>
<string name="month_ago">%s month ago</string>
<string name="months_ago">%s months ago</string>
<string name="year_ago">%s year ago</string>
<string name="years_ago">%s years ago</string>
<string name="edit_opening_hours">Edit business hours</string>
<string name="no_osm_account">Don\'t have an OpenStreetMap account?</string>
<string name="register_at_openstreetmap">Register at OpenStreetMap</string>

View File

@@ -68,7 +68,9 @@ public class Metadata implements Parcelable
FMD_NETWORK(49),
FMD_CONTACT_FEDIVERSE(50),
FMD_CONTACT_BLUESKY(51),
FMD_PANORAMAX(52);
FMD_PANORAMAX(52),
FMD_CHECK_DATE(53),
FMD_CHECK_DATE_OPEN_HOURS(54);
private final int mMetaType;
MetadataType(int metadataType)

View File

@@ -1,11 +1,17 @@
package app.organicmaps.sdk.util;
import android.content.Context;
import android.content.res.Resources;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import app.organicmaps.R;
public final class DateUtils
{
private DateUtils() {}
@@ -23,4 +29,29 @@ public final class DateUtils
{
return android.text.format.DateFormat.is24HourFormat(context);
}
/***
* @param dateString Date string in the yyyy-MM-dd format
* @return Human-readable string of the time that's passed since the date
*/
public static String getRelativePeriodString(Resources resources, String dateString)
{
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
int days = (int) (LocalDate.now().toEpochDay() - LocalDate.parse(dateString, formatter).toEpochDay());
if (days == 0)
return resources.getString(R.string.today);
if (days == 1)
return resources.getString(R.string.yesterday);
if (days < 7)
return resources.getString(R.string.days_ago, Integer.toString(days));
if (days < 30)
return resources.getString(days < 14 ? R.string.week_ago : R.string.weeks_ago, Integer.toString(days / 7));
if (days < 365)
return resources.getString(days < 60 ? R.string.month_ago : R.string.months_ago, Integer.toString(days / 30));
if (days > 365)
return resources.getString(days < 730 ? R.string.year_ago : R.string.years_ago, Integer.toString(days / 365));
else
return "";
}
}