Add OpenPlaceReviewsPlugin

This commit is contained in:
Vitaliy 2021-02-03 13:22:20 +02:00
parent 3fa52bf005
commit 43f326e320
12 changed files with 331 additions and 17 deletions

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:title="@string/open_place_reviews">
<Preference
android:key="opr_settings_info"
android:layout="@layout/preference_info"
android:persistent="false"
android:selectable="false"
android:title="@string/plugin_global_prefs_info" />
<Preference
android:key="opr_login_data"
android:layout="@layout/preference_with_descr"
android:persistent="false"
android:title="@string/login_open_place_reviews" />
<Preference
android:key="opr_logout"
android:layout="@layout/preference_login"
android:persistent="false"
android:title="@string/login_account" />
<net.osmand.plus.settings.preferences.SwitchPreferenceEx
android:key="opr_use_dev_url"
android:layout="@layout/preference_with_descr_dialog_and_switch"
android:title="@string/opr_use_dev_url"
tools:icon="@drawable/ic_plugin_developer" />
</PreferenceScreen>

View file

@ -28,7 +28,6 @@ import net.osmand.map.OsmandRegions.RegionTranslation;
import net.osmand.map.WorldRegion;
import net.osmand.osm.AbstractPoiType;
import net.osmand.osm.MapPoiTypes;
import net.osmand.plus.helpers.DayNightHelper;
import net.osmand.plus.activities.LocalIndexHelper;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.SavingTrackHelper;
@ -36,6 +35,7 @@ import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.DayNightHelper;
import net.osmand.plus.helpers.LockHelper;
import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.inapp.InAppPurchaseHelperImpl;
@ -45,6 +45,7 @@ import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.openplacereviews.OprAuthHelper;
import net.osmand.plus.osmedit.oauth.OsmOAuthHelper;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.quickaction.QuickActionRegistry;
@ -468,6 +469,7 @@ public class AppInitializer implements IProgress {
app.settingsHelper = startupInit(new SettingsHelper(app), SettingsHelper.class);
app.quickActionRegistry = startupInit(new QuickActionRegistry(app.getSettings()), QuickActionRegistry.class);
app.osmOAuthHelper = startupInit(new OsmOAuthHelper(app), OsmOAuthHelper.class);
app.oprAuthHelper = startupInit(new OprAuthHelper(app), OprAuthHelper.class);
app.onlineRoutingHelper = startupInit(new OnlineRoutingHelper(app), OnlineRoutingHelper.class);
initOpeningHoursParser();

View file

@ -68,6 +68,7 @@ import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.openplacereviews.OprAuthHelper;
import net.osmand.plus.osmedit.oauth.OsmOAuthHelper;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.quickaction.QuickActionRegistry;
@ -159,6 +160,7 @@ public class OsmandApplication extends MultiDexApplication {
GpxDbHelper gpxDbHelper;
QuickActionRegistry quickActionRegistry;
OsmOAuthHelper osmOAuthHelper;
OprAuthHelper oprAuthHelper;
MeasurementEditingContext measurementEditingContext;
OnlineRoutingHelper onlineRoutingHelper;
@ -394,6 +396,10 @@ public class OsmandApplication extends MultiDexApplication {
return osmOAuthHelper;
}
public OprAuthHelper getOprAuthHelper() {
return oprAuthHelper;
}
public synchronized DownloadIndexesThread getDownloadThread() {
if (downloadIndexesThread == null) {
downloadIndexesThread = new DownloadIndexesThread(this);

View file

@ -38,6 +38,7 @@ import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.mapillary.MapillaryPlugin;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.myplaces.FavoritesActivity;
import net.osmand.plus.openplacereviews.OpenPlaceReviewsPlugin;
import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin;
import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.parkingpoint.ParkingPositionPlugin;
@ -282,6 +283,7 @@ public abstract class OsmandPlugin {
checkMarketPlugin(app, enabledPlugins, new ParkingPositionPlugin(app));
allPlugins.add(new AccessibilityPlugin(app));
allPlugins.add(new OsmEditingPlugin(app));
allPlugins.add(new OpenPlaceReviewsPlugin(app));
allPlugins.add(new OsmandDevelopmentPlugin(app));
loadCustomPlugins(app);

View file

@ -22,6 +22,7 @@ import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapsource.EditMapSourceDialogFragment;
import net.osmand.plus.openplacereviews.OPRConstants;
import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener;
import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
@ -326,8 +327,8 @@ public class IntentHelper {
if (uri.toString().startsWith(OPRConstants.OPR_OAUTH_PREFIX)) {
String token = uri.getQueryParameter("opr-token");
String username = uri.getQueryParameter("opr-nickname");
app.getSettings().OPR_ACCESS_TOKEN.set(token);
app.getSettings().OPR_USERNAME.set(username);
app.getOprAuthHelper().addListener(getOprAuthorizationListener());
app.getOprAuthHelper().authorize(token, username);
mapActivity.setIntent(null);
return true;
}
@ -348,6 +349,19 @@ public class IntentHelper {
};
}
private OprAuthorizationListener getOprAuthorizationListener() {
return new OprAuthorizationListener() {
@Override
public void authorizationCompleted() {
for (Fragment fragment : mapActivity.getSupportFragmentManager().getFragments()) {
if (fragment instanceof OprAuthorizationListener) {
((OprAuthorizationListener) fragment).authorizationCompleted();
}
}
}
};
}
private boolean handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (!Algorithms.isEmpty(sharedText)) {

View file

@ -47,7 +47,6 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.Version;
import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.ActivityResultListener.OnActivityResultListener;
import net.osmand.plus.activities.MapActivity;
@ -61,6 +60,7 @@ import net.osmand.plus.mapcontextmenu.controllers.AmenityMenuController;
import net.osmand.plus.mapcontextmenu.controllers.TransportStopController;
import net.osmand.plus.openplacereviews.AddPhotosBottomSheetDialogFragment;
import net.osmand.plus.openplacereviews.OPRConstants;
import net.osmand.plus.openplacereviews.OpenPlaceReviewsPlugin;
import net.osmand.plus.openplacereviews.OprStartFragment;
import net.osmand.plus.osmedit.opr.OpenDBAPI;
import net.osmand.plus.poi.PoiFiltersHelper;
@ -133,7 +133,7 @@ public class MenuBuilder {
@Override
public void onPlaceIdAcquired(String[] placeId) {
MenuBuilder.this.placeId = placeId;
if (placeId.length < 2) {
if (placeId.length < 2 || OsmandPlugin.getEnabledPlugin(OpenPlaceReviewsPlugin.class) == null) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
@ -158,6 +158,16 @@ public class MenuBuilder {
}
};
public void addImageCard(ImageCard card) {
if (onlinePhotoCards.size() == 1 && onlinePhotoCards.get(0) instanceof NoImagesCard) {
onlinePhotoCards.clear();
}
onlinePhotoCards.add(0, card);
if (onlinePhotoCardsRow != null) {
onlinePhotoCardsRow.setCards(onlinePhotoCards);
}
}
public interface CollapseExpandListener {
void onCollapseExpand(boolean collapsed);
}
@ -443,8 +453,7 @@ public class MenuBuilder {
}
}
});
//TODO This feature is under development
if (!Version.isDeveloperVersion(app)) {
if (OsmandPlugin.getEnabledPlugin(OpenPlaceReviewsPlugin.class) == null) {
view.setVisibility(View.GONE);
}
photoButton = view;

View file

@ -22,6 +22,7 @@ import net.osmand.PlatformUtil;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity;
@ -29,6 +30,7 @@ import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapillary.MapillaryContributeCard;
import net.osmand.plus.mapillary.MapillaryImageCard;
import net.osmand.plus.openplacereviews.OPRConstants;
import net.osmand.plus.openplacereviews.OpenPlaceReviewsPlugin;
import net.osmand.plus.wikimedia.WikiImageHelper;
import net.osmand.util.Algorithms;
@ -198,7 +200,7 @@ public abstract class ImageCard extends AbstractCard {
return imageCard;
}
private static ImageCard createCardOpr(MapActivity mapActivity, JSONObject imageObject) {
public static ImageCard createCardOpr(MapActivity mapActivity, JSONObject imageObject) {
ImageCard imageCard = null;
if (imageObject.has("cid")) {
imageCard = new IPFSImageCard(mapActivity, imageObject);
@ -464,7 +466,7 @@ public abstract class ImageCard extends AbstractCard {
TrafficStats.setThreadStatsTag(GET_IMAGE_CARD_THREAD_ID);
List<ImageCard> result = new ArrayList<>();
Object o = mapActivity.getMapLayers().getContextMenuLayer().getSelectedObject();
if (o instanceof Amenity) {
if (o instanceof Amenity && OsmandPlugin.getEnabledPlugin(OpenPlaceReviewsPlugin.class) != null) {
Amenity am = (Amenity) o;
long amenityId = am.getId() >> 1;
String baseUrl = OPRConstants.getBaseUrl(app);

View file

@ -0,0 +1,57 @@
package net.osmand.plus.openplacereviews;
import android.graphics.drawable.Drawable;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
public class OpenPlaceReviewsPlugin extends OsmandPlugin {
private static final String ID = "osmand.openplacereviews";
public OpenPlaceReviewsPlugin(OsmandApplication app) {
super(app);
}
@Override
public String getId() {
return ID;
}
@Override
public String getName() {
return app.getString(R.string.open_place_reviews);
}
@Override
public CharSequence getDescription() {
return app.getString(R.string.open_place_reviews_plugin_description);
}
@Override
public SettingsScreenType getSettingsScreenType() {
return SettingsScreenType.OPEN_PLACE_REVIEWS;
}
@Override
public int getLogoResourceId() {
return R.drawable.ic_img_logo_openplacereview;
}
@Override
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.img_plugin_openplacereviews);
}
@Override
public void disable(OsmandApplication app) {
if (app.getSettings().OPR_USE_DEV_URL.get()) {
app.getSettings().OPR_USE_DEV_URL.set(false);
app.getOprAuthHelper().resetAuthorization();
}
super.disable(app);
}
}

View file

@ -0,0 +1,61 @@
package net.osmand.plus.openplacereviews;
import androidx.annotation.NonNull;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.osmedit.opr.OpenDBAPI;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms;
import java.util.HashSet;
import java.util.Set;
public class OprAuthHelper {
private final OsmandApplication app;
private final OsmandSettings settings;
private final OpenDBAPI openDBAPI = new OpenDBAPI();
private final Set<OprAuthorizationListener> listeners = new HashSet<>();
public OprAuthHelper(@NonNull OsmandApplication app) {
this.app = app;
settings = app.getSettings();
}
public void addListener(OprAuthorizationListener listener) {
listeners.add(listener);
}
public void removeListener(OprAuthorizationListener listener) {
listeners.remove(listener);
}
public void resetAuthorization() {
if (isLoginExists()) {
settings.OPR_USERNAME.resetToDefault();
settings.OPR_ACCESS_TOKEN.resetToDefault();
settings.OPR_BLOCKCHAIN_NAME.resetToDefault();
}
}
public boolean isLoginExists() {
return !Algorithms.isEmpty(settings.OPR_USERNAME.get())
&& !Algorithms.isEmpty(settings.OPR_BLOCKCHAIN_NAME.get())
&& !Algorithms.isEmpty(settings.OPR_ACCESS_TOKEN.get());
}
public void notifyAndRemoveListeners() {
for (OprAuthorizationListener listener : listeners) {
listener.authorizationCompleted();
}
listeners.clear();
}
public void authorize(final String token, final String username) {
}
public interface OprAuthorizationListener {
void authorizationCompleted();
}
}

View file

@ -0,0 +1,119 @@
package net.osmand.plus.openplacereviews;
import android.os.Bundle;
import androidx.activity.OnBackPressedCallback;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.OnPreferenceChanged;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
public class OprSettingsFragment extends BaseSettingsFragment implements OnPreferenceChanged, OprAuthorizationListener {
private static final String OPR_LOGOUT = "opr_logout";
public static final String OPR_LOGIN_DATA = "opr_login_data";
private OprAuthHelper authHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
authHelper = app.getOprAuthHelper();
FragmentActivity activity = requireMyActivity();
activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
public void handleOnBackPressed() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
mapActivity.launchPrevActivityIntent();
}
dismiss();
}
});
}
@Override
protected void setupPreferences() {
Preference oprSettingsInfo = findPreference("opr_settings_info");
oprSettingsInfo.setIconSpaceReserved(false);
setupLoginPref();
setupLogoutPref();
setupUseDevUrlPref();
}
private void setupLoginPref() {
Preference nameAndPasswordPref = findPreference(OPR_LOGIN_DATA);
nameAndPasswordPref.setVisible(!authHelper.isLoginExists());
nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_user_account));
}
private void setupLogoutPref() {
Preference nameAndPasswordPref = findPreference(OPR_LOGOUT);
nameAndPasswordPref.setVisible(authHelper.isLoginExists());
nameAndPasswordPref.setSummary(settings.OPR_USERNAME.get());
nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_user_account));
}
private void setupUseDevUrlPref() {
SwitchPreferenceEx useDevUrlPref = findPreference(settings.OPR_USE_DEV_URL.getId());
useDevUrlPref.setVisible(OsmandPlugin.isDevelopment());
useDevUrlPref.setIcon(getPersistentPrefIcon(R.drawable.ic_plugin_developer));
}
@Override
public boolean onPreferenceClick(Preference preference) {
String prefId = preference.getKey();
if (OPR_LOGIN_DATA.equals(prefId)) {
FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager != null) {
OprStartFragment.showInstance(fragmentManager);
return true;
}
} else if (OPR_LOGOUT.equals(prefId)) {
oprLogout();
return true;
}
return super.onPreferenceClick(preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String prefId = preference.getKey();
if (settings.OPR_USE_DEV_URL.getId().equals(prefId) && newValue instanceof Boolean) {
settings.OPR_USE_DEV_URL.set((Boolean) newValue);
oprLogout();
return true;
}
return super.onPreferenceChange(preference, newValue);
}
public void oprLogout() {
authHelper.resetAuthorization();
app.showShortToastMessage(R.string.osm_edit_logout_success);
updateAllSettings();
}
@Override
public void onPreferenceChanged(String prefId) {
if (settings.OPR_USE_DEV_URL.getId().equals(prefId)) {
oprLogout();
}
updateAllSettings();
}
@Override
public void authorizationCompleted() {
if (getContext() != null) {
updateAllSettings();
}
}
}

View file

@ -24,10 +24,11 @@ import net.osmand.PlatformUtil;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener;
import org.apache.commons.logging.Log;
public class OprStartFragment extends BaseOsmAndFragment {
public class OprStartFragment extends BaseOsmAndFragment implements OprAuthorizationListener {
private static final String TAG = OprStartFragment.class.getSimpleName();
private static final Log LOG = PlatformUtil.getLog(OprStartFragment.class);
private static final String openPlaceReviewsUrl = "OpenPlaceReviews.org";
@ -42,10 +43,7 @@ public class OprStartFragment extends BaseOsmAndFragment {
v.findViewById(R.id.back_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentActivity activity = getActivity();
if (activity != null) {
activity.getSupportFragmentManager().popBackStack();
}
dismiss();
}
});
UiUtilities.setupDialogButton(nightMode, createAccount, UiUtilities.DialogButtonType.PRIMARY,
@ -70,14 +68,14 @@ public class OprStartFragment extends BaseOsmAndFragment {
}
private void handleHaveAccount() {
String url = OPRConstants.getLoginUrl(requireContext());
String url = OPRConstants.getLoginUrl(requireMyApplication());
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(requireContext(), Uri.parse(url));
}
private void handleCreateAccount() {
String url = OPRConstants.getRegisterUrl(requireContext());
String url = OPRConstants.getRegisterUrl(requireMyApplication());
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(requireContext(), Uri.parse(url));
@ -114,6 +112,17 @@ public class OprStartFragment extends BaseOsmAndFragment {
}
}
@Override
public void authorizationCompleted() {
dismiss();
}
protected void dismiss() {
FragmentActivity activity = getActivity();
if (activity != null) {
activity.getSupportFragmentManager().popBackStack();
}
}
public static void showInstance(@NonNull FragmentManager fm) {
try {

View file

@ -61,6 +61,7 @@ import net.osmand.plus.activities.OsmandInAppPurchaseActivity;
import net.osmand.plus.audionotes.MultimediaNotesFragment;
import net.osmand.plus.development.DevelopmentSettingsFragment;
import net.osmand.plus.monitoring.MonitoringSettingsFragment;
import net.osmand.plus.openplacereviews.OprSettingsFragment;
import net.osmand.plus.osmedit.OsmEditingFragment;
import net.osmand.plus.profiles.SelectAppModesBottomSheetDialogFragment;
import net.osmand.plus.profiles.SelectAppModesBottomSheetDialogFragment.AppModeChangedListener;
@ -133,6 +134,7 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
MONITORING_SETTINGS(MonitoringSettingsFragment.class.getName(), true, ApplyQueryType.SNACK_BAR, R.xml.monitoring_settings, R.layout.profile_preference_toolbar),
LIVE_MONITORING(LiveMonitoringFragment.class.getName(), false, ApplyQueryType.SNACK_BAR, R.xml.live_monitoring, R.layout.global_preferences_toolbar_with_switch),
ACCESSIBILITY_SETTINGS(AccessibilitySettingsFragment.class.getName(), true, ApplyQueryType.SNACK_BAR, R.xml.accessibility_settings, R.layout.profile_preference_toolbar),
OPEN_PLACE_REVIEWS(OprSettingsFragment.class.getName(), false, null, R.xml.open_place_reviews, R.layout.global_preference_toolbar),
DEVELOPMENT_SETTINGS(DevelopmentSettingsFragment.class.getName(), false, null, R.xml.development_settings, R.layout.global_preference_toolbar);
public final String fragmentName;