aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2014-12-30 10:41:02 +0100
committerBananeweizen <bananeweizen@gmx.de>2014-12-30 10:41:02 +0100
commit896f0bd7d1c6b4096fb37594e5d879f0f49ed3af (patch)
tree66d889c9ba33ff569f700746b01b12caeceae840 /main
parent25b78896facadf9027130fb4180c394b464c7fe1 (diff)
downloadcgeo-896f0bd7d1c6b4096fb37594e5d879f0f49ed3af.zip
cgeo-896f0bd7d1c6b4096fb37594e5d879f0f49ed3af.tar.gz
cgeo-896f0bd7d1c6b4096fb37594e5d879f0f49ed3af.tar.bz2
#4566 new voting dialog
The tap handler for the rating stars will be implemented later.
Diffstat (limited to 'main')
-rw-r--r--main/res/layout/gcvote_dialog.xml10
-rw-r--r--main/res/layout/gcvote_rating_bar.xml26
-rw-r--r--main/res/layout/logcache_activity.xml21
-rw-r--r--main/res/menu/cache_options.xml6
-rw-r--r--main/res/values/changelog_master.xml1
-rw-r--r--main/res/values/strings.xml2
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java17
-rw-r--r--main/src/cgeo/geocaching/LogCacheActivity.java23
-rw-r--r--main/src/cgeo/geocaching/gcvote/GCVote.java9
-rw-r--r--main/src/cgeo/geocaching/gcvote/GCVoteDialog.java74
-rw-r--r--main/src/cgeo/geocaching/gcvote/GCVotePoster.java53
-rw-r--r--main/src/cgeo/geocaching/gcvote/GCVoteRatingBarUtil.java58
12 files changed, 259 insertions, 41 deletions
diff --git a/main/res/layout/gcvote_dialog.xml b/main/res/layout/gcvote_dialog.xml
new file mode 100644
index 0000000..221a8f5
--- /dev/null
+++ b/main/res/layout/gcvote_dialog.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dip"
+ android:orientation="vertical" >
+
+ <include layout="@layout/gcvote_rating_bar" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/main/res/layout/gcvote_rating_bar.xml b/main/res/layout/gcvote_rating_bar.xml
new file mode 100644
index 0000000..87d4ef5
--- /dev/null
+++ b/main/res/layout/gcvote_rating_bar.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools" >
+
+ <RatingBar
+ android:id="@+id/gcvoteRating"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:max="5"
+ android:numStars="5"
+ android:stepSize="0.5"
+ android:visibility="gone" />
+
+ <TextView
+ android:id="@+id/gcvoteLabel"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:padding="10dip"
+ android:text="@string/log_no_rating"
+ android:textColor="?text_color"
+ android:textSize="12sp"
+ android:visibility="gone" />
+
+</merge>
diff --git a/main/res/layout/logcache_activity.xml b/main/res/layout/logcache_activity.xml
index de6b37a..2e966d1 100644
--- a/main/res/layout/logcache_activity.xml
+++ b/main/res/layout/logcache_activity.xml
@@ -74,26 +74,7 @@
tools:ignore="TextFields" />
</LinearLayout>
- <RatingBar
- android:id="@+id/gcvoteRating"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:max="5"
- android:numStars="5"
- android:stepSize="0.5"
- android:visibility="gone" />
-
- <TextView
- android:id="@+id/gcvoteLabel"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:padding="10dip"
- android:text="@string/log_no_rating"
- android:textColor="?text_color"
- android:textSize="12sp"
- android:visibility="gone" />
+ <include layout="@layout/gcvote_rating_bar" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/tweet_box"
diff --git a/main/res/menu/cache_options.xml b/main/res/menu/cache_options.xml
index 8fdb2aa..c6d7322 100644
--- a/main/res/menu/cache_options.xml
+++ b/main/res/menu/cache_options.xml
@@ -38,6 +38,12 @@
app:showAsAction="ifRoom">
</item>
<item
+ android:id="@+id/menu_gcvote"
+ android:title="@string/cache_menu_vote"
+ android:visible="false"
+ app:showAsAction="ifRoom">
+ </item>
+ <item
android:id="@+id/menu_caches_around"
android:icon="@drawable/ic_menu_rotate"
android:title="@string/cache_menu_around"
diff --git a/main/res/values/changelog_master.xml b/main/res/values/changelog_master.xml
index 00bcbfc..bfac8de 100644
--- a/main/res/values/changelog_master.xml
+++ b/main/res/values/changelog_master.xml
@@ -4,6 +4,7 @@
<string name="changelog_master" translatable="false">
<b>Next feature release:</b>\n
· New: Waypoints created from personal notes can now be deleted\n
+ · New: More easy to use vote dialog in cache details\n
· Fix: Up navigation did not work when c:geo was invoked from another app\n
\n
</string>
diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml
index 9c78ffb..3a40a18 100644
--- a/main/res/values/strings.xml
+++ b/main/res/values/strings.xml
@@ -419,6 +419,7 @@
<string name="init_gcvote">GCvote.com</string>
<string name="init_gcvote_password_description">To be able to rate a cache, you need to follow the instructions at GCVote.com and enter your GCVote password here.</string>
<string name="err_gcvote_send_rating">Error while sending rating, check GCVote password in settings or empty it.</string>
+ <string name="gcvote_sent">Voting successfully sent</string>
<string name="init_twitter">Twitter</string>
<string name="settings_activate_twitter">Activate</string>
<string name="init_username">Username</string>
@@ -716,6 +717,7 @@
<string name="cache_menu_navigon">Navigon</string>
<string name="cache_menu_pebble">Pebble</string>
<string name="cache_menu_android_wear">Android Wear</string>
+ <string name="cache_menu_vote">Vote</string>
<string name="cache_status">Status</string>
<string name="cache_status_offline_log">Saved Log</string>
<string name="cache_status_found">Found</string>
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index 8ee4b83..a8d15e4 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -20,6 +20,8 @@ import cgeo.geocaching.enumerations.CacheAttribute;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.WaypointType;
+import cgeo.geocaching.gcvote.GCVote;
+import cgeo.geocaching.gcvote.GCVoteDialog;
import cgeo.geocaching.list.StoredList;
import cgeo.geocaching.location.Units;
import cgeo.geocaching.network.HtmlImage;
@@ -502,6 +504,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
menu.findItem(R.id.menu_store).setVisible(cache != null && !cache.isOffline());
menu.findItem(R.id.menu_delete).setVisible(cache != null && cache.isOffline());
menu.findItem(R.id.menu_refresh).setVisible(cache != null && cache.isOffline());
+ menu.findItem(R.id.menu_gcvote).setVisible(cache != null && GCVote.isVotingPossible(cache));
return super.onPrepareOptionsMenu(menu);
}
@@ -523,6 +526,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
case R.id.menu_refresh:
refreshCache();
return true;
+ case R.id.menu_gcvote:
+ showVoteDialog();
+ return true;
default:
if (NavigationAppFactory.onMenuItemSelected(item, this, cache)) {
return true;
@@ -536,6 +542,15 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
return super.onOptionsItemSelected(item);
}
+ private void showVoteDialog() {
+ GCVoteDialog.show(this, cache, new Runnable() {
+ @Override
+ public void run() {
+ notifyDataSetChanged();
+ }
+ });
+ }
+
private static final class CacheDetailsGeoDirHandler extends GeoDirHandler {
private final WeakReference<CacheDetailActivity> activityRef;
@@ -614,7 +629,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
private void notifyDataSetChanged() {
- // This might get called asynchronically when the activity is shut down
+ // This might get called asynchronous when the activity is shut down
if (isFinishing()) {
return;
}
diff --git a/main/src/cgeo/geocaching/LogCacheActivity.java b/main/src/cgeo/geocaching/LogCacheActivity.java
index c1e7e98..46b185a 100644
--- a/main/src/cgeo/geocaching/LogCacheActivity.java
+++ b/main/src/cgeo/geocaching/LogCacheActivity.java
@@ -12,6 +12,8 @@ import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.LogTypeTrackable;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.gcvote.GCVote;
+import cgeo.geocaching.gcvote.GCVoteRatingBarUtil;
+import cgeo.geocaching.gcvote.GCVoteRatingBarUtil.OnRatingChangeListener;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.twitter.Twitter;
import cgeo.geocaching.ui.dialog.DateDialog;
@@ -45,8 +47,6 @@ import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
-import android.widget.RatingBar;
-import android.widget.RatingBar.OnRatingBarChangeListener;
import android.widget.TextView;
import java.util.ArrayList;
@@ -86,7 +86,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia
private String imageDescription;
private Uri imageUri;
private boolean sendButtonEnabled;
- private boolean isRatingBarShown = false;
+ private final boolean isRatingBarShown = false;
public void onLoadFinished() {
if (loggingManager.hasLoaderError()) {
@@ -287,24 +287,13 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia
private void initializeRatingBar() {
if (GCVote.isVotingPossible(cache) && !isRatingBarShown) {
- final RatingBar ratingBar = ButterKnife.findById(this, R.id.gcvoteRating);
- final TextView label = ButterKnife.findById(this, R.id.gcvoteLabel);
- isRatingBarShown = true;
- ratingBar.setVisibility(View.VISIBLE);
- label.setVisibility(View.VISIBLE);
- ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
+ GCVoteRatingBarUtil.initializeRatingBar(cache, getWindow().getDecorView().getRootView(), new OnRatingChangeListener() {
@Override
- public void onRatingChanged(final RatingBar ratingBar, final float stars, final boolean fromUser) {
- // 0.5 is not a valid rating, therefore we must limit
- rating = GCVote.isValidRating(stars) ? stars : 0;
- if (rating < stars) {
- ratingBar.setRating(rating);
- }
- label.setText(GCVote.getDescription(rating));
+ public void onRatingChanged(final float stars) {
+ rating = stars;
}
});
- ratingBar.setRating(cache.getMyVote());
}
}
diff --git a/main/src/cgeo/geocaching/gcvote/GCVote.java b/main/src/cgeo/geocaching/gcvote/GCVote.java
index eaf7687..2985e89 100644
--- a/main/src/cgeo/geocaching/gcvote/GCVote.java
+++ b/main/src/cgeo/geocaching/gcvote/GCVote.java
@@ -131,8 +131,11 @@ public final class GCVote {
* @return {@code true} if the rating was submitted successfully
*/
public static boolean setRating(final Geocache cache, final float rating) {
- if (!isVotingPossible(cache) || !isValidRating(rating)) {
- throw new IllegalArgumentException(!isVotingPossible(cache) ? "voting is not possible for " + cache : "invalid rating " + rating);
+ if (!isVotingPossible(cache)) {
+ throw new IllegalArgumentException("voting is not possible for " + cache);
+ }
+ if (!isValidRating(rating)) {
+ throw new IllegalArgumentException("invalid rating " + rating);
}
final ImmutablePair<String, String> login = Settings.getGCvoteLogin();
@@ -199,7 +202,7 @@ public final class GCVote {
return rating >= MIN_RATING && rating <= MAX_RATING;
}
- public static boolean isVotingPossible(final Geocache cache) {
+ public static boolean isVotingPossible(@NonNull final Geocache cache) {
return Settings.isGCvoteLogin() && StringUtils.isNotBlank(cache.getGuid()) && cache.supportsGCVote();
}
diff --git a/main/src/cgeo/geocaching/gcvote/GCVoteDialog.java b/main/src/cgeo/geocaching/gcvote/GCVoteDialog.java
new file mode 100644
index 0000000..da14e0b
--- /dev/null
+++ b/main/src/cgeo/geocaching/gcvote/GCVoteDialog.java
@@ -0,0 +1,74 @@
+package cgeo.geocaching.gcvote;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.R;
+import cgeo.geocaching.gcvote.GCVoteRatingBarUtil.OnRatingChangeListener;
+import cgeo.geocaching.settings.Settings;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+import android.widget.Button;
+
+/**
+ * Small dialog showing only a rating bar to vote on GCVote.com. Confirming the dialog will send the vote over the
+ * network (in the background).
+ */
+public class GCVoteDialog {
+
+ public static void show(final Activity context, final Geocache cache, final @Nullable Runnable afterVoteSent) {
+ final Context themedContext;
+
+ if (Settings.isLightSkin() && VERSION.SDK_INT < VERSION_CODES.HONEYCOMB) {
+ themedContext = new ContextThemeWrapper(context, R.style.dark);
+ } else {
+ themedContext = context;
+ }
+
+ final View votingLayout = View.inflate(themedContext, R.layout.gcvote_dialog, null);
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(themedContext);
+ builder.setView(votingLayout);
+ builder.setPositiveButton(R.string.cache_menu_vote, new OnClickListener() {
+
+ @Override
+ public void onClick(final DialogInterface dialog, final int which) {
+ vote(cache, GCVoteRatingBarUtil.getRating(votingLayout), afterVoteSent);
+ }
+ });
+ builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(final DialogInterface dialog, final int whichButton) {
+ dialog.dismiss();
+ }
+ });
+ final AlertDialog dialog = builder.create();
+
+ GCVoteRatingBarUtil.initializeRatingBar(cache, votingLayout, new OnRatingChangeListener() {
+
+ @Override
+ public void onRatingChanged(final float stars) {
+ final Button button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ // this listener might be fired already while the dialog is not yet shown
+ if (button != null) {
+ button.setEnabled(GCVote.isValidRating(stars));
+ }
+ }
+ });
+ dialog.show();
+ dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(GCVote.isValidRating(cache.getMyVote()));
+ }
+
+ protected static void vote(final Geocache cache, final float rating, final @Nullable Runnable afterVoteSent) {
+ new GCVotePoster(cache, rating, afterVoteSent).execute();
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/gcvote/GCVotePoster.java b/main/src/cgeo/geocaching/gcvote/GCVotePoster.java
new file mode 100644
index 0000000..4f6550a
--- /dev/null
+++ b/main/src/cgeo/geocaching/gcvote/GCVotePoster.java
@@ -0,0 +1,53 @@
+package cgeo.geocaching.gcvote;
+
+import cgeo.geocaching.CgeoApplication;
+import cgeo.geocaching.DataStore;
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.R;
+import cgeo.geocaching.utils.Log;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+import android.os.AsyncTask;
+import android.widget.Toast;
+
+class GCVotePoster extends AsyncTask<Void, Void, Boolean> {
+
+ private final Geocache cache;
+ private final float rating;
+ private final @Nullable Runnable afterVoteSent;
+
+ public GCVotePoster(final Geocache cache, final float rating, final @Nullable Runnable afterVoteSent) {
+ this.cache = cache;
+ this.rating = rating;
+ this.afterVoteSent = afterVoteSent;
+ }
+
+ @Override
+ protected Boolean doInBackground(final Void... inputs) {
+ try {
+ if (GCVote.isValidRating(rating) && GCVote.isVotingPossible(cache)) {
+ // store locally
+ cache.setMyVote(rating);
+ DataStore.saveChangedCache(cache);
+
+ // send over network
+ return GCVote.setRating(cache, rating);
+ }
+ } catch (final RuntimeException e) {
+ Log.e("GCVoteAsyncTask.doInBackground", e);
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void onPostExecute(final Boolean status) {
+ final CgeoApplication context = CgeoApplication.getInstance();
+ final String text = context.getString(status.booleanValue() ? R.string.gcvote_sent : R.string.err_gcvote_send_rating);
+ Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
+ if (afterVoteSent != null) {
+ afterVoteSent.run();
+ }
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/gcvote/GCVoteRatingBarUtil.java b/main/src/cgeo/geocaching/gcvote/GCVoteRatingBarUtil.java
new file mode 100644
index 0000000..2d485bd
--- /dev/null
+++ b/main/src/cgeo/geocaching/gcvote/GCVoteRatingBarUtil.java
@@ -0,0 +1,58 @@
+package cgeo.geocaching.gcvote;
+
+import butterknife.ButterKnife;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.R;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+import android.view.View;
+import android.widget.RatingBar;
+import android.widget.RatingBar.OnRatingBarChangeListener;
+import android.widget.TextView;
+
+/**
+ * TODO: convert to fragment
+ *
+ */
+public final class GCVoteRatingBarUtil {
+ public interface OnRatingChangeListener {
+ public void onRatingChanged(final float stars);
+ }
+
+ private GCVoteRatingBarUtil() {
+ // utility class
+ }
+
+ public static void initializeRatingBar(final Geocache cache, final View parentView, @Nullable final OnRatingChangeListener changeListener) {
+ if (GCVote.isVotingPossible(cache)) {
+ final RatingBar ratingBar = ButterKnife.findById(parentView, R.id.gcvoteRating);
+ final TextView label = ButterKnife.findById(parentView, R.id.gcvoteLabel);
+ ratingBar.setVisibility(View.VISIBLE);
+ label.setVisibility(View.VISIBLE);
+ ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
+
+ @Override
+ public void onRatingChanged(final RatingBar ratingBar, final float stars, final boolean fromUser) {
+ // 0.5 is not a valid rating, therefore we must limit
+ final float rating = GCVote.isValidRating(stars) ? stars : 0;
+ if (rating < stars) {
+ ratingBar.setRating(rating);
+ }
+ label.setText(GCVote.getDescription(rating));
+ if (changeListener != null) {
+ changeListener.onRatingChanged(rating);
+ }
+ }
+ });
+ ratingBar.setRating(cache.getMyVote());
+ }
+ }
+
+ public static float getRating(final View parentView) {
+ final RatingBar ratingBar = ButterKnife.findById(parentView, R.id.gcvoteRating);
+ return ratingBar.getRating();
+ }
+
+}