diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java index a6dc39ab..09981547 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java @@ -8,7 +8,6 @@ import org.nuclearfog.twidda.backend.helper.StatusUpdate; import org.nuclearfog.twidda.backend.helper.UserListUpdate; import org.nuclearfog.twidda.backend.helper.UserLists; import org.nuclearfog.twidda.backend.helper.Users; -import org.nuclearfog.twidda.backend.helper.VoteUpdate; import org.nuclearfog.twidda.model.Account; import org.nuclearfog.twidda.model.Emoji; import org.nuclearfog.twidda.model.Location; @@ -526,9 +525,11 @@ public interface Connection { /** * send a vote to a poll * + * @param poll poll tovote + * @param selection selected poll choices * @return updated poll */ - Poll vote(VoteUpdate update) throws ConnectionException; + Poll vote(Poll poll, int[] selection) throws ConnectionException; /** * returns a list of blocked user IDs diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java index 110a0385..7fad3e1a 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java @@ -29,7 +29,6 @@ import org.nuclearfog.twidda.backend.helper.StatusUpdate; import org.nuclearfog.twidda.backend.helper.UserListUpdate; import org.nuclearfog.twidda.backend.helper.UserLists; import org.nuclearfog.twidda.backend.helper.Users; -import org.nuclearfog.twidda.backend.helper.VoteUpdate; import org.nuclearfog.twidda.backend.utils.ConnectionBuilder; import org.nuclearfog.twidda.backend.utils.StringTools; import org.nuclearfog.twidda.config.GlobalSettings; @@ -762,13 +761,13 @@ public class Mastodon implements Connection { @Override - public Poll vote(VoteUpdate update) throws ConnectionException { + public Poll vote(Poll poll, int[] selection) throws ConnectionException { List params = new ArrayList<>(); - for (int choice : update.getSelected()) { + for (int choice : selection) { params.add("choices[]=" + choice); } try { - Response response = post(ENDPOINT_POLL + update.getPollId() + "/votes", params); + Response response = post(ENDPOINT_POLL + poll.getId() + "/votes", params); ResponseBody body = response.body(); if (response.code() == 200 && body != null) { JSONObject json = new JSONObject(body.string()); diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/twitter/impl/v1/TwitterV1.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/twitter/impl/v1/TwitterV1.java index b3a66c35..9fe49159 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/twitter/impl/v1/TwitterV1.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/twitter/impl/v1/TwitterV1.java @@ -22,7 +22,6 @@ import org.nuclearfog.twidda.backend.helper.StatusUpdate; import org.nuclearfog.twidda.backend.helper.UserListUpdate; import org.nuclearfog.twidda.backend.helper.UserLists; import org.nuclearfog.twidda.backend.helper.Users; -import org.nuclearfog.twidda.backend.helper.VoteUpdate; import org.nuclearfog.twidda.backend.utils.ConnectionBuilder; import org.nuclearfog.twidda.backend.utils.StringTools; import org.nuclearfog.twidda.config.GlobalSettings; @@ -928,7 +927,7 @@ public class TwitterV1 implements Connection { @Override - public Poll vote(VoteUpdate update) throws ConnectionException { + public Poll vote(Poll poll, int[] choices) throws ConnectionException { throw new TwitterException("not supported!"); } diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/async/VoteUpdater.java b/app/src/main/java/org/nuclearfog/twidda/backend/async/VoteUpdater.java new file mode 100644 index 00000000..808f6d34 --- /dev/null +++ b/app/src/main/java/org/nuclearfog/twidda/backend/async/VoteUpdater.java @@ -0,0 +1,76 @@ +package org.nuclearfog.twidda.backend.async; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.nuclearfog.twidda.backend.api.Connection; +import org.nuclearfog.twidda.backend.api.ConnectionException; +import org.nuclearfog.twidda.backend.api.ConnectionManager; +import org.nuclearfog.twidda.backend.utils.AsyncExecutor; +import org.nuclearfog.twidda.model.Poll; + +import java.util.Arrays; + +/** + * Asynctask to update a poll vote + * + * @author nuclearfog + */ +public class VoteUpdater extends AsyncExecutor { + + private Connection connection; + + /** + * + */ + public VoteUpdater(Context context) { + connection = ConnectionManager.get(context); + } + + + @NonNull + @Override + protected VoteResult doInBackground(VoteParam param) { + try { + Poll poll = connection.vote(param.poll, param.selection); + return new VoteResult(poll, null); + } catch (ConnectionException exception) { + return new VoteResult(null, exception); + } catch (Exception e) { + e.printStackTrace(); + } + return new VoteResult(null, null); + } + + /** + * + */ + public static class VoteParam { + + public final Poll poll; + public final int[] selection; + + public VoteParam(Poll poll, int[] selection) { + this.poll = poll; + this.selection = Arrays.copyOf(selection, selection.length); + } + } + + /** + * + */ + public static class VoteResult { + + @Nullable + public final Poll poll; + @Nullable + public final ConnectionException exception; + + VoteResult(@Nullable Poll poll, @Nullable ConnectionException exception) { + this.poll = poll; + this.exception = exception; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/helper/VoteUpdate.java b/app/src/main/java/org/nuclearfog/twidda/backend/helper/VoteUpdate.java deleted file mode 100644 index c020328d..00000000 --- a/app/src/main/java/org/nuclearfog/twidda/backend/helper/VoteUpdate.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.nuclearfog.twidda.backend.helper; - -import androidx.annotation.NonNull; - -import org.nuclearfog.twidda.model.Poll; - -import java.util.Set; -import java.util.TreeSet; - -/** - * This class is used to send a vote to a poll - * - * @author nuclearfog - */ -public class VoteUpdate { - - private long id; - private boolean multipleChoice; - private Set choices; - - /** - * @param poll poll to vote - */ - public VoteUpdate(Poll poll) { - id = poll.getId(); - multipleChoice = poll.getLimit() > 1; - choices = new TreeSet<>(); - } - - /** - * select index of the selected vote option, starting with "0" - * - * @param index index of the option - */ - public void setChoice(int index) { - if (!multipleChoice || choices.isEmpty()) { - choices.add(index); - } - } - - /** - * ID of the poll - * - * @return poll ID - */ - public long getPollId() { - return id; - } - - /** - * get all selected vote option - * - * @return array of selected option index - */ - public int[] getSelected() { - int i = 0; - int[] result = new int[choices.size()]; - for (Integer choice : choices) { - result[i] = choice; - i++; - } - return result; - } - - - @NonNull - @Override - public String toString() { - return "id=" + id + " choices=" + choices.size(); - } -} \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java index d2868c9c..8baafe48 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java @@ -56,8 +56,10 @@ import org.nuclearfog.twidda.backend.api.ConnectionException; import org.nuclearfog.twidda.backend.async.StatusAction; import org.nuclearfog.twidda.backend.async.StatusAction.StatusParam; import org.nuclearfog.twidda.backend.async.StatusAction.StatusResult; +import org.nuclearfog.twidda.backend.async.VoteUpdater; +import org.nuclearfog.twidda.backend.async.VoteUpdater.VoteParam; +import org.nuclearfog.twidda.backend.async.VoteUpdater.VoteResult; import org.nuclearfog.twidda.backend.utils.AppStyles; -import org.nuclearfog.twidda.backend.utils.AsyncExecutor.AsyncCallback; import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.utils.PicassoBuilder; import org.nuclearfog.twidda.backend.utils.StringTools; @@ -87,7 +89,7 @@ import jp.wasabeef.picasso.transformations.RoundedCornersTransformation; * * @author nuclearfog */ -public class StatusActivity extends AppCompatActivity implements OnClickListener, OnScrollChangeListener, AsyncCallback, +public class StatusActivity extends AppCompatActivity implements OnClickListener, OnScrollChangeListener, OnLongClickListener, OnTagClickListener, OnConfirmListener, OnCardClickListener { /** @@ -140,8 +142,11 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener @Nullable private ClipboardManager clip; - private GlobalSettings settings; + @Nullable private StatusAction statusAsync; + @Nullable + private VoteUpdater voteAsync; + private GlobalSettings settings; private Picasso picasso; private PreviewAdapter adapter; @@ -272,12 +277,12 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener if (status != null) { setStatus(status); StatusParam param = new StatusParam(StatusParam.ONLINE, status.getId()); - statusAsync.execute(param, this); + statusAsync.execute(param, this::onStatusResult); } // Load status from database first if no status is defined else { StatusParam param = new StatusParam(StatusParam.ONLINE, id); - statusAsync.execute(param, this); + statusAsync.execute(param, this::onStatusResult); } } } @@ -380,7 +385,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener param = new StatusParam(StatusParam.HIDE, status.getId()); } statusAsync = new StatusAction(this); - statusAsync.execute(param, this); + statusAsync.execute(param, this::onStatusResult); } // get status link else if (item.getItemId() == R.id.menu_status_browser) { @@ -505,7 +510,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener param = new StatusParam(StatusParam.REPOST, status.getId()); } statusAsync = new StatusAction(this); - statusAsync.execute(param, this); + statusAsync.execute(param, this::onStatusResult); Toast.makeText(getApplicationContext(), R.string.info_loading, LENGTH_SHORT).show(); return true; } @@ -518,7 +523,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener param = new StatusParam(StatusParam.FAVORITE, status.getId()); } statusAsync = new StatusAction(this); - statusAsync.execute(param, this); + statusAsync.execute(param, this::onStatusResult); Toast.makeText(getApplicationContext(), R.string.info_loading, LENGTH_SHORT).show(); return true; } @@ -556,7 +561,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener param = new StatusParam(StatusParam.BOOKMARK, status.getId()); } statusAsync = new StatusAction(this); - statusAsync.execute(param, this); + statusAsync.execute(param, this::onStatusResult); Toast.makeText(getApplicationContext(), R.string.info_loading, LENGTH_SHORT).show(); return true; } @@ -586,7 +591,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener if (type == ConfirmDialog.DELETE_STATUS) { StatusParam param = new StatusParam(StatusParam.DELETE, status.getId()); statusAsync = new StatusAction(this); - statusAsync.execute(param, this); + statusAsync.execute(param, this::onStatusResult); } // confirm playing video without proxy else if (type == ConfirmDialog.PROXY_CONFIRM) { @@ -692,7 +697,11 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener @Override public void onVoteClick(Poll poll, int[] selection) { - // todo add implementation + if (voteAsync == null || voteAsync.isIdle()) { + VoteParam param = new VoteParam(poll, selection); + voteAsync = new VoteUpdater(this); + voteAsync.execute(param, this::setPollResult); + } } /** @@ -818,16 +827,18 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener } } - - @Override - public void onResult(StatusResult result) { + /** + * + */ + public void onStatusResult(StatusResult result) { if (result.status != null) { setStatus(result.status); } switch (result.mode) { case StatusResult.DATABASE: // update database status StatusParam param = new StatusParam(StatusParam.ONLINE, id); - statusAsync.execute(param, this); + statusAsync = new StatusAction(this); + statusAsync.execute(param, this::onStatusResult); break; case StatusResult.REPOST: @@ -901,4 +912,19 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener break; } } + + /** + * update status poll + * + * @param result poll result + */ + public void setPollResult(VoteResult result) { + if (result.poll != null) { + adapter.updatePoll(result.poll); + Toast.makeText(getApplicationContext(), R.string.info_poll_voted, Toast.LENGTH_SHORT).show(); + } else { + String message = ErrorHandler.getErrorMessage(this, result.exception); + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/PreviewAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/PreviewAdapter.java index 60eee92a..5260f865 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/PreviewAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/PreviewAdapter.java @@ -174,6 +174,21 @@ public class PreviewAdapter extends RecyclerView.Adapter implements notifyDataSetChanged(); } + /** + * update existing poll item + * + * @param poll updated poll item + */ + public void updatePoll(Poll poll) { + for (int i = 0; i < items.size(); i++) { + if (items.get(i) instanceof Poll && ((Poll)items.get(i)).getId() == poll.getId()) { + items.set(i, poll); + notifyItemChanged(i); + break; + } + } + } + /** * item click listener */ diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 0fc3b8d7..1635eeae 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -123,6 +123,7 @@ Mehr laden Bild speichern Video kann nicht abgespielt werden! + abstimmen Proxy aktivieren Proxy Authentifizierung aktivieren Falsche Proxykonfiguration! Änderung verwerfen? @@ -268,4 +269,5 @@ Status zu Lesezeichen hinzugefügt Status aus Lesezeichen entfernt Lesezeichen symbol + Umfrage abgestimmt! \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 864a952b..e784d8a6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -56,6 +56,7 @@ Status text copied Location coordinates copied Media link copied + vote sent! %1$s selected %1$s favorited your status %1$s followed you