First categories implementation
This commit is contained in:
		@@ -2,6 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Nextcloud Maps Geobookmarks Android app
 | 
					# Nextcloud Maps Geobookmarks Android app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[<img src="https://cdn.rawgit.com/steverichey/google-play-badge-svg/master/img/en_get.svg" height="80">](https://play.google.com/store/apps/details?id=it.danieleverducci.nextcloudmaps)
 | 
				
			||||||
 | 
					[<img src="https://raw.githubusercontent.com/andOTP/andOTP/master/assets/badges/get-it-on-github.png" height="80">](https://github.com/penguin86/nextcloud-maps-client/releases/latest)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Android app to show your Nextcloud Maps geobookmarks list. Geobookmarks can be opened in all apps supporting geo links (i.e. Google Maps, Organic Maps etc...).
 | 
					Android app to show your Nextcloud Maps geobookmarks list. Geobookmarks can be opened in all apps supporting geo links (i.e. Google Maps, Organic Maps etc...).
 | 
				
			||||||
A new geobookmark can be created on current location.
 | 
					A new geobookmark can be created on current location.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -50,6 +50,7 @@ import org.threeten.bp.format.DateTimeFormatter;
 | 
				
			|||||||
import org.threeten.bp.format.FormatStyle;
 | 
					import org.threeten.bp.format.FormatStyle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Date;
 | 
					import java.util.Date;
 | 
				
			||||||
 | 
					import java.util.HashSet;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import it.danieleverducci.nextcloudmaps.R;
 | 
					import it.danieleverducci.nextcloudmaps.R;
 | 
				
			||||||
@@ -119,6 +120,12 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        mViewModel = new ViewModelProvider(this).get(GeofavoriteDetailActivityViewModel.class);
 | 
					        mViewModel = new ViewModelProvider(this).get(GeofavoriteDetailActivityViewModel.class);
 | 
				
			||||||
        mViewModel.init();
 | 
					        mViewModel.init();
 | 
				
			||||||
 | 
					        mViewModel.getCategories().observe(this, new Observer<HashSet<String>>() {
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void onChanged(HashSet<String> categories) {
 | 
				
			||||||
 | 
					                mViewHolder.setCategories(categories);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
        mViewModel.getIsUpdating().observe(this, new Observer<Boolean>() {
 | 
					        mViewModel.getIsUpdating().observe(this, new Observer<Boolean>() {
 | 
				
			||||||
            @Override
 | 
					            @Override
 | 
				
			||||||
            public void onChanged(@Nullable Boolean updating) {
 | 
					            public void onChanged(@Nullable Boolean updating) {
 | 
				
			||||||
@@ -280,7 +287,9 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
 | 
				
			|||||||
        private OnSubmitListener listener;
 | 
					        private OnSubmitListener listener;
 | 
				
			||||||
        private Marker mapMarker;
 | 
					        private Marker mapMarker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ViewHolder(LayoutInflater inflater) {
 | 
					        public ViewHolder(LayoutInflater inflater) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.binding = ActivityGeofavoriteDetailBinding.inflate(inflater);
 | 
					            this.binding = ActivityGeofavoriteDetailBinding.inflate(inflater);
 | 
				
			||||||
            this.binding.submitBt.setOnClickListener(this);
 | 
					            this.binding.submitBt.setOnClickListener(this);
 | 
				
			||||||
            this.binding.mapBt.setOnClickListener(this);
 | 
					            this.binding.mapBt.setOnClickListener(this);
 | 
				
			||||||
@@ -289,6 +298,11 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
 | 
				
			|||||||
            this.binding.actionIconDelete.setOnClickListener(this);
 | 
					            this.binding.actionIconDelete.setOnClickListener(this);
 | 
				
			||||||
            this.binding.actionIconNav.setOnClickListener(this);
 | 
					            this.binding.actionIconNav.setOnClickListener(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Set categories adapter
 | 
				
			||||||
 | 
					            CategoriesSpinnerAdapter categoriesAdapter = new CategoriesSpinnerAdapter(binding.root.getContext());
 | 
				
			||||||
 | 
					            this.binding.categoryAt.setAdapter(categoriesAdapter);
 | 
				
			||||||
 | 
					            this.binding.categoryAt.setText(Geofavorite.DEFAULT_CATEGORY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Set map properties
 | 
					            // Set map properties
 | 
				
			||||||
            this.binding.map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
 | 
					            this.binding.map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
 | 
				
			||||||
            this.binding.map.setMultiTouchControls(true);
 | 
					            this.binding.map.setMultiTouchControls(true);
 | 
				
			||||||
@@ -310,7 +324,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
 | 
				
			|||||||
            binding.descriptionEt.setText(item.getComment());
 | 
					            binding.descriptionEt.setText(item.getComment());
 | 
				
			||||||
            binding.createdTv.setText(item.getLocalDateCreated().format(dateFormatter));
 | 
					            binding.createdTv.setText(item.getLocalDateCreated().format(dateFormatter));
 | 
				
			||||||
            binding.modifiedTv.setText(item.getLocalDateCreated().format(dateFormatter));
 | 
					            binding.modifiedTv.setText(item.getLocalDateCreated().format(dateFormatter));
 | 
				
			||||||
            binding.categoryTv.setText(item.getCategory()); // TODO: Category spinner from existing categories
 | 
					            binding.categoryAt.setText(item.getCategory());
 | 
				
			||||||
            updateViewCoords(item);
 | 
					            updateViewCoords(item);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -330,6 +344,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
 | 
				
			|||||||
        public void updateModel(Geofavorite item) {
 | 
					        public void updateModel(Geofavorite item) {
 | 
				
			||||||
            item.setName(binding.nameEt.getText().toString());
 | 
					            item.setName(binding.nameEt.getText().toString());
 | 
				
			||||||
            item.setComment(binding.descriptionEt.getText().toString());
 | 
					            item.setComment(binding.descriptionEt.getText().toString());
 | 
				
			||||||
 | 
					            item.setCategory(binding.categoryAt.getText().toString());
 | 
				
			||||||
            item.setDateModified(System.currentTimeMillis() / 1000);
 | 
					            item.setDateModified(System.currentTimeMillis() / 1000);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -347,6 +362,10 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
 | 
				
			|||||||
                binding.accuracyTv.setBackgroundColor(Color.rgb(red, green, 0.0f));
 | 
					                binding.accuracyTv.setBackgroundColor(Color.rgb(red, green, 0.0f));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void setCategories(HashSet<String> categories) {
 | 
				
			||||||
 | 
					            ((CategoriesSpinnerAdapter)binding.categoryAt.getAdapter()).setCategoriesList(categories);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void hideAccuracy() {
 | 
					        public void hideAccuracy() {
 | 
				
			||||||
            binding.accuracyTv.setVisibility(View.GONE);
 | 
					            binding.accuracyTv.setVisibility(View.GONE);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,10 @@ import androidx.lifecycle.LiveData;
 | 
				
			|||||||
import androidx.lifecycle.MutableLiveData;
 | 
					import androidx.lifecycle.MutableLiveData;
 | 
				
			||||||
import androidx.lifecycle.ViewModel;
 | 
					import androidx.lifecycle.ViewModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.HashMap;
 | 
				
			||||||
 | 
					import java.util.HashSet;
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,6 +26,9 @@ public class GeofavoriteDetailActivityViewModel extends ViewModel {
 | 
				
			|||||||
        mRepo.saveGeofavorite(geofav);
 | 
					        mRepo.saveGeofavorite(geofav);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public LiveData<HashSet<String>> getCategories(){
 | 
				
			||||||
 | 
					        return mRepo.getCategories();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public LiveData<Boolean> getIsUpdating(){
 | 
					    public LiveData<Boolean> getIsUpdating(){
 | 
				
			||||||
        return mRepo.isUpdating();
 | 
					        return mRepo.isUpdating();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -166,7 +166,10 @@ public class Geofavorite implements Serializable {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public boolean valid() {
 | 
					    public boolean valid() {
 | 
				
			||||||
        return getLat() != 0 && getLng() != 0 && getName() != null && getName().length() > 0;
 | 
					        return
 | 
				
			||||||
 | 
					                getLat() != 0 && getLng() != 0 &&
 | 
				
			||||||
 | 
					                getName() != null && getName().length() > 0 &&
 | 
				
			||||||
 | 
					                getCategory() != null && getCategory().length() > 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ import androidx.appcompat.app.AppCompatActivity;
 | 
				
			|||||||
import androidx.lifecycle.MutableLiveData;
 | 
					import androidx.lifecycle.MutableLiveData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.HashSet;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
 | 
					import it.danieleverducci.nextcloudmaps.api.ApiProvider;
 | 
				
			||||||
@@ -24,6 +25,7 @@ public class GeofavoriteRepository {
 | 
				
			|||||||
    private static final String TAG = "GeofavoriteRepository";
 | 
					    private static final String TAG = "GeofavoriteRepository";
 | 
				
			||||||
    private static GeofavoriteRepository instance;
 | 
					    private static GeofavoriteRepository instance;
 | 
				
			||||||
    private MutableLiveData<List<Geofavorite>> mGeofavorites;
 | 
					    private MutableLiveData<List<Geofavorite>> mGeofavorites;
 | 
				
			||||||
 | 
					    private MutableLiveData<HashSet<String>> mCategories = new MutableLiveData<HashSet<String>>();
 | 
				
			||||||
    private MutableLiveData<Boolean> mIsUpdating = new MutableLiveData<>(false);
 | 
					    private MutableLiveData<Boolean> mIsUpdating = new MutableLiveData<>(false);
 | 
				
			||||||
    private SingleLiveEvent<Boolean> mOnFinished = new SingleLiveEvent<>();
 | 
					    private SingleLiveEvent<Boolean> mOnFinished = new SingleLiveEvent<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,6 +44,10 @@ public class GeofavoriteRepository {
 | 
				
			|||||||
        return mGeofavorites;
 | 
					        return mGeofavorites;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public MutableLiveData<HashSet<String>> getCategories() {
 | 
				
			||||||
 | 
					        return mCategories;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public MutableLiveData<Boolean> isUpdating() {
 | 
					    public MutableLiveData<Boolean> isUpdating() {
 | 
				
			||||||
        return mIsUpdating;
 | 
					        return mIsUpdating;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -59,6 +65,7 @@ public class GeofavoriteRepository {
 | 
				
			|||||||
            public void onResponse(@NonNull Call<List<Geofavorite>> call, @NonNull Response<List<Geofavorite>> response) {
 | 
					            public void onResponse(@NonNull Call<List<Geofavorite>> call, @NonNull Response<List<Geofavorite>> response) {
 | 
				
			||||||
                if (response.isSuccessful() && response.body() != null) {
 | 
					                if (response.isSuccessful() && response.body() != null) {
 | 
				
			||||||
                    mGeofavorites.postValue(response.body());
 | 
					                    mGeofavorites.postValue(response.body());
 | 
				
			||||||
 | 
					                    updateCategories(response.body());
 | 
				
			||||||
                    mIsUpdating.postValue(false);
 | 
					                    mIsUpdating.postValue(false);
 | 
				
			||||||
                    mOnFinished.postValue(true);
 | 
					                    mOnFinished.postValue(true);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
@@ -146,4 +153,12 @@ public class GeofavoriteRepository {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void updateCategories(List<Geofavorite> geofavs) {
 | 
				
			||||||
 | 
					        HashSet<String> categories = new HashSet<>();
 | 
				
			||||||
 | 
					        for (Geofavorite g : geofavs) {
 | 
				
			||||||
 | 
					            categories.add(g.getCategory());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        mCategories.postValue(categories);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,7 +138,8 @@
 | 
				
			|||||||
                    android:textAppearance="@style/TextAppearance.AppCompat.Title"
 | 
					                    android:textAppearance="@style/TextAppearance.AppCompat.Title"
 | 
				
			||||||
                    android:background="@android:color/transparent"
 | 
					                    android:background="@android:color/transparent"
 | 
				
			||||||
                    android:drawableLeft="@drawable/ic_edit"
 | 
					                    android:drawableLeft="@drawable/ic_edit"
 | 
				
			||||||
                    android:drawablePadding="5dp"/>
 | 
					                    android:drawablePadding="5dp"
 | 
				
			||||||
 | 
					                    android:drawableTint="@color/defaultBrand"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <EditText
 | 
					                <EditText
 | 
				
			||||||
                    android:id="@+id/description_et"
 | 
					                    android:id="@+id/description_et"
 | 
				
			||||||
@@ -152,8 +153,24 @@
 | 
				
			|||||||
                    android:background="@android:color/transparent"
 | 
					                    android:background="@android:color/transparent"
 | 
				
			||||||
                    android:drawableLeft="@drawable/ic_edit"
 | 
					                    android:drawableLeft="@drawable/ic_edit"
 | 
				
			||||||
                    android:drawablePadding="5dp"
 | 
					                    android:drawablePadding="5dp"
 | 
				
			||||||
 | 
					                    android:drawableTint="@color/defaultBrand"
 | 
				
			||||||
                    android:hint="@string/description"/>
 | 
					                    android:hint="@string/description"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <AutoCompleteTextView
 | 
				
			||||||
 | 
					                    android:id="@+id/category_at"
 | 
				
			||||||
 | 
					                    android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_marginTop="20dp"
 | 
				
			||||||
 | 
					                    android:ems="10"
 | 
				
			||||||
 | 
					                    android:gravity="start|top"
 | 
				
			||||||
 | 
					                    android:inputType="textMultiLine"
 | 
				
			||||||
 | 
					                    android:maxLines="10"
 | 
				
			||||||
 | 
					                    android:background="@android:color/transparent"
 | 
				
			||||||
 | 
					                    android:drawableLeft="@drawable/ic_category_asc"
 | 
				
			||||||
 | 
					                    android:drawablePadding="5dp"
 | 
				
			||||||
 | 
					                    android:drawableTint="@color/defaultBrand"
 | 
				
			||||||
 | 
					                    android:hint="@string/category"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <TextView
 | 
					                <TextView
 | 
				
			||||||
                    android:layout_width="match_parent"
 | 
					                    android:layout_width="match_parent"
 | 
				
			||||||
                    android:layout_height="wrap_content"
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
@@ -180,19 +197,6 @@
 | 
				
			|||||||
                    android:layout_height="wrap_content"
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
                    android:textAlignment="textEnd" />
 | 
					                    android:textAlignment="textEnd" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <TextView
 | 
					 | 
				
			||||||
                    android:layout_width="match_parent"
 | 
					 | 
				
			||||||
                    android:layout_height="wrap_content"
 | 
					 | 
				
			||||||
                    android:layout_marginTop="20dp"
 | 
					 | 
				
			||||||
                    android:textStyle="bold"
 | 
					 | 
				
			||||||
                    android:text="@string/category" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                <TextView
 | 
					 | 
				
			||||||
                    android:id="@+id/category_tv"
 | 
					 | 
				
			||||||
                    android:layout_width="match_parent"
 | 
					 | 
				
			||||||
                    android:layout_height="wrap_content"
 | 
					 | 
				
			||||||
                    android:textAlignment="textEnd" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                <TextView
 | 
					                <TextView
 | 
				
			||||||
                    android:layout_width="match_parent"
 | 
					                    android:layout_width="match_parent"
 | 
				
			||||||
                    android:layout_height="wrap_content"
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,7 @@
 | 
				
			|||||||
    <string name="confirm">Save</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="geofavorite_saved">Geofavorite saved</string>
 | 
					    <string name="geofavorite_saved">Geofavorite saved</string>
 | 
				
			||||||
    <string name="incomplete_geofavorite">Incomplete geofavorite: Name and GPS coordinates are mandatory</string>
 | 
					    <string name="incomplete_geofavorite">Incomplete geofavorite: Name and category are mandatory</string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- About -->
 | 
					    <!-- About -->
 | 
				
			||||||
    <string name="about_version_title">Version</string>
 | 
					    <string name="about_version_title">Version</string>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user