mirror of
https://github.com/nuclearfog/Shitter.git
synced 2025-01-30 19:05:02 +01:00
added poll vote support
This commit is contained in:
parent
bcc9740f3d
commit
cdbf7aff60
@ -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
|
||||
|
@ -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<String> 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());
|
||||
|
@ -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!");
|
||||
}
|
||||
|
||||
|
@ -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<VoteUpdater.VoteParam, VoteUpdater.VoteResult> {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Integer> 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();
|
||||
}
|
||||
}
|
@ -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<StatusResult>,
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -174,6 +174,21 @@ public class PreviewAdapter extends RecyclerView.Adapter<ViewHolder> 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
|
||||
*/
|
||||
|
@ -123,6 +123,7 @@
|
||||
<string name="item_load_more">Mehr laden</string>
|
||||
<string name="item_image_save">Bild speichern</string>
|
||||
<string name="error_cant_load_video">Video kann nicht abgespielt werden!</string>
|
||||
<string name="item_poll_option_vote">abstimmen</string>
|
||||
<string name="settings_enable_proxy">Proxy aktivieren</string>
|
||||
<string name="settings_enable_proxy_auth">Proxy Authentifizierung aktivieren</string>
|
||||
<string name="error_wrong_connection_settings">Falsche Proxykonfiguration! Änderung verwerfen?</string>
|
||||
@ -268,4 +269,5 @@
|
||||
<string name="info_tweet_bookmarked">Status zu Lesezeichen hinzugefügt</string>
|
||||
<string name="info_tweet_unbookmarked">Status aus Lesezeichen entfernt</string>
|
||||
<string name="settings_bookmark_color">Lesezeichen symbol</string>
|
||||
<string name="info_poll_voted">Umfrage abgestimmt!</string>
|
||||
</resources>
|
@ -56,6 +56,7 @@
|
||||
<string name="info_tweet_text_copied">Status text copied</string>
|
||||
<string name="info_tweet_location_copied">Location coordinates copied</string>
|
||||
<string name="info_tweet_medialink_copied">Media link copied</string>
|
||||
<string name="info_poll_voted">vote sent!</string>
|
||||
<string name="info_account_selected">%1$s selected</string>
|
||||
<string name="info_user_favorited">%1$s favorited your status</string>
|
||||
<string name="info_user_follow">%1$s followed you</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user