diff options
author | Bananeweizen <bananeweizen@gmx.de> | 2014-12-30 10:41:02 +0100 |
---|---|---|
committer | Bananeweizen <bananeweizen@gmx.de> | 2014-12-30 10:41:02 +0100 |
commit | 896f0bd7d1c6b4096fb37594e5d879f0f49ed3af (patch) | |
tree | 66d889c9ba33ff569f700746b01b12caeceae840 /main | |
parent | 25b78896facadf9027130fb4180c394b464c7fe1 (diff) | |
download | cgeo-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.xml | 10 | ||||
-rw-r--r-- | main/res/layout/gcvote_rating_bar.xml | 26 | ||||
-rw-r--r-- | main/res/layout/logcache_activity.xml | 21 | ||||
-rw-r--r-- | main/res/menu/cache_options.xml | 6 | ||||
-rw-r--r-- | main/res/values/changelog_master.xml | 1 | ||||
-rw-r--r-- | main/res/values/strings.xml | 2 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/CacheDetailActivity.java | 17 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/LogCacheActivity.java | 23 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/gcvote/GCVote.java | 9 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/gcvote/GCVoteDialog.java | 74 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/gcvote/GCVotePoster.java | 53 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/gcvote/GCVoteRatingBarUtil.java | 58 |
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(); + } + +} |