19 Commits

Author SHA1 Message Date
61263c191e Rev up 2022-01-17 08:51:24 +01:00
b7f61846e3 Fixed drawable tinting bug in geofavs list 2022-01-17 08:19:00 +01:00
4aae6e90be Using pin icons in geofav list
Because circle conventionally is used for user with missing avatar
2022-01-16 13:39:01 +01:00
d5b6158364 Dark mode, styles fix 2022-01-16 10:32:00 +01:00
b9980206f5 WIP Dark theme 2022-01-15 12:29:17 +01:00
6336c4d61b Hidden edit button until the functionality is implemented 2022-01-15 10:56:25 +01:00
864802cdae Accuracy level indicator restyling 2022-01-15 10:01:51 +01:00
907fcb4cb1 issue 9: Button color for sorting uses app accent 2022-01-15 08:49:44 +01:00
d3a21c93c1 issue 8: Defined default accent to colorize elements like text cursor etc... 2022-01-14 08:53:54 +01:00
f57abf150a issue 10: fix mixed names (geofavorite/geobookmark) 2022-01-14 08:43:46 +01:00
a40b64baca Flow fix 2022-01-14 08:39:34 +01:00
15c11a33ee WIP Intent for geobookmark creation 2022-01-12 09:00:05 +01:00
d888485fc2 Fixed coordinates mapping on map picker 2022-01-12 08:24:26 +01:00
d009237679 WIP coordinates parsing
Not working ATM
2022-01-11 08:54:19 +01:00
c3e2496596 WIP adding map picker 2022-01-10 20:02:16 +01:00
607bbd0c2b Italian locale 2022-01-10 07:38:17 +01:00
90c4b998e7 Created empty map pick activity, added FAB actions 2022-01-06 08:26:38 +01:00
8f054dd324 Merge branch 'master' of ssh://ichibi.eu:222/home/git/nextcloud-maps-client 2021-11-22 08:55:42 +01:00
83b3b8a48d Set OSMDroid UserAgent 2021-11-22 08:55:35 +01:00
55 changed files with 893 additions and 123 deletions

2
.idea/compiler.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
<bytecodeTargetLevel target="11" />
</component>
</project>

8
.idea/misc.xml generated
View File

@ -5,20 +5,26 @@
<map>
<entry key="../../../../layout/custom_preview.xml" value="0.5661458333333333" />
<entry key="app/src/main/res/drawable/category_listitem_background.xml" value="0.35104166666666664" />
<entry key="app/src/main/res/drawable/coordinates_label_background.xml" value="0.3614583333333333" />
<entry key="app/src/main/res/drawable/floating_semitransparent_button_background.xml" value="0.512962962962963" />
<entry key="app/src/main/res/drawable/ic_list_pin.xml" value="0.3614583333333333" />
<entry key="app/src/main/res/drawable/ic_map_pin.xml" value="0.6425925925925926" />
<entry key="app/src/main/res/drawable/ic_more.xml" value="0.6166666666666667" />
<entry key="app/src/main/res/drawable/ic_nav.xml" value="0.6083333333333333" />
<entry key="app/src/main/res/drawable/ic_share.xml" value="0.8828125" />
<entry key="app/src/main/res/drawable/round_button_background.xml" value="0.3614583333333333" />
<entry key="app/src/main/res/layout/activity_geofavorite_detail.xml" value="0.4" />
<entry key="app/src/main/res/layout/activity_list_view.xml" value="0.4" />
<entry key="app/src/main/res/layout/activity_login.xml" value="0.2630208333333333" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.5307291666666667" />
<entry key="app/src/main/res/layout/activity_map_picker.xml" value="0.33016304347826086" />
<entry key="app/src/main/res/layout/item_geofav.xml" value="0.5307291666666667" />
<entry key="app/src/main/res/layout/item_navigation.xml" value="0.8" />
<entry key="app/src/main/res/layout/sorting_order_fragment.xml" value="0.4740740740740741" />
<entry key="app/src/main/res/menu/list_context_menu.xml" value="0.41944444444444445" />
</map>
</option>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="11" project-jdk-type="JavaSDK" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" />
</project>

View File

@ -8,8 +8,9 @@
(Always prefer [F-Droid](https://f-droid.org) build, when possible).
Android app to show your Nextcloud Maps geobookmarks list. Geobookmarks can be opened in all apps supporting geo links (i.e. Google Maps, Organic Maps etc...).
A new geobookmark can be created on current location.
UNOFFICIAL and FOSS Nextcloud Maps client at its earliest stages of developement. Shows your Nextcloud Maps geobookmarks list.
Geobookmarks can be opened in all apps supporting geo links (i.e. Google Maps, Organic Maps etc...).
A new geofavorite can be created on current location, by sharing a "geo:" uri from another app or manually picking from the map.
**Requires Maps app to be installed on the Nextcloud instance.**

View File

@ -24,8 +24,8 @@ android {
applicationId "it.danieleverducci.nextcloudmaps"
minSdkVersion 23
targetSdkVersion 30
versionCode 5
versionName "0.3.3"
versionCode 6
versionName "0.3.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -10,8 +10,8 @@
{
"type": "SINGLE",
"filters": [],
"versionCode": 3,
"versionName": "0.3.1",
"versionCode": 6,
"versionName": "0.3.4",
"outputFile": "app-release.apk"
}
]

View File

@ -49,8 +49,7 @@
</activity>
<activity
android:name=".activity.detail.GeofavoriteDetailActivity"
android:theme="@style/AppTheme">
android:name=".activity.detail.GeofavoriteDetailActivity">
<!-- standard "geo" scheme -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
@ -60,6 +59,40 @@
<data android:scheme="geo"/>
</intent-filter>
<!-- Google Maps -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="google.navigation"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="maps.google.com"
android:scheme="https"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="maps.google.com"
android:scheme="http"/>
</intent-filter>
</activity>
<activity android:name=".activity.mappicker.MapPickerActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<activity

View File

@ -0,0 +1,26 @@
package it.danieleverducci.nextcloudmaps.activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import org.osmdroid.views.overlay.TilesOverlay;
public class NextcloudMapsStyledActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// For whatever reason, android:windowLightStatusBar is ignored in styles.xml
int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
if (currentNightMode == Configuration.UI_MODE_NIGHT_YES)
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}

View File

@ -30,8 +30,9 @@ import androidx.appcompat.widget.Toolbar;
import it.danieleverducci.nextcloudmaps.BuildConfig;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity;
public class AboutActivity extends AppCompatActivity {
public class AboutActivity extends NextcloudMapsStyledActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View File

@ -27,7 +27,6 @@ import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;
@ -43,29 +42,26 @@ import androidx.preference.PreferenceManager;
import org.osmdroid.api.IMapController;
import org.osmdroid.config.Configuration;
import org.osmdroid.config.IConfigurationProvider;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.CustomZoomButtonsController;
import org.osmdroid.views.overlay.Marker;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.FormatStyle;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import it.danieleverducci.nextcloudmaps.BuildConfig;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.main.MainActivity;
import it.danieleverducci.nextcloudmaps.activity.main.MainActivityViewModel;
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity;
import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity;
import it.danieleverducci.nextcloudmaps.databinding.ActivityGeofavoriteDetailBinding;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
import it.danieleverducci.nextcloudmaps.utils.IntentGenerator;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import it.danieleverducci.nextcloudmaps.utils.MapUtils;
public class GeofavoriteDetailActivity extends AppCompatActivity implements LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity implements LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
public static final String TAG = "GeofavDetail";
public static final int MINIMUM_ACCEPTABLE_ACCURACY = 50; // In meters
@ -80,9 +76,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// OSMDroid config
Configuration.getInstance().load(getApplicationContext(),
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()));
MapUtils.configOsmdroid(this);
mViewHolder = new ViewHolder(getLayoutInflater());
setContentView(mViewHolder.getRootView());
@ -92,6 +86,11 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
finish();
}
@Override
public void onMapEditPressed() {
//TODO
}
@Override
public void onActionIconShareClicked() {
startActivity(Intent.createChooser(IntentGenerator.newShareIntent(GeofavoriteDetailActivity.this, mGeofavorite), getString(R.string.share_via)));
@ -320,6 +319,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
// Set map properties
this.binding.map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
this.binding.map.setMultiTouchControls(true);
MapUtils.setTheme(this.binding.map);
// this.binding.map.setTilesScaledToDpi(true);
// Create marker
@ -368,13 +368,12 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
}
public void setAccuracy(float accuracy) {
// Display accuracy in meters
binding.accuracyTv.setText(getString(R.string.accuracy).replace("{accuracy}", ((int)accuracy) + ""));
// Color the accuracy background with a scale from red (MINIMUM_ACCEPTABLE_ACCURACY) to green (0 meters)
float red = accuracy / MINIMUM_ACCEPTABLE_ACCURACY;
if (red > 1.0f) red = 1.0f;
float green = 1.0f - red;
if (Build.VERSION.SDK_INT >= 26)
binding.accuracyTv.setBackgroundColor(Color.rgb(red, green, 0.0f));
// Display accuracy in progress bar
int accuracyPercent = (int)accuracy > 100 ? 0 : Math.abs((int)accuracy - 100);
binding.accuracyProgress.setIndeterminate(false);
binding.accuracyProgress.setProgress(accuracyPercent);
}
public void setCategories(HashSet<String> categories) {
@ -383,6 +382,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
public void hideAccuracy() {
binding.accuracyTv.setVisibility(View.GONE);
binding.accuracyProgressContainer.setVisibility(View.GONE);
}
public void hideActions() {
@ -412,6 +412,9 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
if (v.getId() == R.id.back_bt && this.listener != null) {
this.listener.onBackPressed();
}
if (v.getId() == R.id.manual_pos_bt && this.listener != null) {
this.listener.onMapEditPressed();
}
// Actions
if (v.getId() == R.id.action_icon_share && this.listener != null) {
@ -430,6 +433,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
void onSubmit();
void onMapClicked();
void onBackPressed();
void onMapEditPressed();
void onActionIconShareClicked();
void onActionIconNavClicked();
void onActionIconDeleteClicked();

View File

@ -39,10 +39,11 @@ import com.nextcloud.android.sso.model.SingleSignOnAccount;
import com.nextcloud.android.sso.ui.UiExceptionManager;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity;
import it.danieleverducci.nextcloudmaps.activity.main.MainActivity;
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
public class LoginActivity extends AppCompatActivity {
public class LoginActivity extends NextcloudMapsStyledActivity {
protected ApiProvider mApi;
protected ProgressBar progress;

View File

@ -109,7 +109,7 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
Geofavorite geofavorite = geofavoriteListFiltered.get(position);
holder.tv_category.setText(geofavorite.categoryLetter());
holder.tv_category_background.setTint(
holder.setCategoryColor(
geofavorite.categoryColor() == 0 ? context.getColor(R.color.defaultBrand) : geofavorite.categoryColor());
holder.tv_title.setText(Html.fromHtml(geofavorite.getName()));
holder.tv_content.setText(geofavorite.getComment());
@ -164,7 +164,6 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
TextView tv_category, tv_title, tv_content, tv_date;
ImageView bt_context_menu;
ImageView bt_nav;
Drawable tv_category_background;
ItemClickListener itemClickListener;
@ -178,7 +177,6 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
tv_date = itemView.findViewById(R.id.date);
bt_context_menu = itemView.findViewById(R.id.geofav_context_menu_bt);
bt_nav = itemView.findViewById(R.id.geofav_nav_bt);
tv_category_background = DrawableCompat.wrap(tv_category.getBackground());
this.itemClickListener = itemClickListener;
itemView.setOnClickListener(this);
@ -191,19 +189,26 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
public void onClick(View view) {
switch (view.getId()) {
case R.id.geofav_context_menu_bt:
onOverflowIconClicked(view, getAdapterPosition());
onOverflowIconClicked(view, getBindingAdapterPosition());
break;
case R.id.geofav_nav_bt:
if (itemClickListener != null)
itemClickListener.onItemNavClick(get(getAdapterPosition()));
itemClickListener.onItemNavClick(get(getBindingAdapterPosition()));
break;
default:
if (itemClickListener != null)
itemClickListener.onItemClick(get(getAdapterPosition()));
itemClickListener.onItemClick(get(getBindingAdapterPosition()));
}
}
public void setCategoryColor(int ccTint) {
Drawable bg = DrawableCompat.wrap(this.tv_category.getContext().getDrawable(R.drawable.ic_list_pin));
this.tv_category.setBackground(bg);
DrawableCompat.setTint(bg, ccTint);
}
}
private void performSort() {
if (sortRule == SORT_BY_TITLE) {
Collections.sort(geofavoriteListFiltered, Geofavorite.ByTitleAZ);

View File

@ -23,6 +23,7 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
@ -50,11 +51,13 @@ import java.util.ArrayList;
import java.util.List;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity;
import it.danieleverducci.nextcloudmaps.activity.about.AboutActivity;
import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity;
import it.danieleverducci.nextcloudmaps.activity.login.LoginActivity;
import it.danieleverducci.nextcloudmaps.activity.main.NavigationAdapter.NavigationItem;
import it.danieleverducci.nextcloudmaps.activity.main.SortingOrderDialogFragment.OnSortingOrderListener;
import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
import it.danieleverducci.nextcloudmaps.utils.IntentGenerator;
@ -66,11 +69,12 @@ import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_TITLE;
import androidx.lifecycle.Observer;
public class MainActivity extends AppCompatActivity implements OnSortingOrderListener {
public class MainActivity extends NextcloudMapsStyledActivity implements OnSortingOrderListener {
private static final String TAG = "MainActivity";
private static final String NAVIGATION_KEY_ADD_GEOFAVORITE = "add";
private static final String NAVIGATION_KEY_ADD_GEOFAVORITE_FROM_GPS = "add_from_gps";
private static final String NAVIGATION_KEY_ADD_GEOFAVORITE_FROM_MAP = "add_from_map";
private static final String NAVIGATION_KEY_SHOW_ABOUT = "about";
private static final String NAVIGATION_KEY_SWITCH_ACCOUNT = "switch_account";
@ -89,10 +93,13 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
private ItemClickListener rvItemClickListener;
private MainActivityViewModel mMainActivityViewModel;
private boolean isFabOpen = false;
NavigationAdapter navigationCommonAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@ -127,7 +134,7 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
}
};
geofavoriteAdapter = new GeofavoriteAdapter(getApplicationContext(), rvItemClickListener);
geofavoriteAdapter = new GeofavoriteAdapter(this, rvItemClickListener);
recyclerView.setAdapter(geofavoriteAdapter);
geofavoriteAdapter.setSortRule(sortRule);
@ -165,8 +172,14 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
swipeRefresh.setOnRefreshListener(() ->
mMainActivityViewModel.updateGeofavorites());
fab = findViewById(R.id.add);
fab.setOnClickListener(view -> addGeofavorite());
fab = findViewById(R.id.open_fab);
fab.setOnClickListener(view -> openFab(!this.isFabOpen));
fab = findViewById(R.id.add_from_gps);
fab.setOnClickListener(view -> addGeofavoriteFromGps());
fab = findViewById(R.id.add_from_map);
fab.setOnClickListener(view -> addGeofavoriteFromMap());
toolbar = findViewById(R.id.toolbar);
homeToolbar = findViewById(R.id.home_toolbar);
@ -215,13 +228,22 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
updateGridIcon(gridViewEnabled);
}
@Override
protected void onPause() {
openFab(false);
super.onPause();
}
private void setupNavigationMenu() {
ArrayList<NavigationItem> navItems = new ArrayList<>();
navigationCommonAdapter = new NavigationAdapter(this, item -> {
switch (item.id) {
case NAVIGATION_KEY_ADD_GEOFAVORITE:
addGeofavorite();
case NAVIGATION_KEY_ADD_GEOFAVORITE_FROM_GPS:
addGeofavoriteFromGps();
break;
case NAVIGATION_KEY_ADD_GEOFAVORITE_FROM_MAP:
addGeofavoriteFromMap();
break;
case NAVIGATION_KEY_SHOW_ABOUT:
show_about();
@ -232,7 +254,8 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
}
});
navItems.add(new NavigationItem(NAVIGATION_KEY_ADD_GEOFAVORITE, getString(R.string.new_geobookmark), R.drawable.ic_add));
navItems.add(new NavigationItem(NAVIGATION_KEY_ADD_GEOFAVORITE_FROM_GPS, getString(R.string.new_geobookmark_gps), R.drawable.ic_add_gps));
navItems.add(new NavigationItem(NAVIGATION_KEY_ADD_GEOFAVORITE_FROM_MAP, getString(R.string.new_geobookmark_map), R.drawable.ic_add_map));
navItems.add(new NavigationItem(NAVIGATION_KEY_SHOW_ABOUT, getString(R.string.about), R.drawable.ic_info_grey));
navItems.add(new NavigationItem(NAVIGATION_KEY_SWITCH_ACCOUNT, getString(R.string.switch_account), R.drawable.ic_logout_grey));
navigationCommonAdapter.setItems(navItems);
@ -257,12 +280,18 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
SortingOrderDialogFragment.newInstance(sortOrder).show(fragmentTransaction, SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT);
}
private void addGeofavorite() {
private void addGeofavoriteFromGps() {
startActivity(
new Intent(this, GeofavoriteDetailActivity.class)
);
}
private void addGeofavoriteFromMap() {
startActivity(
new Intent(this, MapPickerActivity.class)
);
}
private void show_about() {
startActivity(new Intent(this, AboutActivity.class));
}
@ -336,4 +365,23 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
startActivity(i);
}
private void openFab(boolean open) {
View fab = findViewById(R.id.open_fab);
View addFromGpsFab = findViewById(R.id.add_from_gps);
View addFromMapFab = findViewById(R.id.add_from_map);
if (open) {
this.isFabOpen = true;
fab.animate().rotation(45.0f);
addFromGpsFab.animate().translationY(-getResources().getDimension(R.dimen.fab_vertical_offset));
addFromMapFab.animate().translationY(-getResources().getDimension(R.dimen.fab_vertical_offset) * 2);
} else {
this.isFabOpen = false;
fab.animate().rotation(0f);
addFromGpsFab.animate().translationY(0);
addFromMapFab.animate().translationY(0);
}
}
}

View File

@ -80,15 +80,12 @@ public class NavigationAdapter extends RecyclerView.Adapter<NavigationAdapter.Vi
}
private void bind(@NonNull NavigationItem item) {
int color = view.getResources().getColor(R.color.accent);
currentItem = item;
name.setText(item.label);
name.setTextColor(color);
icon.setImageDrawable(DrawableCompat.wrap(icon.getResources().getDrawable(item.icon)));
icon.setColorFilter(color);
icon.setVisibility(View.VISIBLE);
}

View File

@ -32,6 +32,7 @@ import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.DialogFragment;
@ -130,10 +131,10 @@ public class SortingOrderDialogFragment extends DialogFragment {
if (view instanceof ImageButton) {
Drawable normalDrawable = ((ImageButton) view).getDrawable();
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, this.getResources().getColor(R.color.defaultTint));
DrawableCompat.setTint(wrapDrawable, ContextCompat.getColor(getContext(), R.color.selector_item_selected));
}
if (view instanceof TextView) {
((TextView)view).setTextColor(this.getResources().getColor(R.color.defaultTint));
((TextView)view).setTextColor(ContextCompat.getColor(getContext(), R.color.selector_item_selected));
((TextView)view).setTypeface(Typeface.DEFAULT_BOLD);
}
}

View File

@ -0,0 +1,229 @@
package it.danieleverducci.nextcloudmaps.activity.mappicker;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.preference.PreferenceManager;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.api.IMapController;
import org.osmdroid.config.Configuration;
import org.osmdroid.config.IConfigurationProvider;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.CustomZoomButtonsController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;
import java.util.Locale;
import it.danieleverducci.nextcloudmaps.BuildConfig;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity;
import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity;
import it.danieleverducci.nextcloudmaps.databinding.ActivityMapPickerBinding;
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
import it.danieleverducci.nextcloudmaps.utils.MapUtils;
public class MapPickerActivity extends NextcloudMapsStyledActivity {
public static final String TAG = "MapPickerActivity";
private static final int PERMISSION_REQUEST_CODE = 8888;
private ViewHolder mViewHolder;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapUtils.configOsmdroid(this);
mViewHolder = new MapPickerActivity.ViewHolder(getLayoutInflater());
mViewHolder.setViewEventListener(new ViewEventListener() {
@Override
public void onExitButtonPressed() {
finish();
}
@Override
public void onConfirmButtonPressed() {
double[] coords = mViewHolder.getCurrentCoordinates();
Uri geoUri = GeoUriParser.createUri(coords[0], coords[1], null);
Intent i = new Intent(MapPickerActivity.this, GeofavoriteDetailActivity.class);
i.setData(geoUri);
startActivity(i);
finish();
}
});
Location l = getLastKnownPosition();
if (l != null)
mViewHolder.centerMapOn(l.getLatitude(), l.getLongitude());
setContentView(mViewHolder.getRootView());
}
/**
* May return last known GPS position or null. Used to center the map.
* @return last known GPS position or null
*/
private Location getLastKnownPosition() {
// Check if user granted location permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// User didn't grant permission. Ask it.
requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
return null;
}
LocationManager locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
// Try to use last available location
return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
private class ViewHolder implements View.OnClickListener {
private final ActivityMapPickerBinding binding;
private ViewEventListener listener;
private final MapView map;
private boolean coordsEditMode = false;
public ViewHolder(LayoutInflater inflater) {
this.binding = ActivityMapPickerBinding.inflate(inflater);
// Show confirm button on lat/lng edit
View.OnFocusChangeListener latlonFocusListener = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean focused) {
if (!focused)
return;
(ViewHolder.this).coordsEditMode(true);
}
};
this.binding.latEt.setOnFocusChangeListener(latlonFocusListener);
this.binding.lonEt.setOnFocusChangeListener(latlonFocusListener);
// Setup map
this.map = this.binding.map;
this.map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
this.map.setMultiTouchControls(true);
MapUtils.setTheme(this.map);
this.map.addMapListener(new MapListener() {
@Override
public boolean onScroll(ScrollEvent event) {
// Disable edit mode
if ((ViewHolder.this).coordsEditMode)
(ViewHolder.this).coordsEditMode(false);
// Write coords on edittext
IGeoPoint igp = (ViewHolder.this).map.getMapCenter();
(ViewHolder.this).binding.latEt.setText(String.format(Locale.ENGLISH, "%.06f", igp.getLatitude()));
(ViewHolder.this).binding.lonEt.setText(String.format(Locale.ENGLISH, "%.06f", igp.getLongitude()));
return false;
}
@Override
public boolean onZoom(ZoomEvent event) {
return false;
}
});
IMapController mapController = binding.map.getController();
mapController.setZoom(7.0f);
// Setup onClick
this.binding.latlonConfirmBtn.setOnClickListener(this);
this.binding.backBt.setOnClickListener(this);
this.binding.okBt.setOnClickListener(this);
}
public void setViewEventListener(ViewEventListener listener) {
this.listener = listener;
}
public void centerMapOn(Double lat, Double lon ) {
IMapController mapController = binding.map.getController();
mapController.setCenter(new GeoPoint(lat, lon));
}
public View getRootView() {
return this.binding.root;
}
@Override
public void onClick(View view) {
if (view == this.binding.latlonConfirmBtn) {
this.coordsEditMode(false);
Double lat;
Double lon;
try {
lat = Double.parseDouble(this.binding.latEt.getText().toString());
lon = Double.parseDouble(this.binding.lonEt.getText().toString());
} catch (NumberFormatException e) {
Log.e(TAG, "Unable to parse coordinates: " + e.getLocalizedMessage());
Toast.makeText(MapPickerActivity.this, R.string.coordinates_parse_error, Toast.LENGTH_SHORT).show();
return;
}
// Validate coordinates
if (lon <= -180 || lon >= 180 || lat <= -90 || lat >= 90) {
Toast.makeText(MapPickerActivity.this, R.string.coordinates_invalid_error, Toast.LENGTH_SHORT).show();
return;
}
// Move map to coordinates
this.centerMapOn(lat, lon);
}
if (view == this.binding.backBt)
listener.onExitButtonPressed();
if (view == this.binding.okBt)
listener.onConfirmButtonPressed();
}
public double[] getCurrentCoordinates() {
IGeoPoint igp = (ViewHolder.this).map.getMapCenter();
return new double[]{igp.getLatitude(), igp.getLongitude()};
}
/**
* Enters/exits coordinates edit mode.
* On exit, removes focus from the coordinates ET and hides the button
*/
private void coordsEditMode(boolean active) {
this.coordsEditMode = active;
View btn = this.binding.latlonConfirmBtn;
if (active) {
btn.setVisibility(View.VISIBLE);
} else {
this.binding.latEt.clearFocus();
this.binding.lonEt.clearFocus();
btn.setVisibility(View.GONE);
// Hide soft keyboard
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(btn.getWindowToken(), 0);
}
}
}
protected interface ViewEventListener {
public void onExitButtonPressed();
public void onConfirmButtonPressed();
}
}

View File

@ -36,6 +36,8 @@ import org.threeten.bp.ZoneId;
import java.io.Serializable;
import java.util.Comparator;
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
public class Geofavorite implements Serializable {
public static final String DEFAULT_CATEGORY = "Personal";
private static final double EARTH_RADIUS = 6371; // https://en.wikipedia.org/wiki/Earth_radius
@ -162,7 +164,7 @@ public class Geofavorite implements Serializable {
}
public Uri getGeoUri() {
return Uri.parse("geo:" + this.lat + "," + this.lng + "(" + this.name + ")");
return GeoUriParser.createUri(this.lat, this.lng, this.name);
}
public boolean valid() {
@ -195,7 +197,7 @@ public class Geofavorite implements Serializable {
* @see "https://github.com/nextcloud/maps/blob/master/src/utils.js"
* @return the generated color or null for the default category
*/
public int categoryColor() {
public int categoryColor() {
// If category is default, return null: will be used Nextcloud's accent
if (this.category.equals(DEFAULT_CATEGORY))
return 0;

View File

@ -28,4 +28,17 @@ public class GeoUriParser {
throw new IllegalArgumentException("unable to parse uri");
}
}
public static Uri createUri(double lat, double lon, String name) {
// Check coords validity
if (lon <= -180 || lon >= 180 )
throw new IllegalArgumentException("Invalid longitude: " + lon);
if (lat <= -90 || lat >= 90)
throw new IllegalArgumentException("Invalid latitude: " + lat);
String uriStr = "geo:" + lat + "," + lon;
if (name != null)
uriStr += "(" + name + ")";
return Uri.parse(uriStr);
}
}

View File

@ -2,6 +2,7 @@ package it.danieleverducci.nextcloudmaps.utils;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;

View File

@ -0,0 +1,36 @@
package it.danieleverducci.nextcloudmaps.utils;
import android.content.Context;
import android.content.res.Configuration;
import androidx.preference.PreferenceManager;
import org.osmdroid.config.IConfigurationProvider;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.TilesOverlay;
import it.danieleverducci.nextcloudmaps.BuildConfig;
public class MapUtils {
public static void configOsmdroid(Context context) {
IConfigurationProvider osmdroidConfig = org.osmdroid.config.Configuration.getInstance();
osmdroidConfig.load(context,
PreferenceManager.getDefaultSharedPreferences(context));
osmdroidConfig.setUserAgentValue(BuildConfig.APPLICATION_ID);
}
public static void setTheme(MapView mapView) {
int currentNightMode = mapView.getContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
case Configuration.UI_MODE_NIGHT_NO:
// Night mode is not active, we're using the light theme
mapView.getOverlayManager().getTilesOverlay().setColorFilter(null);
break;
case Configuration.UI_MODE_NIGHT_YES:
// Night mode is active, we're using dark theme
mapView.getOverlayManager().getTilesOverlay().setColorFilter(TilesOverlay.INVERT_COLORS);
break;
}
}
}

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06c-1.13,0.12 -2.19,0.46 -3.16,0.97l1.5,1.5C10.16,5.19 11.06,5 12,5c3.87,0 7,3.13 7,7 0,0.94 -0.19,1.84 -0.52,2.65l1.5,1.5c0.5,-0.96 0.84,-2.02 0.97,-3.15L23,13v-2h-2.06zM3,4.27l2.04,2.04C3.97,7.62 3.25,9.23 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c1.77,-0.2 3.38,-0.91 4.69,-1.98L19.73,21 21,19.73 4.27,3 3,4.27zM16.27,17.54C15.09,18.45 13.61,19 12,19c-3.87,0 -7,-3.13 -7,-7 0,-1.61 0.55,-3.09 1.46,-4.27l9.81,9.81z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06C6.83,3.52 3.52,6.83 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c4.17,-0.46 7.48,-3.77 7.94,-7.94L23,13v-2h-2.06zM12,19c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06C6.83,3.52 3.52,6.83 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c4.17,-0.46 7.48,-3.77 7.94,-7.94L23,13v-2h-2.06zM12,19c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20.5,3l-0.16,0.03L15,5.1 9,3 3.36,4.9c-0.21,0.07 -0.36,0.25 -0.36,0.48V20.5c0,0.28 0.22,0.5 0.5,0.5l0.16,-0.03L9,18.9l6,2.1 5.64,-1.9c0.21,-0.07 0.36,-0.25 0.36,-0.48V3.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM15,19l-6,-2.11V5l6,2.11V19z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="48dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7z"/>
</vector>

View File

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M13.95,13H9V8.05l5.61,-5.61C13.78,2.16 12.9,2 12,2c-4.2,0 -8,3.22 -8,8.2c0,3.32 2.67,7.25 8,11.8c5.33,-4.55 8,-8.48 8,-11.8c0,-1.01 -0.16,-1.94 -0.45,-2.8L13.95,13z"/>
<path
android:fillColor="@android:color/white"
android:pathData="M11,11l2.12,0l6.16,-6.16l-2.12,-2.12l-6.16,6.16z"/>
<path
android:fillColor="@android:color/white"
android:pathData="M20.71,2L20,1.29C19.8,1.1 19.55,1 19.29,1c-0.13,0 -0.48,0.07 -0.71,0.29l-0.72,0.72l2.12,2.12l0.72,-0.72C21.1,3.02 21.1,2.39 20.71,2z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

View File

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="8dp"
android:right="8dp"
android:top="8dp"
android:bottom="8dp">
<item>
<shape
android:shape="oval">
<solid android:color="@color/defaultBrand"/>

View File

@ -53,11 +53,24 @@
android:id="@+id/back_bt"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="start"
android:padding="16dp"
android:src="@drawable/ic_back_grey"
app:tint="@color/white"
android:background="@drawable/floating_semitransparent_button_background"/>
<!-- Manual position button -->
<ImageView
android:id="@+id/manual_pos_bt"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="end"
android:padding="16dp"
android:src="@drawable/ic_manual_pos"
app:tint="@color/white"
android:background="@drawable/floating_semitransparent_button_background"
android:visibility="gone"/> <!-- TODO: Implement edit -->
</androidx.appcompat.widget.Toolbar>
@ -77,15 +90,43 @@
android:orientation="vertical"
android:padding="20dp">
<LinearLayout
android:id="@+id/accuracy_progress_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:src="@drawable/ic_accuracy_fail"
app:tint="@color/disabled"/>
<ProgressBar
android:id="@+id/accuracy_progress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:indeterminate="true"
style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:src="@drawable/ic_accuracy_ok"/>
</LinearLayout>
<TextView
android:id="@+id/accuracy_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:textAlignment="center"
android:text="@string/accuracy"
android:textColor="@android:color/white"
android:background="@android:color/darker_gray"/>
android:text="@string/accuracy_nosignal"
android:textColor="@color/defaultBrand"/>
<LinearLayout
android:id="@+id/action_icons"
@ -100,7 +141,7 @@
android:layout_weight="1"
android:padding="10dp"
android:src="@drawable/ic_share"
android:tint="@color/defaultBrand"/>
app:tint="@color/defaultBrand"/>
<ImageView
android:id="@+id/action_icon_nav"
@ -109,7 +150,7 @@
android:layout_weight="1"
android:padding="10dp"
android:src="@drawable/ic_nav"
android:tint="@color/defaultBrand"/>
app:tint="@color/defaultBrand"/>
<ImageView
android:id="@+id/action_icon_delete"
@ -118,7 +159,7 @@
android:layout_weight="1"
android:padding="10dp"
android:src="@drawable/ic_delete_grey"
android:tint="@color/defaultBrand"
app:tint="@color/defaultBrand"
android:visibility="gone"/> <!-- TODO Implement delete -->

View File

@ -21,7 +21,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_list_view"
android:background="@color/primary"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -65,7 +64,6 @@
android:layout_marginTop="@dimen/spacer_1hx"
android:layout_marginEnd="@dimen/spacer_2x"
android:layout_marginBottom="@dimen/spacer_1hx"
app:cardBackgroundColor="@color/appbar"
app:cardCornerRadius="@dimen/spacer_1x"
app:cardElevation="2dp"
app:strokeWidth="0dp">
@ -77,14 +75,15 @@
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/menu_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:background="?attr/selectableItemBackgroundBorderless"
android:layout_gravity="center_vertical|start"
android:paddingStart="@dimen/spacer_1x"
android:paddingTop="@dimen/spacer_2x"
android:paddingEnd="@dimen/spacer_1x"
android:paddingBottom="@dimen/spacer_2x"
android:tint="?attr/colorAccent"
android:tint="@color/text_color"
android:src="@drawable/ic_menu_grey"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/search_text"
@ -106,8 +105,11 @@
android:layout_gravity="center_vertical|end"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/list_mode"
android:padding="@dimen/spacer_2x"
android:tint="?attr/colorAccent"
android:paddingStart="@dimen/spacer_1x"
android:paddingTop="@dimen/spacer_2x"
android:paddingEnd="@dimen/spacer_1x"
android:paddingBottom="@dimen/spacer_2x"
android:tint="@color/text_color"
android:translationX="@dimen/spacer_1x"
android:src="@drawable/ic_alphabetical_asc" />
<androidx.appcompat.widget.AppCompatImageView
@ -117,10 +119,13 @@
android:layout_gravity="center_vertical|end"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/list_mode"
android:padding="@dimen/spacer_2x"
android:tint="?attr/colorAccent"
android:paddingStart="@dimen/spacer_1x"
android:paddingTop="@dimen/spacer_2x"
android:paddingEnd="@dimen/spacer_1x"
android:paddingBottom="@dimen/spacer_2x" android:tint="@color/text_color"
android:translationX="@dimen/spacer_1x"
android:src="@drawable/ic_view_module" />
android:src="@drawable/ic_view_module"
android:visibility="gone"/> <!-- TODO: Replace with Map View icon -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
@ -154,8 +159,31 @@
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<!-- Add from map FAB -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add"
android:id="@+id/add_from_map"
android:layout_margin="24dp"
android:layout_gravity="bottom|end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:fabSize="mini"
android:src="@drawable/ic_add_map"
app:backgroundTint="@color/defaultBrand"/>
<!-- Add from current position FAB -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_from_gps"
android:layout_margin="24dp"
android:layout_gravity="bottom|end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:fabSize="mini"
android:src="@drawable/ic_add_gps"
app:backgroundTint="@color/defaultBrand"/>
<!-- Main FAB -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/open_fab"
android:layout_margin="16dp"
android:layout_gravity="bottom|end"
android:layout_width="wrap_content"

View File

@ -46,8 +46,7 @@
android:layout_centerVertical="true"
android:layout_marginBottom="48dp"
android:textSize="24sp"
android:gravity="center_horizontal"
android:textColor="@color/accent"/>
android:gravity="center_horizontal"/>
<Button
android:id="@+id/chose_button"

View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<FrameLayout
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.osmdroid.views.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="24dp"
android:layout_gravity="center"
android:src="@drawable/ic_map_pin"/>
<ImageView
android:id="@+id/back_bt"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="start"
android:padding="16dp"
android:src="@drawable/ic_back_grey"
app:tint="@color/white"
android:background="@drawable/floating_semitransparent_button_background"/>
<ImageView
android:id="@+id/ok_bt"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="end"
android:padding="16dp"
android:src="@drawable/ic_ok"
app:tint="@color/white"
android:background="@drawable/floating_semitransparent_button_background"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="10dp"
android:orientation="horizontal"
android:background="@color/defaultBrandAlpha">
<EditText
android:id="@+id/lat_et"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:textAlignment="center"
android:lines="1"
android:maxLines="1"
android:inputType="numberDecimal"
android:textColor="@color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textStyle="bold"
android:text="°N"
android:textColor="@color/white"/>
<EditText
android:id="@+id/lon_et"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:layout_marginStart="10dp"
android:textAlignment="center"
android:lines="1"
android:maxLines="1"
android:inputType="numberDecimal"
android:textColor="@color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textStyle="bold"
android:text="°E"
android:textColor="@color/white"/>
<ImageView
android:id="@+id/latlon_confirm_btn"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="10dp"
android:padding="8dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_ok"
app:tint="@color/white"
android:background="@drawable/round_button_background"
android:visibility="gone"/>
</LinearLayout>
</FrameLayout>
</layout>

View File

@ -19,6 +19,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="90dp"
@ -32,11 +33,13 @@
android:layout_height="64dp"
android:layout_marginStart="4dp"
android:layout_weight="0"
android:background="@drawable/category_listitem_background"
android:gravity="center"
android:background="@drawable/ic_list_pin"
android:gravity="top|center"
android:paddingTop="5dp"
android:textSize="28dp"
android:textAllCaps="true"
android:textColor="@color/white"/>
android:textColor="@color/white"
app:drawableTint="@color/defaultBrand" />
<LinearLayout
android:orientation="vertical"
@ -103,7 +106,7 @@
android:layout_weight="0"
android:padding="8dp"
android:src="@drawable/ic_nav"
android:tint="@color/secondary_text_color" /> <!-- TODO: app:tint is not working -->
app:tint="@color/secondary_text_color" /> <!-- TODO: app:tint is not working -->
<ImageView
android:id="@+id/geofav_context_menu_bt"
@ -112,6 +115,6 @@
android:layout_weight="0"
android:padding="8dp"
android:src="@drawable/ic_more"
android:tint="@color/secondary_text_color" /> <!-- TODO: app:tint is not working -->
app:tint="@color/secondary_text_color" /> <!-- TODO: app:tint is not working -->
</LinearLayout>

View File

@ -18,6 +18,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
@ -33,7 +34,8 @@
android:contentDescription="@null"
android:focusable="false"
android:scaleType="center"
android:src="@drawable/ic_time_grey"/>
android:src="@drawable/ic_time_grey"
app:tint="@color/text_color"/>
<TextView
android:id="@+id/navigationItemLabel"

View File

@ -16,8 +16,9 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout
android:id="@+id/root"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="300dp"
@ -57,7 +58,8 @@
android:paddingEnd="@dimen/standard_half_padding"
android:paddingBottom="@dimen/standard_half_padding"
android:contentDescription="@string/menu_item_sort_by_title_a_z"
android:src="@drawable/ic_alphabetical_asc" />
android:src="@drawable/ic_alphabetical_asc"
app:tint="@color/selector_item_unselected"/>
<TextView
android:id="@+id/sortByTitleAscendingText"
@ -72,7 +74,8 @@
android:paddingBottom="@dimen/standard_half_padding"
android:singleLine="true"
android:text="@string/menu_item_sort_by_title_a_z"
android:textSize="@dimen/two_line_primary_text_size"/>
android:textSize="@dimen/two_line_primary_text_size"
android:textColor="@color/text_color"/>
</TableRow>
@ -92,7 +95,8 @@
android:paddingEnd="@dimen/standard_half_padding"
android:paddingBottom="@dimen/standard_half_padding"
android:contentDescription="@string/menu_item_sort_by_date_newest_first"
android:src="@drawable/ic_modification_asc"/>
android:src="@drawable/ic_modification_asc"
app:tint="@color/selector_item_unselected"/>
<TextView
android:id="@+id/sortByCreationDateDescendingText"
@ -107,7 +111,8 @@
android:paddingBottom="@dimen/standard_half_padding"
android:singleLine="true"
android:text="@string/menu_item_sort_by_date_newest_first"
android:textSize="@dimen/two_line_primary_text_size" />
android:textSize="@dimen/two_line_primary_text_size"
android:textColor="@color/selector_item_unselected" />
</TableRow>
@ -127,7 +132,8 @@
android:paddingEnd="@dimen/standard_half_padding"
android:paddingBottom="@dimen/standard_half_padding"
android:contentDescription="@string/menu_item_sort_by_category_a_z"
android:src="@drawable/ic_category_asc"/>
android:src="@drawable/ic_category_asc"
app:tint="@color/selector_item_unselected"/>
<TextView
android:id="@+id/sortByCategoryAscendingText"
@ -142,7 +148,8 @@
android:paddingBottom="@dimen/standard_half_padding"
android:singleLine="true"
android:text="@string/menu_item_sort_by_category_a_z"
android:textSize="@dimen/two_line_primary_text_size" />
android:textSize="@dimen/two_line_primary_text_size"
android:textColor="@color/selector_item_unselected" />
</TableRow>
@ -163,7 +170,8 @@
android:paddingEnd="@dimen/standard_half_padding"
android:paddingBottom="@dimen/standard_half_padding"
android:contentDescription="@string/menu_item_sort_by_distance_nearest_first"
android:src="@drawable/ic_distance_asc"/>
android:src="@drawable/ic_distance_asc"
app:tint="@color/selector_item_unselected"/>
<TextView
android:id="@+id/sortByDistanceAscendingText"
@ -178,7 +186,8 @@
android:paddingBottom="@dimen/standard_half_padding"
android:singleLine="true"
android:text="@string/menu_item_sort_by_distance_nearest_first"
android:textSize="@dimen/two_line_primary_text_size" />
android:textSize="@dimen/two_line_primary_text_size"
android:textColor="@color/selector_item_unselected" />
</TableRow>
@ -196,7 +205,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/common_cancel"
android:layout_marginTop="@dimen/standard_half_margin"/>
android:textAllCaps="false"
android:layout_marginTop="@dimen/standard_half_margin"
style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog"/>
</LinearLayout>

View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Nextcloud Maps Geofavorites for Android
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<!-- App strings -->
<string name="app_name">Maps Geobookmarks</string>
<string name="welcome">Benvenuto su Nextcloud Maps Geobookmarks</string>
<!-- Login Activity -->
<string name="choose_account">Scegli account</string>
<!-- Geobookmarks list -->
<string name="new_geobookmark">Nuovo geosegnalibro</string>
<string name="about">Informazioni</string>
<string name="switch_account">Cambia account</string>
<string name="list_mode">Lista</string>
<string name="search_in_all">Cerca per nome</string>
<string name="share_via">Condividi via</string>
<string name="share_message">Posizione condivisa: {lat}°N, {lng}°E https://www.openstreetmap.org/#map=17/{lat}/{lng}</string>
<string name="list_context_menu_share">Condividi</string>
<string name="list_context_menu_delete">Elimina</string>
<string name="dialog_delete_title">Elimina geosegnalibro</string>
<string name="dialog_delete_message">Stai per eliminare il geosegnalibro {name}. Procedere?</string>
<string name="dialog_delete_delete">Elimina</string>
<string name="dialog_delete_cancel">Mantieni</string>
<string name="list_geofavorite_deleted">Geosegnalibro eliminato</string>
<string name="list_geofavorite_connection_error">Impossibile ottenere la lista dei geosegnalibri</string>
<!-- Sort dialog -->
<string name="sort_by">Ordina per</string>
<string name="menu_item_sort_by_title_a_z">A - Z</string>
<string name="menu_item_sort_by_date_newest_first">Più recenti</string>
<string name="menu_item_sort_by_category_a_z">Categoria</string>
<string name="menu_item_sort_by_distance_nearest_first">Distanza</string>
<!-- Geobookmarks detail -->
<string name="name">Nome</string>
<string name="description">Descrizione</string>
<string name="created">Creato</string>
<string name="modified">Modificato</string>
<string name="category">Categoria</string>
<string name="coords">Coordinate</string>
<string name="accuracy">Accuratezza: {accuracy} m</string>
<string name="accuracy_nosignal">Nessun segnale GPS!</string>
<string name="location_permission_required">Per creare un geosegnalibro è necessario consentire l\'accesso alla posizione.</string>
<string name="confirm">Salva</string>
<string name="error_saving_geofavorite">Impossibile salvare il geosegnalibro</string>
<string name="error_unsupported_uri">Impossibile ottenere le coordinate dai dati ricevuti</string>
<string name="geofavorite_saved">Geosegnalibro salvato</string>
<string name="incomplete_geofavorite">Geosegnalibro incompleto: nome e categoria sono obbligatori</string>
<!-- Map picker activity -->
<string name="coordinates_parse_error">Le coordinate dovrebbero essere nel formato xx.xxxxxx</string>
<string name="coordinates_invalid_error">Coordinate non valide</string>
<string name="coordinates_north">°N</string>
<string name="coordinates_east">°E</string>
<!-- About -->
<string name="about_version_title">Versione</string>
<string name="about_version">Stai usando la versione &lt;strong>%1$s&lt;/strong></string>
<string name="about_source_title">Codice sorgente</string>
<string name="about_source">Questo progetto è disponibile su GitHub: &lt;a href="%1$s">%1$s&lt;/a></string>
<string name="about_issues_title">Segnalazioni</string>
<string name="about_issues">Puoi segnalare bugs, proporre migliorie o richiedere nuove funzionalità sul GitHub issue tracker: &lt;a href="%1$s">%1$s&lt;/a></string>
<string name="about_maps_title">Mappe</string>
<string name="about_maps">Questa app usa i server e le tiles di OpenStreetMap. Non accetto donazioni per questa app, ma raccomando piuttosto di donare a &lt;a href="%1$s">OpenStreetMap&lt;/a>, poiché questa applicazione non potrebbe esistere senza di loro.</string>
<string name="about_app_license_title">Licenza</string>
<string name="about_app_license">Questa applicazione è rilasciata sotto licenza GNU GENERAL PUBLIC LICENSE v3+.</string>
<string name="about_app_license_button">Mostra licenza</string>
<!-- Common strings -->
<string name="common_yes">Si</string>
<string name="common_cancel">Annulla</string>
<!-- URLs -->
<string name="url_source" translatable="false">https://github.com/penguin86/nextcloud-maps-client</string>
<string name="url_issues" translatable="false">https://github.com/penguin86/nextcloud-maps-client/issues</string>
<string name="url_license" translatable="false">https://raw.githubusercontent.com/penguin86/nextcloud-maps-client/master/LICENSE</string>
<string name="url_maps" translatable="false">https://donate.openstreetmap.org</string>
<!-- Settings -->
<string name="setting_sort_by">SETTING_SORT_BY</string>
<string name="setting_grid_view_enabled">SETTING_GRID_VIEW_ENABLED</string>
<!-- Menu -->
<string name="new_geobookmark_gps">Crea dalla posizione corrente</string>
<string name="new_geobookmark_map">Crea dalla mappa</string>
</resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="text_color">#eee</color>
<color name="disabled">#888</color>
<color name="defaultBackground">#000</color>
</resources>

View File

@ -19,16 +19,20 @@
<resources>
<!-- Generic Colors -->
<color name="primary">#ffffff</color>
<color name="accent">#121212</color>
<color name="transparent">#00000000</color>
<color name="defaultBrand">#0082C9</color>
<color name="defaultBrandAlpha">#550082C9</color>
<color name="appbar">@android:color/white</color>
<color name="defaultTint">#202124</color>
<color name="disabled">#666</color>
<color name="systemBar">@color/defaultBackground</color>
<color name="defaultBackground">#fff</color>
<!-- List Colors -->
<color name="text_color">#333333</color>
<color name="secondary_text_color">#666666</color>
<color name="text_color">#333</color>
<color name="secondary_text_color">@color/disabled</color>
<!-- Selectors text/tint colors -->
<color name="selector_item_selected">@color/defaultBrand</color>
<color name="selector_item_unselected">@color/disabled</color>
<!-- Generic Colors -->
<color name="white">#fff</color>

View File

@ -36,4 +36,7 @@
<dimen name="two_line_primary_text_size">16sp</dimen>
<dimen name="two_line_secondary_text_size">12sp</dimen>
<!-- FAB dimensions -->
<dimen name="fab_vertical_offset">75dp</dimen>
</resources>

View File

@ -24,7 +24,7 @@
<string name="choose_account">Choose account</string>
<!-- Geobookmarks list -->
<string name="new_geobookmark">New geobookmark</string>
<string name="new_geobookmark">New geofavorite</string>
<string name="about">About</string>
<string name="switch_account">Switch account</string>
<string name="list_mode">List</string>
@ -33,8 +33,8 @@
<string name="share_message">Check out this place: {lat}°N, {lng}°E https://www.openstreetmap.org/#map=17/{lat}/{lng}</string>
<string name="list_context_menu_share">Share</string>
<string name="list_context_menu_delete">Delete</string>
<string name="dialog_delete_title">Delete geobookmark</string>
<string name="dialog_delete_message">You are about to delete geobookmark {name}. Proceed?</string>
<string name="dialog_delete_title">Delete geofavorite</string>
<string name="dialog_delete_message">You are about to delete geofavorite {name}. Proceed?</string>
<string name="dialog_delete_delete">Delete</string>
<string name="dialog_delete_cancel">Maintain</string>
<string name="list_geofavorite_deleted">Geofavorite deleted</string>
@ -55,6 +55,7 @@
<string name="category">Category</string>
<string name="coords">Coordinates</string>
<string name="accuracy">Accuracy: {accuracy} m</string>
<string name="accuracy_nosignal">No GPS signal!</string>
<string name="location_permission_required">Location permission is required to create a geofavorite.</string>
<string name="confirm">Save</string>
<string name="error_saving_geofavorite">Unable to save geofavorite</string>
@ -62,6 +63,12 @@
<string name="geofavorite_saved">Geofavorite saved</string>
<string name="incomplete_geofavorite">Incomplete geofavorite: Name and category are mandatory</string>
<!-- Map picker activity -->
<string name="coordinates_parse_error">Coordinates should be in format xx.xxxxxx</string>
<string name="coordinates_invalid_error">Invalid coordinates</string>
<string name="coordinates_north">°N</string>
<string name="coordinates_east">°E</string>
<!-- About -->
<string name="about_version_title">Version</string>
<string name="about_version">You are currently using &lt;strong>%1$s&lt;/strong></string>
@ -89,4 +96,8 @@
<string name="setting_sort_by">SETTING_SORT_BY</string>
<string name="setting_grid_view_enabled">SETTING_GRID_VIEW_ENABLED</string>
<!-- Menu -->
<string name="new_geobookmark_gps">New from current position</string>
<string name="new_geobookmark_map">New from map</string>
</resources>

View File

@ -18,37 +18,25 @@
<resources>
<!-- Base application theme. -->
<style name="BaseTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/primary</item>
<!-- <item name="android:textColorPrimary">@color/white</item>-->
<item name="colorPrimaryDark">@color/primary</item>
<item name="colorAccent">@color/accent</item>
<item name="android:actionModeBackground">?attr/colorPrimary</item>
<item name="colorAccent">@color/defaultBrand</item>
<item name="colorControlNormal">?attr/colorAccent</item>
<item name="windowActionModeOverlay">true</item>
<item name="toolbarStyle">@style/toolbarStyle</item>
<!-- App bar -->
<item name="colorPrimary">@color/systemBar</item>
<!-- Generic background -->
<item name="android:windowBackground">@color/defaultBackground</item>
</style>
<style name="AppTheme" parent="BaseTheme"/>
<style name="EditorTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@android:color/transparent</item>
<item name="colorPrimaryDark">@color/accent</item>
<item name="colorAccent">@color/accent</item>
</style>
<style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
<style name="SplashTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
<style name="toolbarStyle" parent="@style/Widget.AppCompat.Toolbar">
<item name="android:background">?attr/colorPrimary</item>
</style>
<!-- Geofavorite detail text appearances -->
<style name="TextAppearance.GeofavoriteDetail.Header.Expanded" parent="TextAppearance.Design.CollapsingToolbar.Expanded">

View File

@ -1 +1 @@
First alpha release: working geobookmarks list, open geobookmarks in other apps via geo link, add geobookmark on current location.
First alpha release: working geobookmarks list, open geobookmarks in other apps via geo link, add geofavorite on current location.

View File

@ -0,0 +1,5 @@
Add geofavorite from map or coordinates
Night mode (dark theme)
New, less ambiguous, category icons (the old circle with letter inside is conventionally associated with user accounts)
Graphic fixes
Italian translation

View File

@ -1,6 +1,6 @@
UNOFFICIAL and FOSS Nextcloud Maps client at its earliest stages of developement. Shows your Nextcloud Maps geobookmarks list.
Geobookmarks can be opened in all apps supporting geo links (i.e. Google Maps, Organic Maps etc...).
A new geobookmark can be created on current location or by sharing a geo: uri from another app.
A new geofavorite can be created on current location, by sharing a "geo:" uri from another app or manually picking from the map.
Requires Maps app to be installed on the Nextcloud instance.
As per Nextcloud's guidelines, the login is implemented using Nextcloud's Single Sign On module and thus requires Nextcloud app installed.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

BIN
screenshots/full/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
screenshots/full/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB