Compare commits

..

No commits in common. "develop" and "master" have entirely different histories.

89 changed files with 683 additions and 1754 deletions

7
.gitignore vendored
View File

@ -96,10 +96,3 @@ lint/generated/
lint/outputs/ lint/outputs/
lint/tmp/ lint/tmp/
# lint/reports/ # lint/reports/
app/release/output-metadata.json
.idea/deploymentTargetDropDown.xml
.idea/misc.xml
.idea/deploymentTargetSelector.xml
.idea/other.xml

View File

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

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="$USER_HOME$/.android/avd/Pixel_5_API_29.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-02-15T07:23:10.782369Z" />
</component>
</project>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

30
.idea/misc.xml Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<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_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" />
</project>

View File

@ -8,7 +8,7 @@
(Always prefer [F-Droid](https://f-droid.org) build, when possible). (Always prefer [F-Droid](https://f-droid.org) build, when possible).
UNOFFICIAL and FOSS Nextcloud Maps client at its earliest stages of developement. Shows your Nextcloud Maps geofavorites in a list and a map. UNOFFICIAL and FOSS Nextcloud Maps client at its earliest stages of developement. Shows your Nextcloud Maps geofavorites list.
Geofavorites can be opened in all apps supporting geo links (i.e. Google Maps, Organic Maps etc...). Geofavorites 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. A new geofavorite can be created on current location, by sharing a "geo:" uri from another app or manually picking from the map.
@ -16,5 +16,5 @@ A new geofavorite can be created on current location, by sharing a "geo:" uri fr
This work is heavily based on [matiasdelellis's Nextcloud SSO example](https://github.com/matiasdelellis/app-tutorial-android) to implement [Nextcloud single sign on](https://github.com/nextcloud/Android-SingleSignOn). This work is heavily based on [matiasdelellis's Nextcloud SSO example](https://github.com/matiasdelellis/app-tutorial-android) to implement [Nextcloud single sign on](https://github.com/nextcloud/Android-SingleSignOn).
![Screenshot 1](screenshots/1.png) ![Screenshot 2](screenshots/2.png) ![Screenshot 3](screenshots/3.png) ![Screenshot 1](screenshots/1.png) ![Screenshot 1](screenshots/2.png)

View File

@ -18,12 +18,14 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 31
defaultConfig { defaultConfig {
applicationId "it.danieleverducci.nextcloudmaps" applicationId "it.danieleverducci.nextcloudmaps"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 35 targetSdkVersion 31
versionCode 9 versionCode 8
versionName "0.4.0" versionName "0.3.6"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@ -35,9 +37,6 @@ android {
} }
} }
compileOptions { compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
@ -45,7 +44,6 @@ android {
buildFeatures { buildFeatures {
dataBinding true dataBinding true
} }
namespace 'it.danieleverducci.nextcloudmaps'
} }
repositories { repositories {
@ -56,40 +54,28 @@ repositories {
dependencies { dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
// Desugaring lib: see https://developer.android.com/studio/write/java8-support implementation 'com.android.support:design:31.0.0'
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.2") implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.android.support:design:34.0.0'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.cardview:cardview:1.0.0"
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation "androidx.preference:preference:1.2.1" implementation "androidx.preference:preference:1.1.1"
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// Retrofif2 // Retrofif2
implementation 'com.squareup.retrofit2:retrofit:2.11.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1' implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
// Nextcloud SSO // Nextcloud SSO
implementation "com.github.nextcloud:Android-SingleSignOn:1.3.2" implementation "com.github.nextcloud:Android-SingleSignOn:0.6.1"
// OSMDroid // OSMDroid
implementation 'org.osmdroid:osmdroid-android:6.1.18' implementation 'org.osmdroid:osmdroid-android:6.1.10'
//Threeten-Backport (ports Java 8 Date API on Java 6+) //Threeten-Backport (ports Java 8 Date API on Java 6+)
implementation 'org.threeten:threetenbp:1.5.1' implementation 'org.threeten:threetenbp:1.5.1'
// https://mvnrepository.com/artifact/commons-io/commons-io
implementation 'commons-io:commons-io:2.13.0'
// Picasso (image loader)
implementation 'com.squareup.picasso:picasso:2.8'
configurations.all {
resolutionStrategy {
force 'commons-io:commons-io:2.11.0'
}
}
} }

View File

@ -17,7 +17,8 @@
--> -->
<manifest <manifest
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android"
package="it.danieleverducci.nextcloudmaps">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

View File

@ -1,47 +0,0 @@
package it.danieleverducci.nextcloudmaps.activity.detail;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.DrawableCompat;
import java.util.ArrayList;
import java.util.HashSet;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
public class CategoriesAdapter extends ArrayAdapter<String> {
public CategoriesAdapter(@NonNull Context context) {
super(context, R.layout.category_listitem, R.id.category_name, new ArrayList<>());
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View v = super.getView(position, convertView, parent);
TextView categoryName = v.findViewById(R.id.category_name);
Drawable backgroundDrawable = categoryName.getBackground();
DrawableCompat.setTint(
backgroundDrawable,
Geofavorite.categoryColorFromName(categoryName.getText().toString()) == 0
? v.getContext().getColor(R.color.defaultBrand)
: Geofavorite.categoryColorFromName(categoryName.getText().toString())
);
return v;
}
public void setCategoriesList(HashSet<String> categories) {
clear();
addAll(categories);
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,24 @@
package it.danieleverducci.nextcloudmaps.activity.detail;
import android.content.Context;
import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import java.util.HashSet;
public class CategoriesSpinnerAdapter extends ArrayAdapter<String> {
public CategoriesSpinnerAdapter(@NonNull Context context) {
super(context, android.R.layout.simple_dropdown_item_1line);
}
// TODO: implement colors
public void setCategoriesList(HashSet<String> categories) {
clear();
addAll(categories);
notifyDataSetChanged();
}
}

View File

@ -18,14 +18,14 @@
package it.danieleverducci.nextcloudmaps.activity.detail; package it.danieleverducci.nextcloudmaps.activity.detail;
import android.Manifest; import android.Manifest;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location; import android.location.Location;
import android.location.LocationListener; import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -34,6 +34,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
@ -42,6 +43,7 @@ import androidx.preference.PreferenceManager;
import org.osmdroid.api.IMapController; import org.osmdroid.api.IMapController;
import org.osmdroid.config.Configuration; import org.osmdroid.config.Configuration;
import org.osmdroid.config.IConfigurationProvider;
import org.osmdroid.util.GeoPoint; import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.CustomZoomButtonsController; import org.osmdroid.views.CustomZoomButtonsController;
import org.osmdroid.views.overlay.Marker; import org.osmdroid.views.overlay.Marker;
@ -50,8 +52,10 @@ import org.threeten.bp.format.FormatStyle;
import java.util.HashSet; import java.util.HashSet;
import it.danieleverducci.nextcloudmaps.BuildConfig;
import it.danieleverducci.nextcloudmaps.R; import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity; import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity;
import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity;
import it.danieleverducci.nextcloudmaps.databinding.ActivityGeofavoriteDetailBinding; import it.danieleverducci.nextcloudmaps.databinding.ActivityGeofavoriteDetailBinding;
import it.danieleverducci.nextcloudmaps.model.Geofavorite; import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser; import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
@ -82,6 +86,11 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple
finish(); finish();
} }
@Override
public void onMapEditPressed() {
//TODO
}
@Override @Override
public void onActionIconShareClicked() { public void onActionIconShareClicked() {
startActivity(Intent.createChooser(IntentGenerator.newShareIntent(GeofavoriteDetailActivity.this, mGeofavorite), getString(R.string.share_via))); startActivity(Intent.createChooser(IntentGenerator.newShareIntent(GeofavoriteDetailActivity.this, mGeofavorite), getString(R.string.share_via)));
@ -304,15 +313,9 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple
this.binding.actionIconNav.setOnClickListener(this); this.binding.actionIconNav.setOnClickListener(this);
// Set categories adapter // Set categories adapter
CategoriesAdapter categoriesAdapter = new CategoriesAdapter(binding.root.getContext()); CategoriesSpinnerAdapter categoriesAdapter = new CategoriesSpinnerAdapter(binding.root.getContext());
this.binding.categoryAt.setAdapter(categoriesAdapter); this.binding.categoryAt.setAdapter(categoriesAdapter);
this.binding.categoryAt.setText(Geofavorite.DEFAULT_CATEGORY); this.binding.categoryAt.setText(Geofavorite.DEFAULT_CATEGORY);
this.binding.categoryAtClear.setOnClickListener((v) -> {
if (this.binding.categoryAt.getText().toString().isEmpty())
this.binding.categoryAt.setText(Geofavorite.DEFAULT_CATEGORY);
else
this.binding.categoryAt.setText("");
});
// Set map properties // Set map properties
this.binding.map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER); this.binding.map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
@ -343,12 +346,6 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple
public void updateViewCoords(Geofavorite item) { public void updateViewCoords(Geofavorite item) {
binding.coordsTv.setText(item.getCoordinatesString()); binding.coordsTv.setText(item.getCoordinatesString());
binding.coordsTv.setOnClickListener((v) -> {
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(item.getCoordinatesString(), item.getCoordinatesString());
clipboard.setPrimaryClip(clip);
Toast.makeText(GeofavoriteDetailActivity.this, R.string.coords_copied, Toast.LENGTH_SHORT).show();
});
// Center map // Center map
GeoPoint position = new GeoPoint(item.getLat(), item.getLng()); GeoPoint position = new GeoPoint(item.getLat(), item.getLng());
@ -381,7 +378,7 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple
} }
public void setCategories(HashSet<String> categories) { public void setCategories(HashSet<String> categories) {
((CategoriesAdapter)binding.categoryAt.getAdapter()).setCategoriesList(categories); ((CategoriesSpinnerAdapter)binding.categoryAt.getAdapter()).setCategoriesList(categories);
} }
public void hideAccuracy() { public void hideAccuracy() {
@ -416,6 +413,9 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple
if (v.getId() == R.id.back_bt && this.listener != null) { if (v.getId() == R.id.back_bt && this.listener != null) {
this.listener.onBackPressed(); this.listener.onBackPressed();
} }
if (v.getId() == R.id.manual_pos_bt && this.listener != null) {
this.listener.onMapEditPressed();
}
// Actions // Actions
if (v.getId() == R.id.action_icon_share && this.listener != null) { if (v.getId() == R.id.action_icon_share && this.listener != null) {
@ -434,6 +434,7 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple
void onSubmit(); void onSubmit();
void onMapClicked(); void onMapClicked();
void onBackPressed(); void onBackPressed();
void onMapEditPressed();
void onActionIconShareClicked(); void onActionIconShareClicked();
void onActionIconNavClicked(); void onActionIconNavClicked();
void onActionIconDeleteClicked(); void onActionIconDeleteClicked();

View File

@ -20,8 +20,6 @@ package it.danieleverducci.nextcloudmaps.activity.login;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@ -47,7 +45,6 @@ import it.danieleverducci.nextcloudmaps.api.API;
import it.danieleverducci.nextcloudmaps.api.ApiProvider; import it.danieleverducci.nextcloudmaps.api.ApiProvider;
public class LoginActivity extends NextcloudMapsStyledActivity { public class LoginActivity extends NextcloudMapsStyledActivity {
private static final String TAG = "LoginActivity";
protected ProgressBar progress; protected ProgressBar progress;
protected Button button; protected Button button;
@ -66,25 +63,18 @@ public class LoginActivity extends NextcloudMapsStyledActivity {
openAccountChooser(); openAccountChooser();
}); });
Handler h = new Handler();
h.post(() -> {
try { try {
ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(getApplicationContext()); ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(getApplicationContext());
SingleAccountHelper.applyCurrentAccount(getApplicationContext(), ssoAccount.name); SingleAccountHelper.setCurrentAccount(getApplicationContext(), ssoAccount.name);
accountAccessDone(); accountAccessDone();
} catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) { } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) {
Log.e(TAG, "Autologin: " + e.toString());
} }
});
} }
private void openAccountChooser() { private void openAccountChooser() {
try { try {
AccountImporter.pickNewAccount(this); AccountImporter.pickNewAccount(this);
} catch (NextcloudFilesAppNotInstalledException | AndroidGetAccountsPermissionNotGranted e) { } catch (NextcloudFilesAppNotInstalledException | AndroidGetAccountsPermissionNotGranted e) {
UiExceptionManager.showDialogForException(this, e); UiExceptionManager.showDialogForException(this, e);
Log.e(TAG, "openAccountChooser: " + e.toString());
progress.setVisibility(View.GONE);
} }
} }
@ -108,7 +98,7 @@ public class LoginActivity extends NextcloudMapsStyledActivity {
@Override @Override
public void accountAccessGranted(SingleSignOnAccount account) { public void accountAccessGranted(SingleSignOnAccount account) {
Context l_context = getApplicationContext(); Context l_context = getApplicationContext();
SingleAccountHelper.applyCurrentAccount(l_context, account.name); SingleAccountHelper.setCurrentAccount(l_context, account.name);
accountAccessDone(); accountAccessDone();
} }

View File

@ -28,6 +28,8 @@ import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.PopupMenu; import android.widget.PopupMenu;
import android.widget.TextView; import android.widget.TextView;
@ -40,13 +42,14 @@ import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.FormatStyle; import org.threeten.bp.format.FormatStyle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import it.danieleverducci.nextcloudmaps.R; import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.model.Geofavorite; import it.danieleverducci.nextcloudmaps.model.Geofavorite;
public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.GeofavoriteViewHolder> { public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.GeofavoriteViewHolder> implements Filterable {
public static final String TAG = "GeofavoriteAdapter"; public static final String TAG = "GeofavoriteAdapter";
@ -55,11 +58,12 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
public static final int SORT_BY_CATEGORY = 2; public static final int SORT_BY_CATEGORY = 2;
public static final int SORT_BY_DISTANCE = 3; public static final int SORT_BY_DISTANCE = 3;
private final Context context; private Context context;
private final ItemClickListener itemClickListener; private ItemClickListener itemClickListener;
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT); private DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
private List<Geofavorite> items = new ArrayList<>(); private List<Geofavorite> geofavoriteList = new ArrayList<>();
private List<Geofavorite> geofavoriteListFiltered = new ArrayList<>();
private int sortRule = SORT_BY_CREATED; private int sortRule = SORT_BY_CREATED;
// Contains the position of the element containing the overflow menu clicked // Contains the position of the element containing the overflow menu clicked
@ -71,15 +75,15 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
} }
public void setGeofavoriteList(@NonNull List<Geofavorite> geofavoriteList) { public void setGeofavoriteList(@NonNull List<Geofavorite> geofavoriteList) {
this.items.clear(); this.geofavoriteList = geofavoriteList;
this.items.addAll(geofavoriteList); this.geofavoriteListFiltered = new ArrayList<>(geofavoriteList);
performSort(); performSort();
notifyDataSetChanged(); notifyDataSetChanged();
} }
public Geofavorite get(int position) { public Geofavorite get(int position) {
return items.get(position); return geofavoriteListFiltered.get(position);
} }
public int getSortRule() { public int getSortRule() {
@ -102,7 +106,7 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
@Override @Override
public void onBindViewHolder(@NonNull GeofavoriteViewHolder holder, int position) { public void onBindViewHolder(@NonNull GeofavoriteViewHolder holder, int position) {
Geofavorite geofavorite = items.get(position); Geofavorite geofavorite = geofavoriteListFiltered.get(position);
holder.tv_category.setText(geofavorite.categoryLetter()); holder.tv_category.setText(geofavorite.categoryLetter());
holder.setCategoryColor( holder.setCategoryColor(
@ -114,9 +118,48 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
@Override @Override
public int getItemCount() { public int getItemCount() {
return items.size(); return geofavoriteListFiltered.size();
} }
@Override
public Filter getFilter() {
return filter;
}
Filter filter = new Filter() {
@Override
// Run on Background thread.
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults filterResults = new FilterResults();
List <Geofavorite> filteredGeofavorites = new ArrayList<>();
if (charSequence.toString().isEmpty()) {
filteredGeofavorites.addAll(geofavoriteList);
} else {
for (Geofavorite geofavorite : geofavoriteList) {
String query = charSequence.toString().toLowerCase();
if (geofavorite.getName() != null && geofavorite.getName().toLowerCase().contains(query)) {
filteredGeofavorites.add(geofavorite);
} else if (geofavorite.getComment() != null && geofavorite.getComment().toLowerCase().contains(query)) {
filteredGeofavorites.add(geofavorite);
}
}
}
filterResults.values = filteredGeofavorites;
return filterResults;
}
//Run on ui thread
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
geofavoriteListFiltered.clear();
geofavoriteListFiltered.addAll((Collection<? extends Geofavorite>) filterResults.values);
performSort();
notifyDataSetChanged();
}
};
class GeofavoriteViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { class GeofavoriteViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tv_category, tv_title, tv_content, tv_date; TextView tv_category, tv_title, tv_content, tv_date;
ImageView bt_context_menu; ImageView bt_context_menu;
@ -168,13 +211,13 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
private void performSort() { private void performSort() {
if (sortRule == SORT_BY_TITLE) { if (sortRule == SORT_BY_TITLE) {
Collections.sort(items, Geofavorite.ByTitleAZ); Collections.sort(geofavoriteListFiltered, Geofavorite.ByTitleAZ);
} else if (sortRule == SORT_BY_CREATED) { } else if (sortRule == SORT_BY_CREATED) {
Collections.sort(items, Geofavorite.ByLastCreated); Collections.sort(geofavoriteListFiltered, Geofavorite.ByLastCreated);
} else if (sortRule == SORT_BY_CATEGORY) { } else if (sortRule == SORT_BY_CATEGORY) {
Collections.sort(items, Geofavorite.ByCategory); Collections.sort(geofavoriteListFiltered, Geofavorite.ByCategory);
} else if (sortRule == SORT_BY_DISTANCE) { } else if (sortRule == SORT_BY_DISTANCE) {
Collections.sort(items, Geofavorite.ByDistance); Collections.sort(geofavoriteListFiltered, Geofavorite.ByDistance);
} }
} }

View File

@ -17,25 +17,38 @@
package it.danieleverducci.nextcloudmaps.activity.main; package it.danieleverducci.nextcloudmaps.activity.main;
import android.Manifest; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat; import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.nextcloud.android.sso.helper.SingleAccountHelper; import com.nextcloud.android.sso.helper.SingleAccountHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import it.danieleverducci.nextcloudmaps.R; import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity; import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity;
@ -43,87 +56,124 @@ import it.danieleverducci.nextcloudmaps.activity.about.AboutActivity;
import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity; import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity;
import it.danieleverducci.nextcloudmaps.activity.login.LoginActivity; import it.danieleverducci.nextcloudmaps.activity.login.LoginActivity;
import it.danieleverducci.nextcloudmaps.activity.main.NavigationAdapter.NavigationItem; 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.activity.mappicker.MapPickerActivity;
import it.danieleverducci.nextcloudmaps.api.ApiProvider; import it.danieleverducci.nextcloudmaps.api.ApiProvider;
import it.danieleverducci.nextcloudmaps.fragments.GeofavoriteListFragment; import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.fragments.GeofavoriteMapFragment; import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository; import it.danieleverducci.nextcloudmaps.utils.IntentGenerator;
import it.danieleverducci.nextcloudmaps.utils.SettingsManager;
public class MainActivity extends NextcloudMapsStyledActivity { import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.*;
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_CREATED;
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_TITLE;
import androidx.lifecycle.Observer;
public class MainActivity extends NextcloudMapsStyledActivity implements OnSortingOrderListener {
private static final String TAG = "MainActivity"; private static final String TAG = "MainActivity";
private static final int PERMISSION_REQUEST_CODE = 3890;
private static final String NAVIGATION_KEY_ADD_GEOFAVORITE_FROM_GPS = "add_from_gps"; 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_ADD_GEOFAVORITE_FROM_MAP = "add_from_map";
private static final String NAVIGATION_KEY_SHOW_ABOUT = "about"; private static final String NAVIGATION_KEY_SHOW_ABOUT = "about";
private static final String NAVIGATION_KEY_SWITCH_ACCOUNT = "switch_account"; private static final String NAVIGATION_KEY_SWITCH_ACCOUNT = "switch_account";
private ArrayList<OnGpsPermissionGrantedListener> onGpsPermissionGrantedListener = new ArrayList<>(); private SharedPreferences preferences;
private DrawerLayout drawerLayout; private DrawerLayout drawerLayout;
private Toolbar toolbar;
private MaterialCardView homeToolbar;
private SearchView searchView;
private SwipeRefreshLayout swipeRefresh;
private RecyclerView recyclerView;
private StaggeredGridLayoutManager layoutManager;
private FloatingActionButton fab;
private GeofavoriteAdapter geofavoriteAdapter;
private ItemClickListener rvItemClickListener;
private MainActivityViewModel mMainActivityViewModel;
private boolean isFabOpen = false; private boolean isFabOpen = false;
NavigationAdapter navigationCommonAdapter; NavigationAdapter navigationCommonAdapter;
public void openDrawer() {
drawerLayout.openDrawer(GravityCompat.START);
}
public void showMap() {
replaceFragment(new GeofavoriteMapFragment());
SettingsManager.setGeofavoriteListShownAsMap(this, true);
}
public void showList() {
replaceFragment(new GeofavoriteListFragment());
SettingsManager.setGeofavoriteListShownAsMap(this, false);
}
public void addOnGpsPermissionGrantedListener(OnGpsPermissionGrantedListener l) {
onGpsPermissionGrantedListener.add(l);
}
public void removeOnGpsPermissionGrantedListener(OnGpsPermissionGrantedListener l) {
onGpsPermissionGrantedListener.remove(l);
}
public void requestGpsPermissions() {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_CODE
);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE && permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
for (OnGpsPermissionGrantedListener l : onGpsPermissionGrantedListener) {
l.onGpsPermissionGranted();
}
}
}
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
boolean showMap = SettingsManager.isGeofavoriteListShownAsMap(this); preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
if (showMap)
showMap();
else
showList();
FloatingActionButton fab = findViewById(R.id.open_fab); int sortRule = preferences.getInt(getString(R.string.setting_sort_by), SORT_BY_CREATED);
boolean gridViewEnabled = preferences.getBoolean(getString(R.string.setting_grid_view_enabled), false);
recyclerView = findViewById(R.id.recycler_view);
layoutManager = new StaggeredGridLayoutManager(gridViewEnabled ? 2 : 1, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
rvItemClickListener = new ItemClickListener() {
@Override
public void onItemClick(Geofavorite item) {
showGeofavoriteDetailActivity(item);
}
@Override
public void onItemShareClick(Geofavorite item) {
startActivity(Intent.createChooser(IntentGenerator.newShareIntent(MainActivity.this, item), getString(R.string.share_via)));
}
@Override
public void onItemNavClick(Geofavorite item) {
startActivity(IntentGenerator.newGeoUriIntent(MainActivity.this, item));
}
@Override
public void onItemDeleteClick(Geofavorite item) {
showGeofavoriteDeteleDialog(item);
}
};
geofavoriteAdapter = new GeofavoriteAdapter(this, rvItemClickListener);
recyclerView.setAdapter(geofavoriteAdapter);
geofavoriteAdapter.setSortRule(sortRule);
mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
mMainActivityViewModel.init(getApplicationContext());
mMainActivityViewModel.getIsUpdating().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean aBoolean) {
if(aBoolean){
swipeRefresh.setRefreshing(true);
}
else{
swipeRefresh.setRefreshing(false);
}
}
});
mMainActivityViewModel.getOnFinished().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean success) {
if(success == null || !success){
Toast.makeText(MainActivity.this, R.string.list_geofavorite_connection_error, Toast.LENGTH_LONG).show();
}
}
});
mMainActivityViewModel.getGeofavorites().observe(this, new Observer<List<Geofavorite>>() {
@Override
public void onChanged(List<Geofavorite> geofavorites) {
geofavoriteAdapter.setGeofavoriteList(geofavorites);
}
});
mMainActivityViewModel.updateGeofavorites();
swipeRefresh = findViewById(R.id.swipe_refresh);
swipeRefresh.setOnRefreshListener(() ->
mMainActivityViewModel.updateGeofavorites());
fab = findViewById(R.id.open_fab);
fab.setOnClickListener(view -> openFab(!this.isFabOpen)); fab.setOnClickListener(view -> openFab(!this.isFabOpen));
fab = findViewById(R.id.add_from_gps); fab = findViewById(R.id.add_from_gps);
@ -132,9 +182,51 @@ public class MainActivity extends NextcloudMapsStyledActivity {
fab = findViewById(R.id.add_from_map); fab = findViewById(R.id.add_from_map);
fab.setOnClickListener(view -> addGeofavoriteFromMap()); fab.setOnClickListener(view -> addGeofavoriteFromMap());
toolbar = findViewById(R.id.toolbar);
homeToolbar = findViewById(R.id.home_toolbar);
searchView = findViewById(R.id.search_view);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String query) {
geofavoriteAdapter.getFilter().filter(query);
return false;
}
});
searchView.setOnCloseListener(() -> {
if (toolbar.getVisibility() == VISIBLE && TextUtils.isEmpty(searchView.getQuery())) {
updateToolbars(true);
return true;
}
return false;
});
setSupportActionBar(toolbar);
setupNavigationMenu(); setupNavigationMenu();
homeToolbar.setOnClickListener(view -> updateToolbars(false));
AppCompatImageView sortButton = findViewById(R.id.sort_mode);
sortButton.setOnClickListener(view -> openSortingOrderDialogFragment(getSupportFragmentManager(), geofavoriteAdapter.getSortRule()));
drawerLayout = findViewById(R.id.drawerLayout); drawerLayout = findViewById(R.id.drawerLayout);
AppCompatImageButton menuButton = findViewById(R.id.menu_button);
menuButton.setOnClickListener(view -> drawerLayout.openDrawer(GravityCompat.START));
AppCompatImageView viewButton = findViewById(R.id.view_mode);
viewButton.setOnClickListener(view -> {
boolean gridEnabled = layoutManager.getSpanCount() == 1;
onGridIconChosen(gridEnabled);
});
updateSortingIcon(sortRule);
updateGridIcon(gridViewEnabled);
} }
@Override @Override
@ -143,13 +235,6 @@ public class MainActivity extends NextcloudMapsStyledActivity {
super.onPause(); super.onPause();
} }
private void replaceFragment(Fragment fragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
}
private void setupNavigationMenu() { private void setupNavigationMenu() {
ArrayList<NavigationItem> navItems = new ArrayList<>(); ArrayList<NavigationItem> navItems = new ArrayList<>();
@ -180,6 +265,22 @@ public class MainActivity extends NextcloudMapsStyledActivity {
navigationMenuCommon.setAdapter(navigationCommonAdapter); navigationMenuCommon.setAdapter(navigationCommonAdapter);
} }
private void updateToolbars(boolean disableSearch) {
homeToolbar.setVisibility(disableSearch ? VISIBLE : GONE);
toolbar.setVisibility(disableSearch ? GONE : VISIBLE);
if (disableSearch) {
searchView.setQuery(null, true);
}
searchView.setIconified(disableSearch);
}
private void openSortingOrderDialogFragment(FragmentManager supportFragmentManager, int sortOrder) {
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(null);
SortingOrderDialogFragment.newInstance(sortOrder).show(fragmentTransaction, SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT);
}
private void addGeofavoriteFromGps() { private void addGeofavoriteFromGps() {
startActivity( startActivity(
new Intent(this, GeofavoriteDetailActivity.class) new Intent(this, GeofavoriteDetailActivity.class)
@ -196,15 +297,77 @@ public class MainActivity extends NextcloudMapsStyledActivity {
startActivity(new Intent(this, AboutActivity.class)); startActivity(new Intent(this, AboutActivity.class));
} }
public void switch_account() { private void switch_account() {
ApiProvider.logout(); ApiProvider.logout();
GeofavoriteRepository.resetInstance(); SingleAccountHelper.setCurrentAccount(this, null);
SingleAccountHelper.applyCurrentAccount(this, null);
Intent intent = new Intent(MainActivity.this, LoginActivity.class); Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent); startActivity(intent);
finish(); finish();
} }
@Override
public void onSortingOrderChosen(int sortSelection) {
geofavoriteAdapter.setSortRule(sortSelection);
updateSortingIcon(sortSelection);
preferences.edit().putInt(getString(R.string.setting_sort_by), sortSelection).apply();
}
public void updateSortingIcon(int sortSelection) {
AppCompatImageView sortButton = findViewById(R.id.sort_mode);
switch (sortSelection) {
case SORT_BY_TITLE:
sortButton.setImageResource(R.drawable.ic_alphabetical_asc);
break;
case SORT_BY_CREATED:
sortButton.setImageResource(R.drawable.ic_modification_asc);
break;
case SORT_BY_CATEGORY:
sortButton.setImageResource(R.drawable.ic_category_asc);
break;
case SORT_BY_DISTANCE:
sortButton.setImageResource(R.drawable.ic_distance_asc);
break;
}
}
public void onGridIconChosen(boolean gridEnabled) {
layoutManager.setSpanCount(gridEnabled ? 2 : 1);
updateGridIcon(gridEnabled);
preferences.edit().putBoolean(getString(R.string.setting_grid_view_enabled), gridEnabled).apply();
}
public void updateGridIcon(boolean gridEnabled) {
AppCompatImageView viewButton = findViewById(R.id.view_mode);
viewButton.setImageResource(gridEnabled ? R.drawable.ic_view_list : R.drawable.ic_view_module);
}
private void showGeofavoriteDeteleDialog(Geofavorite item) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage(getString(R.string.dialog_delete_message).replace("{name}", item.getName() != null ? item.getName() : ""))
.setTitle(R.string.dialog_delete_title)
.setPositiveButton(R.string.dialog_delete_delete, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mMainActivityViewModel.deleteGeofavorite(item);
dialog.dismiss();
}
})
.setNegativeButton(R.string.dialog_delete_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog ad = builder.create();
ad.show();
}
private void showGeofavoriteDetailActivity(Geofavorite item) {
Intent i = new Intent(this, GeofavoriteDetailActivity.class);
i.putExtra(GeofavoriteDetailActivity.ARG_GEOFAVORITE, item.getId());
startActivity(i);
}
private void openFab(boolean open) { private void openFab(boolean open) {
View fab = findViewById(R.id.open_fab); View fab = findViewById(R.id.open_fab);
View addFromGpsFab = findViewById(R.id.add_from_gps); View addFromGpsFab = findViewById(R.id.add_from_gps);
@ -224,8 +387,4 @@ public class MainActivity extends NextcloudMapsStyledActivity {
} }
public interface OnGpsPermissionGrantedListener {
public void onGpsPermissionGranted();
}
} }

View File

@ -3,15 +3,15 @@ package it.danieleverducci.nextcloudmaps.activity.main;
import android.content.Context; import android.content.Context;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import java.util.HashSet;
import java.util.List; import java.util.List;
import it.danieleverducci.nextcloudmaps.model.Geofavorite; import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository; import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository;
public class GeofavoritesFragmentViewModel extends ViewModel { public class MainActivityViewModel extends ViewModel {
private GeofavoriteRepository mRepo; private GeofavoriteRepository mRepo;
public void init(Context applicationContext) { public void init(Context applicationContext) {
@ -27,10 +27,6 @@ public class GeofavoritesFragmentViewModel extends ViewModel {
mRepo.updateGeofavorites(); mRepo.updateGeofavorites();
} }
public LiveData<HashSet<String>> getCategories(){
return mRepo.getCategories();
}
public void deleteGeofavorite(Geofavorite geofav) { public void deleteGeofavorite(Geofavorite geofav) {
mRepo.deleteGeofavorite(geofav); mRepo.deleteGeofavorite(geofav);
} }

View File

@ -48,7 +48,6 @@ public class SortingOrderDialogFragment extends DialogFragment {
public static final String SORTING_ORDER_FRAGMENT = "SORTING_ORDER_FRAGMENT"; public static final String SORTING_ORDER_FRAGMENT = "SORTING_ORDER_FRAGMENT";
private static final String KEY_SORT_ORDER = "SORT_ORDER"; private static final String KEY_SORT_ORDER = "SORT_ORDER";
private OnSortingOrderListener onSortingOrderListener;
private View mView; private View mView;
private View[] mTaggedViews; private View[] mTaggedViews;
private Button mCancel; private Button mCancel;
@ -91,10 +90,6 @@ public class SortingOrderDialogFragment extends DialogFragment {
return mView; return mView;
} }
public void setOnSortingOrderListener(OnSortingOrderListener listener) {
this.onSortingOrderListener = listener;
}
/** /**
* find all relevant UI elements and set their values. * find all relevant UI elements and set their values.
* TODO: this is REALLY ugly. * TODO: this is REALLY ugly.
@ -176,8 +171,8 @@ public class SortingOrderDialogFragment extends DialogFragment {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
dismissAllowingStateLoss(); dismissAllowingStateLoss();
if (onSortingOrderListener != null) ((SortingOrderDialogFragment.OnSortingOrderListener) getActivity())
onSortingOrderListener.onSortingOrderChosen((int) v.getTag()); .onSortingOrderChosen((int) v.getTag());
} }
} }

View File

@ -1,153 +0,0 @@
package it.danieleverducci.nextcloudmaps.fragments;
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_CATEGORY;
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_CREATED;
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_DISTANCE;
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_TITLE;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.ArrayList;
import java.util.List;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter;
import it.danieleverducci.nextcloudmaps.activity.main.MainActivity;
import it.danieleverducci.nextcloudmaps.activity.main.SortingOrderDialogFragment;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.utils.GeofavoritesFilter;
import it.danieleverducci.nextcloudmaps.utils.SettingsManager;
public class GeofavoriteListFragment extends GeofavoritesFragment implements SortingOrderDialogFragment.OnSortingOrderListener {
private SwipeRefreshLayout swipeRefresh;
private GeofavoriteAdapter geofavoriteAdapter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_geofavorite_list, container, false);
// Setup list
int sortRule = SettingsManager.getGeofavoriteListSortBy(requireContext());
RecyclerView recyclerView = v.findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(requireContext());
recyclerView.setLayoutManager(layoutManager);
GeofavoriteAdapter.ItemClickListener rvItemClickListener = new GeofavoriteAdapter.ItemClickListener() {
@Override
public void onItemClick(Geofavorite item) {
openGeofavorite(item);
}
@Override
public void onItemShareClick(Geofavorite item) {
shareGeofavorite(item);
}
@Override
public void onItemNavClick(Geofavorite item) {
navigateToGeofavorite(item);
}
@Override
public void onItemDeleteClick(Geofavorite item) {
deleteGeofavorite(item);
}
};
geofavoriteAdapter = new GeofavoriteAdapter(requireContext(), rvItemClickListener);
recyclerView.setAdapter(geofavoriteAdapter);
geofavoriteAdapter.setSortRule(sortRule);
// Register for data source events
mGeofavoritesFragmentViewModel.getIsUpdating().observe(getViewLifecycleOwner(), new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean changed) {
if(Boolean.TRUE.equals(changed)){
swipeRefresh.setRefreshing(true);
}
else{
swipeRefresh.setRefreshing(false);
}
}
});
// Setup view listeners
swipeRefresh = v.findViewById(R.id.swipe_refresh);
swipeRefresh.setOnRefreshListener(() ->
mGeofavoritesFragmentViewModel.updateGeofavorites());
AppCompatImageView sortButton = v.findViewById(R.id.sort_mode);
sortButton.setOnClickListener(view -> openSortingOrderDialogFragment(geofavoriteAdapter.getSortRule()));
View showMapButton = v.findViewById(R.id.view_mode_map);
showMapButton.setOnClickListener(View -> ((MainActivity)requireActivity()).showMap());
return v;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set icons
int sortRule = SettingsManager.getGeofavoriteListSortBy(requireContext());
updateSortingIcon(sortRule);
}
@Override
public void onDatasetChange(List<Geofavorite> items) {
// Called when the items are loaded or a filtering happens
geofavoriteAdapter.setGeofavoriteList(items);
}
@Override
public void onSortingOrderChosen(int sortSelection) {
geofavoriteAdapter.setSortRule(sortSelection);
updateSortingIcon(sortSelection);
SettingsManager.setGeofavoriteListSortBy(requireContext(), sortSelection);
}
private void openSortingOrderDialogFragment(int sortOrder) {
FragmentTransaction fragmentTransaction = requireActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(null);
SortingOrderDialogFragment sodf = SortingOrderDialogFragment.newInstance(sortOrder);
sodf.setOnSortingOrderListener(this);
sodf.show(fragmentTransaction, SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT);
}
private void updateSortingIcon(int sortSelection) {
AppCompatImageView sortButton = requireView().findViewById(R.id.sort_mode);
switch (sortSelection) {
case SORT_BY_TITLE:
sortButton.setImageResource(R.drawable.ic_alphabetical_asc);
break;
case SORT_BY_CREATED:
sortButton.setImageResource(R.drawable.ic_modification_asc);
break;
case SORT_BY_CATEGORY:
sortButton.setImageResource(R.drawable.ic_category_asc);
break;
case SORT_BY_DISTANCE:
sortButton.setImageResource(R.drawable.ic_distance_asc);
break;
}
}
}

View File

@ -1,240 +0,0 @@
package it.danieleverducci.nextcloudmaps.fragments;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.app.ActivityCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.lifecycle.Observer;
import org.osmdroid.api.IMapController;
import org.osmdroid.events.MapEventsReceiver;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.CustomZoomButtonsController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.MapEventsOverlay;
import org.osmdroid.views.overlay.Marker;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.infowindow.InfoWindow;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
import java.util.List;
import java.util.Set;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity;
import it.danieleverducci.nextcloudmaps.activity.main.MainActivity;
import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
import it.danieleverducci.nextcloudmaps.utils.MapUtils;
import it.danieleverducci.nextcloudmaps.utils.SettingsManager;
import it.danieleverducci.nextcloudmaps.views.GeofavMarkerInfoWindow;
public class GeofavoriteMapFragment extends GeofavoritesFragment implements MainActivity.OnGpsPermissionGrantedListener {
private MapView map;
private MyLocationNewOverlay mLocationOverlay;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapUtils.configOsmdroid(requireContext());
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_geofavorite_map, container, false);
// Register listeners
v.findViewById(R.id.center_position).setOnClickListener((cpv) -> moveToUserPosition());
// Setup map
map = v.findViewById(R.id.map);
map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
map.setMultiTouchControls(true);
MapUtils.setTheme(map);
MapEventsOverlay meo = new MapEventsOverlay(new MapEventsReceiver() {
@Override
public boolean singleTapConfirmedHelper(GeoPoint p) {
InfoWindow.closeAllInfoWindowsOn(map);
return false;
}
@Override
public boolean longPressHelper(GeoPoint p) {
// Create new geofavorite (go to geofav creation activity)
Uri geoUri = GeoUriParser.createGeoUri(p.getLatitude(), p.getLongitude(), null);
Intent i = new Intent(requireActivity(), GeofavoriteDetailActivity.class);
i.setData(geoUri);
startActivity(i);
return true;
}
});
map.getOverlays().add(0, meo);
showUserPosition();
// Setup view listeners
View showListButton = v.findViewById(R.id.view_mode_list);
showListButton.setOnClickListener(View -> ((MainActivity)requireActivity()).showList());
View loadingWall = v.findViewById(R.id.loading_wall);
// Register for data source events
mGeofavoritesFragmentViewModel.getIsUpdating().observe(getViewLifecycleOwner(), new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean changed) {
if(Boolean.TRUE.equals(changed)){
loadingWall.setVisibility(View.VISIBLE);
}
else{
loadingWall.setVisibility(View.GONE);
}
}
});
return v;
}
@Override
public void onStart() {
super.onStart();
((MainActivity)requireActivity()).addOnGpsPermissionGrantedListener(this);
}
@Override
public void onDatasetChange(List<Geofavorite> items) {
clearAllMarkers();
for(Geofavorite gf : items)
addMarker(gf);
map.invalidate();
}
@Override
public void onStop() {
super.onStop();
((MainActivity)requireActivity()).removeOnGpsPermissionGrantedListener(this);
SettingsManager.setLastMapPosition(
requireContext(),
map.getMapCenter().getLatitude(),
map.getMapCenter().getLongitude(),
map.getZoomLevelDouble()
);
}
@Override
public void onGpsPermissionGranted() {
showUserPosition();
}
private void showUserPosition() {
// Center map on last position
double[] pos = SettingsManager.getLastMapPosition(requireContext());
IMapController mapController = map.getController();
mapController.setCenter(new GeoPoint(pos[0], pos[1]));
mapController.setZoom(pos[2]);
// Check if user granted location permission
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
) {
// User didn't grant permission. Ask it.
((MainActivity)requireActivity()).requestGpsPermissions();
return;
}
// Display user position on screen
mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(requireContext()), map);
Bitmap personIcon = ((BitmapDrawable)AppCompatResources.getDrawable(requireContext(), R.mipmap.ic_person)).getBitmap();
mLocationOverlay.setPersonIcon(personIcon);
mLocationOverlay.setDirectionIcon(personIcon);
mLocationOverlay.setPersonAnchor(.5f, .5f);
mLocationOverlay.setDirectionAnchor(.5f, .5f);
// On first gps fix, show "center to my position" icon
mLocationOverlay.runOnFirstFix(() -> {
if(getActivity() != null) {
getActivity().runOnUiThread(() -> {
getView().findViewById(R.id.center_position).setVisibility(View.VISIBLE);
});
}
});
mLocationOverlay.enableMyLocation();
map.getOverlays().add(mLocationOverlay);
}
void moveToUserPosition() {
if (mLocationOverlay != null)
map.getController().animateTo(mLocationOverlay.getMyLocation());
}
private void addMarker(Geofavorite geofavorite){
GeoPoint pos = new GeoPoint(geofavorite.getLat(), geofavorite.getLng());
// Set icon and color
Drawable icon = DrawableCompat.wrap(AppCompatResources.getDrawable(requireContext(), R.drawable.ic_map_pin));
DrawableCompat.setTint(icon, geofavorite.categoryColor() == 0 ? requireContext().getColor(R.color.defaultBrand) : geofavorite.categoryColor());
// Set infowindow (popup opened on marker click) and its listeners
GeofavMarkerInfoWindow iw = new GeofavMarkerInfoWindow(map, geofavorite);
iw.setOnGeofavMarkerInfoWindowClickListener(new GeofavMarkerInfoWindow.OnGeofavMarkerInfoWindowClickListener() {
@Override
public void onGeofavMarkerInfoWindowEditClick() {
openGeofavorite(geofavorite);
}
@Override
public void onGeofavMarkerInfoWindowShareClick() {
shareGeofavorite(geofavorite);
}
@Override
public void onGeofavMarkerInfoWindowNavClick() {
navigateToGeofavorite(geofavorite);
}
@Override
public void onGeofavMarkerInfoWindowDeleteClick() {
deleteGeofavorite(geofavorite);
}
});
// Set marker
Marker m = new Marker(map);
m.setPosition(pos);
m.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
m.setIcon(icon);
m.setTitle(geofavorite.getName());
m.setSnippet(geofavorite.getComment());
m.setSubDescription(geofavorite.getCategory());
m.setInfoWindow(iw);
map.getOverlays().add(m);
}
private void clearAllMarkers() {
// Close any open infowindow before removing related marker
InfoWindow.closeAllInfoWindowsOn(map);
// Remove all markers, leaving the other overlays (user position and tap listener ones)
for(Overlay o : map.getOverlays()) {
if (o instanceof Marker) {
map.getOverlays().remove(o);
}
}
}
}

View File

@ -1,270 +0,0 @@
package it.danieleverducci.nextcloudmaps.fragments;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.SearchView;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.nextcloud.android.sso.helper.SingleAccountHelper;
import com.nextcloud.android.sso.model.SingleSignOnAccount;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.detail.CategoriesAdapter;
import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity;
import it.danieleverducci.nextcloudmaps.activity.main.GeofavoritesFragmentViewModel;
import it.danieleverducci.nextcloudmaps.activity.main.MainActivity;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.utils.GeofavoritesFilter;
import it.danieleverducci.nextcloudmaps.utils.IntentGenerator;
/**
* Separates the specific list/map implementation details providing a standard interface
* to communicate with the activity
*/
public abstract class GeofavoritesFragment extends Fragment {
private final String TAG = "GeofavoritesFragment";
protected GeofavoritesFragmentViewModel mGeofavoritesFragmentViewModel;
private View toolbar;
private View homeToolbar;
private SearchView searchView;
private ImageButton filterButton;
private List<Geofavorite> geofavorites = new ArrayList<>();
private HashSet<String> categories = new HashSet<>();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load data
mGeofavoritesFragmentViewModel = new ViewModelProvider(this).get(GeofavoritesFragmentViewModel.class);
mGeofavoritesFragmentViewModel.init(requireContext());
mGeofavoritesFragmentViewModel.getOnFinished().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean success) {
if(success == null || !success){
Toast.makeText(requireContext(), R.string.list_geofavorite_connection_error, Toast.LENGTH_LONG).show();
}
}
});
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set views
AppCompatImageButton menuButton = view.findViewById(R.id.menu_button);
menuButton.setOnClickListener(v -> ((MainActivity)requireActivity()).openDrawer());
View userBadgeContainer = view.findViewById(R.id.user_badge_container);
userBadgeContainer.setOnClickListener(v -> showSwitchAccountDialog());
// Setup toolbar/searchbar
toolbar = view.findViewById(R.id.toolbar);
homeToolbar = view.findViewById(R.id.home_toolbar);
filterButton = view.findViewById(R.id.search_filter);
filterButton.setOnClickListener(v -> showCategoryFilterDialog());
searchView = view.findViewById(R.id.search_view);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String query) {
onDatasetChange(
(new GeofavoritesFilter(geofavorites)).byText(query)
);
return false;
}
});
mGeofavoritesFragmentViewModel.getGeofavorites().observe(getViewLifecycleOwner(), new Observer<List<Geofavorite>>() {
@Override
public void onChanged(List<Geofavorite> geofavorites) {
GeofavoritesFragment.this.geofavorites = geofavorites;
onDatasetChange(geofavorites);
}
});
mGeofavoritesFragmentViewModel.getCategories().observe(getViewLifecycleOwner(), new Observer<HashSet<String>>() {
@Override
public void onChanged(HashSet<String> categories) {
GeofavoritesFragment.this.categories = categories;
}
});
searchView.setOnCloseListener(() -> {
if (toolbar.getVisibility() == VISIBLE && TextUtils.isEmpty(searchView.getQuery())) {
updateToolbars(true);
return true;
}
return false;
});
homeToolbar.setOnClickListener(v -> updateToolbars(false));
// Set user badge (async)
Handler h = new Handler();
h.post(() -> {
try {
SingleSignOnAccount ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(requireContext());
String userBadgePath = ssoAccount.url + "/index.php/avatar/" + ssoAccount.userId + "/64";
if (getActivity() != null)
getActivity().runOnUiThread(
() -> Picasso.get().load(userBadgePath).into((AppCompatImageView)userBadgeContainer.findViewById(R.id.user_badge))
);
} catch (Exception e) {
Log.e(TAG, "Unable to load user image: " + e.toString());
}
});
}
@Override
public void onStart() {
super.onStart();
// Reset filter and update data
filterButton.setImageResource(R.drawable.ic_filter_off);
mGeofavoritesFragmentViewModel.updateGeofavorites();
}
abstract public void onDatasetChange(List<Geofavorite> items);
protected void openGeofavorite(Geofavorite item) {
showGeofavoriteDetailActivity(item);
}
protected void shareGeofavorite(Geofavorite item) {
startActivity(Intent.createChooser(IntentGenerator.newShareIntent(requireActivity(), item), getString(R.string.share_via)));
}
protected void navigateToGeofavorite(Geofavorite item) {
startActivity(IntentGenerator.newGeoUriIntent(requireActivity(), item));
}
protected void deleteGeofavorite(Geofavorite item) {
showGeofavoriteDeteleDialog(item);
}
private void showGeofavoriteDetailActivity(Geofavorite item) {
Intent i = new Intent(requireContext(), GeofavoriteDetailActivity.class);
i.putExtra(GeofavoriteDetailActivity.ARG_GEOFAVORITE, item.getId());
startActivity(i);
}
private void showGeofavoriteDeteleDialog(Geofavorite item) {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setMessage(getString(R.string.dialog_delete_message).replace("{name}", item.getName() != null ? item.getName() : ""))
.setTitle(R.string.dialog_delete_title)
.setPositiveButton(R.string.dialog_delete_delete, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mGeofavoritesFragmentViewModel.deleteGeofavorite(item);
dialog.dismiss();
}
})
.setNegativeButton(R.string.dialog_delete_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog ad = builder.create();
ad.show();
}
private void showSwitchAccountDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setMessage(R.string.dialog_logout_message)
.setTitle(R.string.dialog_logout_title)
.setPositiveButton(android.R.string.yes, (dialog, id) -> {
if (getActivity() != null)
((MainActivity) getActivity()).switch_account();
dialog.dismiss();
})
.setNegativeButton(android.R.string.no, (dialog, id) -> dialog.dismiss());
AlertDialog ad = builder.create();
ad.show();
}
private void showCategoryFilterDialog() {
if (categories.isEmpty()) {
Toast.makeText(requireContext(), R.string.filtering_unavailable, Toast.LENGTH_SHORT).show();
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setTitle(R.string.filtering_dialog_title);
CategoriesAdapter ca = new CategoriesAdapter(requireContext());
ca.setCategoriesList(categories);
builder.setAdapter(ca, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Set filter button enabled icon and color
String categoryName = ca.getItem(which);
filterButton.setImageResource(R.drawable.ic_filter);
Drawable d = filterButton.getDrawable();
DrawableCompat.setTint(
d,
Geofavorite.categoryColorFromName(categoryName) == 0
? requireContext().getColor(R.color.defaultBrand)
: Geofavorite.categoryColorFromName(categoryName)
);
filterByCategory(categoryName);
}
});
builder.setPositiveButton(R.string.filtering_dialog_cancel, (dialog, id) -> {
dialog.dismiss();
filterButton.setImageResource(R.drawable.ic_filter_off);
filterByCategory(null);
});
AlertDialog dialog = builder.create();
dialog.show();
}
private void updateToolbars(boolean disableSearch) {
homeToolbar.setVisibility(disableSearch ? VISIBLE : GONE);
toolbar.setVisibility(disableSearch ? GONE : VISIBLE);
if (disableSearch) {
searchView.setQuery(null, true);
}
searchView.setIconified(disableSearch);
}
private void filterByCategory(String category) {
onDatasetChange(
(new GeofavoritesFilter(geofavorites)).byCategory(category)
);
}
}

View File

@ -22,7 +22,6 @@ package it.danieleverducci.nextcloudmaps.model;
import android.graphics.Color; import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
import android.widget.Filter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -35,9 +34,7 @@ import org.threeten.bp.LocalDate;
import org.threeten.bp.ZoneId; import org.threeten.bp.ZoneId;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.List;
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser; import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
@ -204,7 +201,17 @@ public class Geofavorite implements Serializable {
* @return the generated color or null for the default category * @return the generated color or null for the default category
*/ */
public int categoryColor() { public int categoryColor() {
return categoryColorFromName(this.category); // If category is default, return null: will be used Nextcloud's accent
if (this.category == null || this.category.equals(DEFAULT_CATEGORY) || this.category.length() == 0)
return 0;
float letter1Index = this.category.toLowerCase().charAt(0);
float letter2Index = this.category.toLowerCase().charAt(1);
float letterCoef = ((letter1Index * letter2Index) % 100) / 100;
float h = letterCoef * 360;
float s = 75 + letterCoef * 10;
float l = 50 + letterCoef * 10;
return Color.HSVToColor( new float[]{ Math.round(h), Math.round(s), Math.round(l) });
} }
public String categoryLetter() { public String categoryLetter() {
@ -219,27 +226,4 @@ public class Geofavorite implements Serializable {
return "[" + getName() + " (" + getLat() + "," + getLng() + ")]"; return "[" + getName() + " (" + getLat() + "," + getLng() + ")]";
} }
/**
* Based on Nextcloud Maps's getLetterColor util.
* Assigns a color to a category based on its two first letters.
*
* @see "https://github.com/nextcloud/maps/blob/master/src/utils.js"
* @return the generated color or null for the default category
*/
public static int categoryColorFromName(String category) {
// If category is default, return null: will be used Nextcloud's accent
if (category == null || category.equals(DEFAULT_CATEGORY) || category.length() == 0)
return 0;
float letter1Index = category.toLowerCase().charAt(0);
float letter2Index = category.toLowerCase().charAt(1);
float letterCoef = ((letter1Index * letter2Index) % 100) / 100;
float h = letterCoef * 360;
float s = 75 + letterCoef * 10;
float l = 50 + letterCoef * 10;
return Color.HSVToColor( new float[]{ Math.round(h), Math.round(s), Math.round(l) });
}
} }

View File

@ -42,10 +42,6 @@ public class GeofavoriteRepository {
return instance; return instance;
} }
public static void resetInstance() {
instance = null;
}
public MutableLiveData<List<Geofavorite>> getGeofavorites(){ public MutableLiveData<List<Geofavorite>> getGeofavorites(){
if (mGeofavorites == null) { if (mGeofavorites == null) {
mGeofavorites = new MutableLiveData<>(); mGeofavorites = new MutableLiveData<>();

View File

@ -1,47 +0,0 @@
package it.danieleverducci.nextcloudmaps.utils;
import java.util.ArrayList;
import java.util.List;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
public class GeofavoritesFilter {
List<Geofavorite> items;
public GeofavoritesFilter(List<Geofavorite> items) {
this.items = items;
}
public List<Geofavorite> byText(String text) {
List<Geofavorite> filteredGeofavorites = new ArrayList<>();
if (text.isEmpty()) {
return items;
} else {
for (Geofavorite geofavorite : items) {
String query = text.toLowerCase();
if (geofavorite.getName() != null && geofavorite.getName().toLowerCase().contains(query)) {
filteredGeofavorites.add(geofavorite);
} else if (geofavorite.getComment() != null && geofavorite.getComment().toLowerCase().contains(query)) {
filteredGeofavorites.add(geofavorite);
}
}
}
return filteredGeofavorites;
}
public List<Geofavorite> byCategory(String category) {
List<Geofavorite> filteredGeofavorites = new ArrayList<>();
if (category == null) {
return items;
} else {
for (Geofavorite geofavorite : items) {
if (geofavorite.getCategory().equals(category)) {
filteredGeofavorites.add(geofavorite);
}
}
}
return filteredGeofavorites;
}
}

View File

@ -14,7 +14,6 @@ public class IntentGenerator {
i.setAction(Intent.ACTION_SEND); i.setAction(Intent.ACTION_SEND);
i.setType("text/plain"); i.setType("text/plain");
String shareMessage = context.getString(R.string.share_message) String shareMessage = context.getString(R.string.share_message)
.replace("{title}", item.getName() == null ? context.getString(R.string.share_message_default_title) : item.getName())
.replace("{lat}", ""+item.getLat()) .replace("{lat}", ""+item.getLat())
.replace("{lng}", ""+item.getLng()); .replace("{lng}", ""+item.getLng());
i.putExtra(Intent.EXTRA_TEXT, shareMessage ); i.putExtra(Intent.EXTRA_TEXT, shareMessage );

View File

@ -1,57 +0,0 @@
package it.danieleverducci.nextcloudmaps.utils;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
import it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter;
public class SettingsManager {
static private final String SETTING_SORT_BY = "SETTING_SORT_BY";
static private final String SETTING_LAST_SELECTED_LIST_VIEW = "SETTING_LAST_SELECTED_LIST_VIEW";
static private final String SETTING_LAST_MAP_POSITION_LAT = "SETTING_LAST_MAP_POSITION_LAT";
static private final String SETTING_LAST_MAP_POSITION_LNG = "SETTING_LAST_MAP_POSITION_LNG";
static private final String SETTING_LAST_MAP_POSITION_ZOOM = "SETTING_LAST_MAP_POSITION_ZOOM";
public static int getGeofavoriteListSortBy(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getInt(SETTING_SORT_BY, GeofavoriteAdapter.SORT_BY_CREATED);
}
public static void setGeofavoriteListSortBy(Context context, int value) {
PreferenceManager.getDefaultSharedPreferences(context)
.edit().putInt(SETTING_SORT_BY, value).apply();
}
public static boolean isGeofavoriteListShownAsMap(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(SETTING_LAST_SELECTED_LIST_VIEW, false);
}
public static void setGeofavoriteListShownAsMap(Context context, boolean value) {
PreferenceManager.getDefaultSharedPreferences(context)
.edit().putBoolean(SETTING_LAST_SELECTED_LIST_VIEW, value).apply();
}
/**
* Returns the last saved position
* @param context
* @return double[lat,lng,zoom]
*/
public static double[] getLastMapPosition(Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
return new double[] {
(double) sp.getFloat(SETTING_LAST_MAP_POSITION_LAT, 0.0f),
(double) sp.getFloat(SETTING_LAST_MAP_POSITION_LNG, 0.0f),
(double) sp.getFloat(SETTING_LAST_MAP_POSITION_ZOOM, 10.0f),
};
}
public static void setLastMapPosition(Context context, double lat, double lng, double zoom) {
PreferenceManager.getDefaultSharedPreferences(context).edit()
.putFloat(SETTING_LAST_MAP_POSITION_LAT, (float)lat)
.putFloat(SETTING_LAST_MAP_POSITION_LNG, (float)lng)
.putFloat(SETTING_LAST_MAP_POSITION_ZOOM, (float)zoom)
.apply();
}
}

View File

@ -1,72 +0,0 @@
package it.danieleverducci.nextcloudmaps.views;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.graphics.drawable.DrawableCompat;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.infowindow.InfoWindow;
import org.osmdroid.views.overlay.infowindow.MarkerInfoWindow;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
public class GeofavMarkerInfoWindow extends MarkerInfoWindow implements View.OnClickListener {
private OnGeofavMarkerInfoWindowClickListener onGeofavMarkerInfoWindowClickListener;
public GeofavMarkerInfoWindow(MapView mapView, Geofavorite geofavorite) {
super(R.layout.infowindow_geofav, mapView);
Context context = getView().getContext();
// Set category color
View category = getView().findViewById(R.id.bubble_subdescription);
Drawable backgroundDrawable = category.getBackground();
DrawableCompat.setTint(backgroundDrawable, geofavorite.categoryColor() == 0 ? context.getColor(R.color.defaultBrand) : geofavorite.categoryColor());
// Set listeners
getView().findViewById(R.id.action_icon_share).setOnClickListener(this);
getView().findViewById(R.id.action_icon_nav).setOnClickListener(this);
getView().findViewById(R.id.action_icon_delete).setOnClickListener(this);
getView().findViewById(R.id.action_icon_edit).setOnClickListener(this);
}
public void setOnGeofavMarkerInfoWindowClickListener(OnGeofavMarkerInfoWindowClickListener l) {
this.onGeofavMarkerInfoWindowClickListener = l;
}
@Override
public void onOpen(Object item) {
InfoWindow.closeAllInfoWindowsOn(getMapView());
super.onOpen(item);
}
@Override
public void onClick(View v) {
if (onGeofavMarkerInfoWindowClickListener == null)
return;
if (v.getId() == R.id.action_icon_share)
onGeofavMarkerInfoWindowClickListener.onGeofavMarkerInfoWindowShareClick();
if (v.getId() == R.id.action_icon_nav)
onGeofavMarkerInfoWindowClickListener.onGeofavMarkerInfoWindowNavClick();
if (v.getId() == R.id.action_icon_delete)
onGeofavMarkerInfoWindowClickListener.onGeofavMarkerInfoWindowDeleteClick();
if (v.getId() == R.id.action_icon_edit)
onGeofavMarkerInfoWindowClickListener.onGeofavMarkerInfoWindowEditClick();
}
public interface OnGeofavMarkerInfoWindowClickListener {
public void onGeofavMarkerInfoWindowEditClick();
public void onGeofavMarkerInfoWindowShareClick();
public void onGeofavMarkerInfoWindowNavClick();
public void onGeofavMarkerInfoWindowDeleteClick();
}
}

View File

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

View File

@ -1,13 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="209.21dp"
android:height="45.14dp"
android:viewportWidth="209.21"
android:viewportHeight="45.14">
<path
android:pathData="m204.31,0.14c-0.97,0.02 -2.1,0.07 -3.3,0.15l8.18,-0.01c0,0 -1.81,-0.2 -4.89,-0.14zM201.01,0.29 L0.02,0.46c0,0 32.67,5.29 57.83,17.7 25.15,12.42 45.33,26.81 45.33,26.81 0,0 18.75,-13.75 38.46,-26.28 20.46,-13 49.14,-17.73 59.37,-18.41z"
android:strokeLineJoin="miter"
android:strokeWidth="0.264583"
android:fillColor="#000000"
android:strokeColor="#00000000"
android:strokeLineCap="butt"/>
</vector>

View File

@ -3,7 +3,7 @@
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal"> android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" 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"/> 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"/>

View File

@ -3,7 +3,7 @@
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal"> android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" 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"/> 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"/>

View File

@ -3,7 +3,7 @@
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal"> android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M12,2l-5.5,9h11z"/> android:pathData="M12,2l-5.5,9h11z"/>

View File

@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#000000"
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="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View File

@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#000000"
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="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
</vector>

View File

@ -3,7 +3,7 @@
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal"> android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M21,3L3,10.53v0.98l6.84,2.65L12.48,21h0.98L21,3z"/> android:pathData="M21,3L3,10.53v0.98l6.84,2.65L12.48,21h0.98L21,3z"/>

View File

@ -1,5 +0,0 @@
<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="M4.25,5.61C6.27,8.2 10,13 10,13v6c0,0.55 0.45,1 1,1h2c0.55,0 1,-0.45 1,-1v-6c0,0 3.72,-4.8 5.74,-7.39C20.25,4.95 19.78,4 18.95,4H5.04C4.21,4 3.74,4.95 4.25,5.61z"/>
</vector>

View File

@ -1,6 +0,0 @@
<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="M19.79,5.61C20.3,4.95 19.83,4 19,4H6.83l7.97,7.97L19.79,5.61z"/>
<path android:fillColor="@android:color/white" android:pathData="M2.81,2.81L1.39,4.22L10,13v6c0,0.55 0.45,1 1,1h2c0.55,0 1,-0.45 1,-1v-2.17l5.78,5.78l1.41,-1.41L2.81,2.81z"/>
</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

@ -3,7 +3,7 @@
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal"> android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/> android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>

View File

@ -1,5 +0,0 @@
<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,25 @@
<!--
~ 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/>.
-->
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#FFFFFF"
android:pathData="M16,5V11H21V5M10,11H15V5H10M16,18H21V12H16M10,18H15V12H10M4,18H9V12H4M4,11H9V5H4V11Z" />
</vector>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/defaultBackground"/>
<stroke android:width="7dp" android:color="@color/defaultBrand" />
<corners android:radius="20dp"/>
</shape>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#000" />
<padding android:left="10dp" android:top="3dp" android:right="10dp" android:bottom="3dp" />
<corners android:radius="20dp" />
</shape>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="oval">
<solid android:color="@color/translucent"/>
</shape>
</item>
</layer-list>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="oval"
android:useLevel="false">
<solid android:color="@android:color/transparent" />
<stroke
android:width="10dp"
android:color="@color/toolbar_background" />
</shape>
</item>
</layer-list>

View File

@ -32,7 +32,7 @@
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize" android:layout_height="?attr/actionBarSize"
app:contentInsetStartWithNavigation="0dp" app:contentInsetStartWithNavigation="0dp"
app:navigationIcon="@drawable/ic_back_grey" app:navigationIcon="@drawable/ic_back_grey"
app:titleMarginStart="0dp"/> app:titleMarginStart="0dp"/>

View File

@ -43,7 +43,7 @@
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize" android:layout_height="?attr/actionBarSize"
app:contentInsetStart="0dp" app:contentInsetStart="0dp"
app:layout_collapseMode="pin" app:layout_collapseMode="pin"
android:background="@android:color/transparent"> android:background="@android:color/transparent">
@ -51,26 +51,25 @@
<!-- Back button --> <!-- Back button -->
<ImageView <ImageView
android:id="@+id/back_bt" android:id="@+id/back_bt"
android:layout_width="40dp" android:layout_width="?attr/actionBarSize"
android:layout_height="40dp" android:layout_height="?attr/actionBarSize"
android:layout_gravity="start" android:layout_gravity="start"
android:layout_margin="8dp" android:padding="16dp"
android:padding="8dp"
android:src="@drawable/ic_back_grey" android:src="@drawable/ic_back_grey"
app:tint="@color/white" app:tint="@color/white"
android:background="@drawable/floating_semitransparent_button_background"/> android:background="@drawable/floating_semitransparent_button_background"/>
<!-- Save button --> <!-- Manual position button -->
<ImageView <ImageView
android:id="@+id/submit_bt" android:id="@+id/manual_pos_bt"
android:layout_width="40dp" android:layout_width="?attr/actionBarSize"
android:layout_height="40dp" android:layout_height="?attr/actionBarSize"
android:layout_gravity="end" android:layout_gravity="end"
android:layout_margin="8dp" android:padding="16dp"
android:padding="8dp" android:src="@drawable/ic_manual_pos"
android:src="@drawable/ic_ok"
app:tint="@color/white" app:tint="@color/white"
android:background="@drawable/round_button_background"/> android:background="@drawable/floating_semitransparent_button_background"
android:visibility="gone"/> <!-- TODO: Implement edit -->
</androidx.appcompat.widget.Toolbar> </androidx.appcompat.widget.Toolbar>
@ -198,40 +197,20 @@
android:drawableTint="@color/defaultBrand" android:drawableTint="@color/defaultBrand"
android:hint="@string/description"/> android:hint="@string/description"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp">
<AutoCompleteTextView <AutoCompleteTextView
android:id="@+id/category_at" android:id="@+id/category_at"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_marginTop="20dp"
android:maxLines="1" android:ems="10"
android:gravity="start|top"
android:inputType="textMultiLine"
android:maxLines="10"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:drawableLeft="@drawable/ic_category_asc" android:drawableLeft="@drawable/ic_category_asc"
android:drawablePadding="5dp" android:drawablePadding="5dp"
android:drawableTint="@color/defaultBrand" android:drawableTint="@color/defaultBrand"
android:hint="@string/category" android:hint="@string/category"/>
android:completionThreshold="0"/>
<ImageButton
android:id="@+id/category_at_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:background="@color/transparent"
android:src="@drawable/ic_clear"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/category_hint"
android:textSize="12sp"/>
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -270,9 +249,7 @@
android:id="@+id/coords_tv" android:id="@+id/coords_tv"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAlignment="textEnd" android:textAlignment="textEnd" />
app:drawableEndCompat="@drawable/ic_copy"
android:drawablePadding="10sp"/>
<ProgressBar <ProgressBar
android:id="@+id/progress" android:id="@+id/progress"
@ -281,6 +258,16 @@
android:indeterminate="true" android:indeterminate="true"
android:visibility="gone"/> android:visibility="gone"/>
<Button
android:id="@+id/submit_bt"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="50dp"
android:text="@string/confirm"
app:backgroundTint="@color/defaultBrand"
android:onClick="onSubmit"/>
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>

View File

@ -15,34 +15,160 @@
~ You should have received a copy of the GNU General Public License ~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<FrameLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_list_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView <com.google.android.material.appbar.AppBarLayout
android:id="@+id/fragment_container" android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:elevation="0dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:toolbarId="@+id/toolbar" >
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="it.danieleverducci.nextcloudmaps.fragments.GeofavoriteListFragment" android:visibility="visible"
tools:layout="@layout/fragment_geofavorite_list" /> app:contentInsetStartWithNavigation="0dp"
app:titleMarginStart="0dp"
tools:title="@string/app_name">
<androidx.appcompat.widget.SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.appcompat.widget.SearchView>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.card.MaterialCardView
android:id="@+id/home_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacer_2x"
android:layout_marginTop="@dimen/spacer_1hx"
android:layout_marginEnd="@dimen/spacer_2x"
android:layout_marginBottom="@dimen/spacer_1hx"
app:cardCornerRadius="@dimen/spacer_1x"
app:cardElevation="2dp"
app:strokeWidth="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/menu_button"
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="@color/text_color"
android:src="@drawable/ic_menu_grey"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/search_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/spacer_1x"
android:layout_marginEnd="@dimen/spacer_1x"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="start"
android:lines="1"
android:textSize="16sp"
android:text="@string/search_in_all"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/sort_mode"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="center_vertical|end"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/list_mode"
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
android:id="@+id/view_mode"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="center_vertical|end"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/list_mode"
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:visibility="gone"/> <!-- TODO: Replace with Map View icon -->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/spacer_1hx"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
app:spanCount="1"
tools:itemCount="3"
tools:listitem="@layout/item_geofav">
</androidx.recyclerview.widget.RecyclerView>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<!-- Add from map FAB --> <!-- Add from map FAB -->
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_from_map" android:id="@+id/add_from_map"
android:layout_margin="24dp"
android:layout_gravity="bottom|end"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="24dp"
android:src="@drawable/ic_add_map"
app:backgroundTint="@color/defaultBrand"
app:fabSize="mini" app:fabSize="mini"
app:tint="@color/white" android:src="@drawable/ic_add_map"
tools:ignore="DuplicateClickableBoundsCheck" app:backgroundTint="@color/defaultBrand"/>
android:contentDescription="@string/add_from_map" />
<!-- Add from current position FAB --> <!-- Add from current position FAB -->
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
@ -53,9 +179,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:fabSize="mini" app:fabSize="mini"
android:src="@drawable/ic_add_gps" android:src="@drawable/ic_add_gps"
app:backgroundTint="@color/defaultBrand" app:backgroundTint="@color/defaultBrand"/>
app:tint="@color/white"
android:contentDescription="@string/add_from_gps"/>
<!-- Main FAB --> <!-- Main FAB -->
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
@ -65,8 +189,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/ic_add" android:src="@drawable/ic_add"
app:backgroundTint="@color/defaultBrand" app:backgroundTint="@color/defaultBrand"/>
app:tint="@color/white"
android:contentDescription="@string/open_fab"/>
</FrameLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -42,7 +42,7 @@
android:id="@+id/scrollView" android:id="@+id/scrollView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?android:attr/colorPrimary"> android:background="?attr/colorPrimary">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -68,11 +68,9 @@
android:id="@+id/app_name" android:id="@+id/app_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_toEndOf="@id/logo" android:layout_toEndOf="@id/logo"
android:ellipsize="end" android:ellipsize="end"
android:lines="2"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:gravity="center_vertical" android:gravity="center_vertical"
android:text="@string/app_name" android:text="@string/app_name"

View File

@ -16,30 +16,27 @@
android:layout_height="48dp" android:layout_height="48dp"
android:layout_marginBottom="24dp" android:layout_marginBottom="24dp"
android:layout_gravity="center" android:layout_gravity="center"
android:src="@drawable/ic_map_pin" android:src="@drawable/ic_map_pin"/>
app:tint="@color/defaultBrand"/>
<ImageView <ImageView
android:id="@+id/back_bt" android:id="@+id/back_bt"
android:layout_width="?android:attr/actionBarSize" android:layout_width="?attr/actionBarSize"
android:layout_height="?android:attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:layout_margin="16dp"
android:layout_gravity="start" android:layout_gravity="start"
android:padding="16dp" android:padding="16dp"
android:src="@drawable/ic_back_grey" android:src="@drawable/ic_back_grey"
app:tint="@color/text_color" app:tint="@color/white"
android:background="@drawable/unselected_floating_semitransparent_button_background"/> android:background="@drawable/floating_semitransparent_button_background"/>
<ImageView <ImageView
android:id="@+id/ok_bt" android:id="@+id/ok_bt"
android:layout_width="?android:attr/actionBarSize" android:layout_width="?attr/actionBarSize"
android:layout_height="?android:attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:layout_margin="16dp"
android:layout_gravity="end" android:layout_gravity="end"
android:padding="16dp" android:padding="16dp"
android:src="@drawable/ic_ok" android:src="@drawable/ic_ok"
app:tint="@color/white" app:tint="@color/white"
android:background="@drawable/round_button_background"/> android:background="@drawable/floating_semitransparent_button_background"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1,102 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
app:contentInsetStartWithNavigation="0dp"
app:titleMarginStart="0dp"
tools:title="@string/app_name">
<androidx.appcompat.widget.SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:background="@color/translucent">
</androidx.appcompat.widget.SearchView>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.card.MaterialCardView
android:id="@+id/home_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacer_2x"
android:layout_marginTop="@dimen/spacer_1hx"
android:layout_marginEnd="@dimen/spacer_2x"
android:layout_marginBottom="@dimen/spacer_1hx"
app:cardBackgroundColor="@color/toolbar_background"
app:cardCornerRadius="30dp"
app:cardElevation="2dp"
app:strokeWidth="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/menu_button"
android:layout_width="?android:attr/actionBarSize"
android:layout_height="?android:attr/actionBarSize"
android:background="?android: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="@color/text_color"
android:src="@drawable/ic_menu_grey"
android:contentDescription="@string/menu"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/search_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/spacer_1x"
android:layout_marginEnd="@dimen/spacer_1x"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="start"
android:lines="1"
android:textSize="16sp"
android:text="@string/search_in_all"/>
<!-- Filter button -->
<ImageButton
android:id="@+id/search_filter"
android:layout_width="?android:attr/actionBarSize"
android:layout_height="?android:attr/actionBarSize"
android:src="@drawable/ic_filter_off"
app:tint="@color/inactive"
android:background="@color/transparent"/>
<!-- User badge -->
<FrameLayout
android:id="@+id/user_badge_container"
android:layout_width="?android:attr/actionBarSize"
android:layout_height="?android:attr/actionBarSize">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/user_badge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/user_badge_mask"/>
</FrameLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</FrameLayout>

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<TextView
android:id="@+id/category_name"
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center_vertical"
android:lines="1"
android:ellipsize="end"
android:text="Lorem ipsum"
app:drawableLeftCompat="@drawable/ic_category_asc"
android:drawablePadding="8sp"
android:drawableTint="@color/white"
android:textColor="@color/white"
android:textStyle="bold"
android:background="@drawable/rounded_label_background"/>
</FrameLayout>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?android:attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:toolbarId="@+id/toolbar" >
<include layout="@layout/app_toolbar"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="?android:attr/actionBarSize"
android:paddingTop="20dp"
android:paddingStart="5dp"
android:paddingEnd="5dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/sort_mode"
android:layout_width="wrap_content"
android:layout_height="@dimen/floating_bar_height"
android:layout_alignParentLeft="true"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/list_mode"
android:paddingStart="@dimen/spacer_2x"
android:paddingEnd="@dimen/spacer_2x"
android:tint="@color/text_color"
android:src="@drawable/ic_alphabetical_asc" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/view_mode_map"
android:layout_width="wrap_content"
android:layout_height="@dimen/floating_bar_height"
android:layout_alignParentRight="true"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/list_mode"
android:paddingStart="@dimen/spacer_2x"
android:paddingEnd="@dimen/spacer_2x"
android:tint="@color/text_color"
android:src="@drawable/ic_view_map" />
</RelativeLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
app:spanCount="1"
tools:itemCount="3"
tools:listitem="@layout/item_geofav">
</androidx.recyclerview.widget.RecyclerView>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,69 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_list_view"
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"/>
<FrameLayout
android:id="@+id/loading_wall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/translucent"
android:visibility="gone">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_gravity="center"/>
</FrameLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:orientation="vertical">
<include layout="@layout/app_toolbar"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/view_mode_list"
android:layout_width="@dimen/floating_bar_height"
android:layout_height="@dimen/floating_bar_height"
android:layout_marginTop="2dp"
android:layout_marginEnd="@dimen/spacer_2x"
android:layout_gravity="right"
android:background="@drawable/unselected_floating_semitransparent_button_background"
android:contentDescription="@string/list_mode"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:tint="@color/text_color"
android:src="@drawable/ic_view_list" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/center_position"
android:layout_width="@dimen/floating_bar_height"
android:layout_height="@dimen/floating_bar_height"
android:layout_marginRight="100dp"
android:layout_marginBottom="25dp"
android:layout_gravity="bottom|right"
android:background="@drawable/unselected_floating_semitransparent_button_background"
android:padding="5dp"
android:tint="@color/text_color"
android:src="@drawable/ic_add_gps"
android:visibility="gone"/>
</FrameLayout>

View File

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="250dp"
android:background="@drawable/infowindow_geofav_background"
android:padding="7dp"
android:orientation="vertical">
<!-- Geofavorite title -->
<TextView
android:id="@+id/bubble_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/defaultBrand"
android:padding="10dp"
android:lines="1"
android:ellipsize="end"
style="@style/TextAppearance.GeofavoriteInfowindow"
android:text="Lorem"/>
<!-- Geofavorite description -->
<TextView
android:id="@+id/bubble_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="Lorem ipsum"/>
<!-- Geofavorite category -->
<TextView
android:id="@+id/bubble_subdescription"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:gravity="center_vertical"
android:lines="1"
android:ellipsize="end"
android:text="Lorem ipsum"
app:drawableLeftCompat="@drawable/ic_category_asc"
android:drawablePadding="8sp"
android:drawableTint="@color/white"
android:textColor="@color/white"
android:textStyle="bold"
android:background="@drawable/rounded_label_background"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/action_icon_share"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:src="@drawable/ic_share"
app:tint="@color/defaultBrand"/>
<ImageView
android:id="@+id/action_icon_nav"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:src="@drawable/ic_nav"
app:tint="@color/defaultBrand"/>
<ImageView
android:id="@+id/action_icon_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:src="@drawable/ic_delete_grey"
app:tint="@color/defaultBrand"/>
<ImageView
android:id="@+id/action_icon_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:src="@drawable/ic_edit"
app:tint="@color/defaultBrand"/>
</LinearLayout>
<ImageView
android:id="@+id/bubble_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
</LinearLayout>
<ImageView
android:layout_width="50dp"
android:layout_height="10dp"
android:layout_marginTop="-1dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/geofav_infowindow_pointer"
app:tint="@color/defaultBrand" />
</LinearLayout>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -31,21 +31,15 @@
<string name="list_mode">Lista</string> <string name="list_mode">Lista</string>
<string name="search_in_all">Cerca per nome</string> <string name="search_in_all">Cerca per nome</string>
<string name="share_via">Condividi via</string> <string name="share_via">Condividi via</string>
<string name="share_message">{title}: {lat}°N, {lng}°E https://www.openstreetmap.org/#map=17/{lat}/{lng}</string> <string name="share_message">Posizione condivisa: {lat}°N, {lng}°E https://www.openstreetmap.org/#map=17/{lat}/{lng}</string>
<string name="share_message_default_title">Posizione condivisa:</string>
<string name="list_context_menu_share">Condividi</string> <string name="list_context_menu_share">Condividi</string>
<string name="list_context_menu_delete">Elimina</string> <string name="list_context_menu_delete">Elimina</string>
<string name="dialog_delete_title">Elimina geosegnalibro</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_message">Stai per eliminare il geosegnalibro {name}. Procedere?</string>
<string name="dialog_delete_delete">Elimina</string> <string name="dialog_delete_delete">Elimina</string>
<string name="dialog_delete_cancel">Mantieni</string> <string name="dialog_delete_cancel">Mantieni</string>
<string name="dialog_logout_title">Cambia account</string>
<string name="dialog_logout_message">Vuoi cambiare account?</string>
<string name="list_geofavorite_deleted">Geosegnalibro eliminato</string> <string name="list_geofavorite_deleted">Geosegnalibro eliminato</string>
<string name="list_geofavorite_connection_error">Impossibile ottenere la lista dei geosegnalibri</string> <string name="list_geofavorite_connection_error">Impossibile ottenere la lista dei geosegnalibri</string>
<string name="filtering_unavailable">Il filtro per categoria non è disponibile al momento</string>
<string name="filtering_dialog_title">Filtra per categoria</string>
<string name="filtering_dialog_cancel">Mostra tutti</string>
<!-- Sort dialog --> <!-- Sort dialog -->
<string name="sort_by">Ordina per</string> <string name="sort_by">Ordina per</string>
@ -64,12 +58,11 @@
<string name="accuracy">Accuratezza: {accuracy} m</string> <string name="accuracy">Accuratezza: {accuracy} m</string>
<string name="accuracy_nosignal">Nessun segnale GPS!</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="location_permission_required">Per creare un geosegnalibro è necessario consentire l\'accesso alla posizione.</string>
<string name="category_hint">Scrivi il nome per creare una nuova categoria</string> <string name="confirm">Salva</string>
<string name="error_saving_geofavorite">Impossibile salvare il geosegnalibro</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="error_unsupported_uri">Impossibile ottenere le coordinate dai dati ricevuti</string>
<string name="geofavorite_saved">Geosegnalibro salvato</string> <string name="geofavorite_saved">Geosegnalibro salvato</string>
<string name="incomplete_geofavorite">Geosegnalibro incompleto: nome e categoria sono obbligatori</string> <string name="incomplete_geofavorite">Geosegnalibro incompleto: nome e categoria sono obbligatori</string>
<string name="coords_copied">Coordinate copiate nella clipboard</string>
<!-- Map picker activity --> <!-- Map picker activity -->
<string name="coordinates_parse_error">Le coordinate dovrebbero essere nel formato xx.xxxxxx</string> <string name="coordinates_parse_error">Le coordinate dovrebbero essere nel formato xx.xxxxxx</string>
@ -100,13 +93,12 @@
<string name="url_license" translatable="false">https://raw.githubusercontent.com/penguin86/nextcloud-maps-client/master/LICENSE</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> <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 --> <!-- Menu -->
<string name="new_geobookmark_gps">Crea dalla posizione corrente</string> <string name="new_geobookmark_gps">Crea dalla posizione corrente</string>
<string name="new_geobookmark_map">Crea dalla mappa</string> <string name="new_geobookmark_map">Crea dalla mappa</string>
<!-- Accessibility (content descriptions) -->
<string name="open_fab">Aggiungi</string>
<string name="add_from_gps">Crea dalla posizione corrente</string>
<string name="add_from_map">Crea dalla mappa</string>
</resources> </resources>

View File

@ -3,8 +3,4 @@
<color name="text_color">#eee</color> <color name="text_color">#eee</color>
<color name="disabled">#888</color> <color name="disabled">#888</color>
<color name="defaultBackground">#000</color> <color name="defaultBackground">#000</color>
<color name="translucent">#C000</color>
<!-- Toolbar -->
<color name="toolbar_background">#211e28</color>
</resources> </resources>

View File

@ -19,7 +19,7 @@
<resources> <resources>
<style name="AppTheme" parent="BaseTheme"> <style name="AppTheme" parent="BaseTheme">
<item name="android:statusBarColor">?android:attr/colorPrimary</item> <item name="android:statusBarColor">?attr/colorPrimary</item>
<item name="android:windowLightStatusBar">true</item> <item name="android:windowLightStatusBar">true</item>
</style> </style>

View File

@ -19,9 +19,9 @@
<resources> <resources>
<style name="AppTheme" parent="BaseTheme"> <style name="AppTheme" parent="BaseTheme">
<item name="android:statusBarColor">?android:attr/colorPrimary</item> <item name="android:statusBarColor">?attr/colorPrimary</item>
<item name="android:windowLightStatusBar">true</item> <item name="android:windowLightStatusBar">true</item>
<item name="android:navigationBarColor">?android:attr/colorPrimary</item> <item name="android:navigationBarColor">?attr/colorPrimary</item>
<item name="android:windowLightNavigationBar">true</item> <item name="android:windowLightNavigationBar">true</item>
</style> </style>

View File

@ -20,13 +20,11 @@
<!-- Generic Colors --> <!-- Generic Colors -->
<color name="primary">#ffffff</color> <color name="primary">#ffffff</color>
<color name="transparent">#00000000</color> <color name="transparent">#00000000</color>
<color name="translucent">#AEFFFFFF</color>
<color name="defaultBrand">#0082C9</color> <color name="defaultBrand">#0082C9</color>
<color name="defaultBrandAlpha">#550082C9</color> <color name="defaultBrandAlpha">#550082C9</color>
<color name="disabled">#666</color> <color name="disabled">#666</color>
<color name="systemBar">@color/defaultBackground</color> <color name="systemBar">@color/defaultBackground</color>
<color name="defaultBackground">#fff</color> <color name="defaultBackground">#fff</color>
<color name="inactive">#ccc</color>
<!-- List Colors --> <!-- List Colors -->
<color name="text_color">#333</color> <color name="text_color">#333</color>
@ -38,7 +36,4 @@
<!-- Generic Colors --> <!-- Generic Colors -->
<color name="white">#fff</color> <color name="white">#fff</color>
<!-- Toolbar -->
<color name="toolbar_background">@color/defaultBackground</color>
</resources> </resources>

View File

@ -39,7 +39,4 @@
<!-- FAB dimensions --> <!-- FAB dimensions -->
<dimen name="fab_vertical_offset">75dp</dimen> <dimen name="fab_vertical_offset">75dp</dimen>
<!-- Floating bar below search bar -->
<dimen name="floating_bar_height">36dp</dimen>
</resources> </resources>

View File

@ -30,21 +30,15 @@
<string name="list_mode">List</string> <string name="list_mode">List</string>
<string name="search_in_all">Search by name</string> <string name="search_in_all">Search by name</string>
<string name="share_via">Share via</string> <string name="share_via">Share via</string>
<string name="share_message">{title}: {lat}°N, {lng}°E https://www.openstreetmap.org/#map=17/{lat}/{lng}</string> <string name="share_message">Check out this place: {lat}°N, {lng}°E https://www.openstreetmap.org/#map=17/{lat}/{lng}</string>
<string name="share_message_default_title">Check out this place:</string>
<string name="list_context_menu_share">Share</string> <string name="list_context_menu_share">Share</string>
<string name="list_context_menu_delete">Delete</string> <string name="list_context_menu_delete">Delete</string>
<string name="dialog_delete_title">Delete geofavorite</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_message">You are about to delete geofavorite {name}. Proceed?</string>
<string name="dialog_delete_delete">Delete</string> <string name="dialog_delete_delete">Delete</string>
<string name="dialog_delete_cancel">Maintain</string> <string name="dialog_delete_cancel">Maintain</string>
<string name="dialog_logout_title">Switch account</string>
<string name="dialog_logout_message">Do you want to switch account?</string>
<string name="list_geofavorite_deleted">Geofavorite deleted</string> <string name="list_geofavorite_deleted">Geofavorite deleted</string>
<string name="list_geofavorite_connection_error">Unable to obtain geofavorites list</string> <string name="list_geofavorite_connection_error">Unable to obtain geofavorites list</string>
<string name="filtering_unavailable">Category filtering is unavailable at the moment</string>
<string name="filtering_dialog_title">Filter by category</string>
<string name="filtering_dialog_cancel">Show all</string>
<!-- Sort dialog --> <!-- Sort dialog -->
<string name="sort_by">Sort by</string> <string name="sort_by">Sort by</string>
@ -63,12 +57,11 @@
<string name="accuracy">Accuracy: {accuracy} m</string> <string name="accuracy">Accuracy: {accuracy} m</string>
<string name="accuracy_nosignal">No GPS signal!</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="location_permission_required">Location permission is required to create a geofavorite.</string>
<string name="category_hint">Write the name to create a new category</string> <string name="confirm">Save</string>
<string name="error_saving_geofavorite">Unable to save geofavorite</string> <string name="error_saving_geofavorite">Unable to save geofavorite</string>
<string name="error_unsupported_uri">Unable to obtain coordinates from shared data</string> <string name="error_unsupported_uri">Unable to obtain coordinates from shared data</string>
<string name="geofavorite_saved">Geofavorite saved</string> <string name="geofavorite_saved">Geofavorite saved</string>
<string name="incomplete_geofavorite">Incomplete geofavorite: Name and category are mandatory</string> <string name="incomplete_geofavorite">Incomplete geofavorite: Name and category are mandatory</string>
<string name="coords_copied">Coordinates have been copied to the clipboard</string>
<!-- Map picker activity --> <!-- Map picker activity -->
<string name="coordinates_parse_error">Coordinates should be in format xx.xxxxxx</string> <string name="coordinates_parse_error">Coordinates should be in format xx.xxxxxx</string>
@ -99,13 +92,12 @@
<string name="url_license" translatable="false">https://raw.githubusercontent.com/penguin86/nextcloud-maps-client/master/LICENSE</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> <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 --> <!-- Menu -->
<string name="new_geobookmark_gps">New from current position</string> <string name="new_geobookmark_gps">New from current position</string>
<string name="new_geobookmark_map">New from map</string> <string name="new_geobookmark_map">New from map</string>
<!-- Accessibility (content descriptions) -->
<string name="open_fab">Add geofavorite</string>
<string name="add_from_gps">Add geofavorite at current GPS position</string>
<string name="add_from_map">Add geofavorite from map</string>
<string name="menu">Open menu</string>
</resources> </resources>

View File

@ -17,17 +17,15 @@
<resources> <resources>
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="BaseTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <style name="BaseTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="colorAccent">@color/defaultBrand</item> <item name="colorAccent">@color/defaultBrand</item>
<item name="colorControlNormal">?android:attr/colorAccent</item> <item name="colorControlNormal">?attr/colorAccent</item>
<item name="windowActionModeOverlay">true</item> <item name="windowActionModeOverlay">true</item>
<!-- App bar --> <!-- App bar -->
<item name="colorPrimary">@color/systemBar</item> <item name="colorPrimary">@color/systemBar</item>
<!-- Generic background --> <!-- Generic background -->
<item name="android:windowBackground">@color/defaultBackground</item> <item name="android:windowBackground">@color/defaultBackground</item>
<item name="alertDialogTheme">@style/AlertDialogTheme</item>
</style> </style>
<style name="AppTheme" parent="BaseTheme"/> <style name="AppTheme" parent="BaseTheme"/>
@ -50,22 +48,4 @@
<item name="android:textColor">@color/white</item> <item name="android:textColor">@color/white</item>
</style> </style>
<style name="TextAppearance.GeofavoriteInfowindow" parent="TextAppearance.AppCompat.Title">
<item name="android:textColor">@color/white</item>
</style>
<!-- Alertdialogs -->
<style name="AlertDialogTheme" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
<item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
<item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
</style>
<style name="NegativeButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
<item name="android:textColor">@color/inactive</item>
</style>
<style name="PositiveButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
<item name="android:textColor">@color/defaultBrand</item>
</style>
</resources> </resources>

View File

@ -25,7 +25,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.5.1' classpath 'com.android.tools.build:gradle:7.1.1'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -1,5 +0,0 @@
Map view
Filter by category
Button to copy coordinates to clipboard
Faster autocomplete
Graphics restyling to match new Nextcloud style

View File

@ -1,4 +1,4 @@
UNOFFICIAL and FOSS Nextcloud Maps client. Shows your Nextcloud Maps geofavorites in a list or a map. UNOFFICIAL and FOSS Nextcloud Maps client at its earliest stages of developement. Shows your Nextcloud Maps geofavorites list.
Geofavorites can be opened in all apps supporting geo links (i.e. Google Maps, Organic Maps etc...). Geofavorites 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. A new geofavorite can be created on current location, by sharing a "geo:" uri from another app or manually picking from the map.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@ -1,3 +1,3 @@
Client per Nextcloud Maps non ufficiale e FOSS al suo stato iniziale di sviluppo. Client per Nextcloud Maps non ufficiale e FOSS al suo stato iniziale di sviluppo.
Mostra i geosegnalibri di Nextcloud Maps in lista o in mappa e permette di aprirli in qualunque app supporti i "geo:" urls (i.e. Google Maps, Organic Maps etc...). Mostra la lista dei geosegnalibri di Nextcloud Maps e permette di aprirli in qualunque app supporti i "geo:" urls (i.e. Google Maps, Organic Maps etc...).
È possibile creare nuovi geosegnalibri nella posizione GPS attuale, scegliendo la posizione dalla mappa o condividendola da altre app sotto forma di "geo:" uri. È possibile creare nuovi geosegnalibri nella posizione GPS attuale, scegliendo la posizione dalla mappa o condividendola da altre app sotto forma di "geo:" uri.

View File

@ -37,6 +37,3 @@ org.gradle.jvmargs=-Xmx2048m
android.useAndroidX=true android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX # Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false

View File

@ -1,6 +1,6 @@
#Sun Feb 20 08:50:37 CET 2022 #Sun Feb 20 08:50:37 CET 2022
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

After

Width:  |  Height:  |  Size: 114 KiB

BIN
screenshots/full/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB