Manage votes
This commit is contained in:
parent
c0f6352604
commit
4c54271a70
|
@ -94,5 +94,6 @@ dependencies {
|
|||
implementation 'com.github.mabbas007:TagsEditText:1.0.5'
|
||||
implementation 'com.jaredrummler:material-spinner:1.3.1'
|
||||
implementation "com.tonyodev.fetch2:fetch2:2.3.6"
|
||||
implementation 'com.github.stom79:horizontalbargraph:1.3'
|
||||
playstoreImplementation "io.github.kobakei:ratethisapp:$ratethisappLibraryVersion"
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ import android.widget.ListView;
|
|||
import android.widget.PopupMenu;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TimePicker;
|
||||
import android.widget.Toast;
|
||||
|
@ -124,6 +125,8 @@ import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
|||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Poll;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.PollOptions;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Results;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
|
@ -217,6 +220,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
|
|||
private String contentType;
|
||||
private int max_media_count;
|
||||
public static HashMap<String, Uri> filesMap;
|
||||
private Poll poll;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -1050,29 +1054,152 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
|
|||
case R.id.action_poll:
|
||||
AlertDialog.Builder alertPoll = new AlertDialog.Builder(TootActivity.this, style);
|
||||
alertPoll.setTitle(R.string.create_poll);
|
||||
View view = getLayoutInflater().inflate(R.layout.popup_poll, null);
|
||||
alertPoll.setView(view);
|
||||
Spinner poll_choice = view.findViewById(R.id.poll_choice);
|
||||
Spinner poll_duration = view.findViewById(R.id.poll_duration);
|
||||
EditText choice_1 = view.findViewById(R.id.choice_1);
|
||||
EditText choice_2 = view.findViewById(R.id.choice_2);
|
||||
EditText choice_3 = view.findViewById(R.id.choice_3);
|
||||
EditText choice_4 = view.findViewById(R.id.choice_4);
|
||||
ArrayAdapter<CharSequence> pollduration = ArrayAdapter.createFromResource(TootActivity.this,
|
||||
R.array.poll_duration, android.R.layout.simple_spinner_item);
|
||||
|
||||
alert.setView(input);
|
||||
String content = tootReply.getContent();
|
||||
if(tootReply.getReblog() != null)
|
||||
content = tootReply.getReblog().getContent();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
input.setText(Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY));
|
||||
ArrayAdapter<CharSequence> pollchoice = ArrayAdapter.createFromResource(TootActivity.this,
|
||||
R.array.poll_choice_type, android.R.layout.simple_spinner_item);
|
||||
poll_choice.setAdapter(pollchoice);
|
||||
poll_duration.setAdapter(pollduration);
|
||||
poll_duration.setSelection(4);
|
||||
poll_choice.setSelection(0);
|
||||
if( poll != null){
|
||||
int i = 1;
|
||||
for(PollOptions pollOptions: poll.getOptionsList()){
|
||||
switch (i){
|
||||
case 1:
|
||||
if( pollOptions.getTitle() != null)
|
||||
choice_1.setText(pollOptions.getTitle());
|
||||
break;
|
||||
case 2:
|
||||
if( pollOptions.getTitle() != null)
|
||||
choice_2.setText(pollOptions.getTitle());
|
||||
break;
|
||||
case 3:
|
||||
if( pollOptions.getTitle() != null)
|
||||
choice_3.setText(pollOptions.getTitle());
|
||||
break;
|
||||
case 4:
|
||||
if( pollOptions.getTitle() != null)
|
||||
choice_4.setText(pollOptions.getTitle());
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
switch (poll.getExpires_in()){
|
||||
case 300:
|
||||
poll_duration.setSelection(0);
|
||||
break;
|
||||
case 1800:
|
||||
poll_duration.setSelection(1);
|
||||
break;
|
||||
case 3600:
|
||||
poll_duration.setSelection(2);
|
||||
break;
|
||||
case 21600:
|
||||
poll_duration.setSelection(3);
|
||||
break;
|
||||
case 86400:
|
||||
poll_duration.setSelection(4);
|
||||
break;
|
||||
case 259200:
|
||||
poll_duration.setSelection(5);
|
||||
break;
|
||||
case 604800:
|
||||
poll_duration.setSelection(6);
|
||||
break;
|
||||
}
|
||||
if( poll.isMultiple())
|
||||
poll_choice.setSelection(1);
|
||||
else
|
||||
//noinspection deprecation
|
||||
input.setText(Html.fromHtml(content));
|
||||
alert.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
|
||||
poll_choice.setSelection(0);
|
||||
|
||||
|
||||
}
|
||||
alertPoll.setNeutralButton(R.string.delete, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
if( poll != null)
|
||||
poll = null;
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
alert.setNegativeButton(R.string.accounts, new DialogInterface.OnClickListener() {
|
||||
|
||||
alertPoll.setPositiveButton(R.string.done, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
new RetrieveAccountsForReplyAsyncTask(getApplicationContext(), tootReply.getReblog() != null?tootReply.getReblog():tootReply, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
int poll_duration_pos = poll_duration.getSelectedItemPosition();
|
||||
|
||||
int poll_choice_pos = poll_choice.getSelectedItemPosition();
|
||||
String choice1 = choice_1.getText().toString().trim();
|
||||
String choice2 = choice_2.getText().toString().trim();
|
||||
String choice3 = choice_3.getText().toString().trim();
|
||||
String choice4 = choice_4.getText().toString().trim();
|
||||
|
||||
if( choice1.isEmpty() && choice2.isEmpty()){
|
||||
Toasty.error(getApplicationContext(), getString(R.string.poll_invalid_choices), Toast.LENGTH_SHORT).show();
|
||||
}else{
|
||||
poll = new Poll();
|
||||
poll.setMultiple(poll_choice_pos != 0);
|
||||
int expire = 0;
|
||||
switch (poll_duration_pos){
|
||||
case 0:
|
||||
expire = 300;
|
||||
break;
|
||||
case 1:
|
||||
expire = 1800;
|
||||
break;
|
||||
case 2:
|
||||
expire = 3600;
|
||||
break;
|
||||
case 3:
|
||||
expire = 21600;
|
||||
break;
|
||||
case 4:
|
||||
expire = 86400;
|
||||
break;
|
||||
case 5:
|
||||
expire = 259200;
|
||||
break;
|
||||
case 6:
|
||||
expire = 604800;
|
||||
break;
|
||||
default:
|
||||
expire = 864000;
|
||||
}
|
||||
poll.setExpires_in(expire);
|
||||
|
||||
List<PollOptions> pollOptions = new ArrayList<>();
|
||||
PollOptions pollOption1 = new PollOptions();
|
||||
pollOption1.setTitle(choice1);
|
||||
pollOptions.add(pollOption1);
|
||||
|
||||
PollOptions pollOption2 = new PollOptions();
|
||||
pollOption2.setTitle(choice2);
|
||||
pollOptions.add(pollOption2);
|
||||
|
||||
PollOptions pollOption3 = new PollOptions();
|
||||
pollOption3.setTitle(choice3);
|
||||
pollOptions.add(pollOption3);
|
||||
|
||||
PollOptions pollOption4 = new PollOptions();
|
||||
pollOption4.setTitle(choice4);
|
||||
pollOptions.add(pollOption4);
|
||||
poll.setOptionsList(pollOptions);
|
||||
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
return true;
|
||||
alertPoll.show();
|
||||
return false;
|
||||
case R.id.action_translate:
|
||||
final CountryPicker picker = CountryPicker.newInstance(getString(R.string.which_language)); // dialog title
|
||||
if( theme == Helper.THEME_LIGHT){
|
||||
|
@ -1548,6 +1675,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
|
|||
if( tootReply != null)
|
||||
toot.setIn_reply_to_id(tootReply.getId());
|
||||
toot.setContent(tootContent);
|
||||
if( poll != null)
|
||||
toot.setPoll(poll);
|
||||
if( timestamp == null)
|
||||
if( scheduledstatus == null)
|
||||
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
|
|
@ -20,6 +20,10 @@ import android.content.SharedPreferences;
|
|||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
@ -31,6 +35,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.net.URLEncoder;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.Format;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
@ -61,6 +66,8 @@ import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
|||
import fr.gouv.etalab.mastodon.client.Entities.NodeInfo;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Poll;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.PollOptions;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Results;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Schedule;
|
||||
|
@ -436,6 +443,7 @@ public class API {
|
|||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a relationship between the authenticated account and an account
|
||||
* @param accounts ArrayList<Account> accounts fetched
|
||||
|
@ -2088,6 +2096,38 @@ public class API {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Public api call to submit a vote
|
||||
* @param pollId
|
||||
* @param choices
|
||||
* @return
|
||||
*/
|
||||
public Poll submiteVote(String pollId, int[] choices){
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
JsonArray jchoices = new JsonArray();
|
||||
for(int choice : choices){
|
||||
jchoices.add(choice);
|
||||
}
|
||||
jsonObject.add("choices",jchoices);
|
||||
try {
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
String response = httpsConnection.postJson(getAbsoluteUrl(String.format("/polls/%s/votes", pollId)), 60, jsonObject, prefKeyOauthTokenT);
|
||||
return parsePoll(context, new JSONObject(response));
|
||||
} catch (HttpsConnection.HttpsConnectionException e) {
|
||||
setError(e.getStatusCode(), e);
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (KeyManagementException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Posts a status
|
||||
|
@ -2096,38 +2136,41 @@ public class API {
|
|||
*/
|
||||
public APIResponse postStatusAction(Status status){
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
try {
|
||||
params.put("status", URLEncoder.encode(status.getContent(), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
params.put("status", status.getContent());
|
||||
}
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("status", status.getContent());
|
||||
if( status.getContentType() != null)
|
||||
params.put("content_type", status.getContentType());
|
||||
jsonObject.addProperty("content_type", status.getContentType());
|
||||
if( status.getIn_reply_to_id() != null)
|
||||
params.put("in_reply_to_id", status.getIn_reply_to_id());
|
||||
jsonObject.addProperty("in_reply_to_id", status.getIn_reply_to_id());
|
||||
if( status.getMedia_attachments() != null && status.getMedia_attachments().size() > 0 ) {
|
||||
StringBuilder parameters = new StringBuilder();
|
||||
JsonArray mediaArray = new JsonArray();
|
||||
for(Attachment attachment: status.getMedia_attachments())
|
||||
parameters.append("media_ids[]=").append(attachment.getId()).append("&");
|
||||
parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(12));
|
||||
params.put("media_ids[]", parameters.toString());
|
||||
mediaArray.add(attachment.getId());
|
||||
jsonObject.add("media_ids", mediaArray);
|
||||
}
|
||||
if( status.getScheduled_at() != null)
|
||||
params.put("scheduled_at", status.getScheduled_at());
|
||||
jsonObject.addProperty("scheduled_at", status.getScheduled_at());
|
||||
if( status.isSensitive())
|
||||
params.put("sensitive", Boolean.toString(status.isSensitive()));
|
||||
jsonObject.addProperty("sensitive", Boolean.toString(status.isSensitive()));
|
||||
if( status.getSpoiler_text() != null)
|
||||
try {
|
||||
params.put("spoiler_text", URLEncoder.encode(status.getSpoiler_text(), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
params.put("spoiler_text", status.getSpoiler_text());
|
||||
jsonObject.addProperty("spoiler_text", status.getSpoiler_text());
|
||||
if( status.getPoll() != null){
|
||||
JsonObject poll = new JsonObject();
|
||||
JsonArray options = new JsonArray();
|
||||
for(PollOptions option: status.getPoll().getOptionsList()){
|
||||
if( !option.getTitle().isEmpty())
|
||||
options.add(option.getTitle());
|
||||
}
|
||||
params.put("visibility", status.getVisibility());
|
||||
poll.add("options",options);
|
||||
poll.addProperty("expires_in",status.getPoll().getExpires_in());
|
||||
poll.addProperty("multiple",status.getPoll().isMultiple());
|
||||
jsonObject.add("poll", poll);
|
||||
}
|
||||
jsonObject.addProperty("visibility", status.getVisibility());
|
||||
statuses = new ArrayList<>();
|
||||
try {
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
String response = httpsConnection.post(getAbsoluteUrl("/statuses"), 60, params, prefKeyOauthTokenT);
|
||||
String response = httpsConnection.postJson(getAbsoluteUrl("/statuses"), 60, jsonObject, prefKeyOauthTokenT);
|
||||
apiResponse.setSince_id(httpsConnection.getSince_id());
|
||||
apiResponse.setMax_id(httpsConnection.getMax_id());
|
||||
Status statusreturned = parseStatuses(context, new JSONObject(response));
|
||||
|
@ -3502,6 +3545,40 @@ public class API {
|
|||
return statuses;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a poll
|
||||
* @param context
|
||||
* @param resobj
|
||||
* @return
|
||||
*/
|
||||
public static Poll parsePoll(Context context, JSONObject resobj){
|
||||
Poll poll = new Poll();
|
||||
try {
|
||||
poll.setId(resobj.getString("id"));
|
||||
poll.setExpires_at(Helper.mstStringToDate(context, resobj.getString("expires_at")));
|
||||
poll.setExpired(resobj.getBoolean("expired"));
|
||||
poll.setMultiple(resobj.getBoolean("multiple"));
|
||||
poll.setVotes_count(resobj.getInt("votes_count"));
|
||||
poll.setVoted(resobj.getBoolean("voted"));
|
||||
JSONArray options = resobj.getJSONArray("options");
|
||||
List<PollOptions> pollOptions = new ArrayList<>();
|
||||
for(int i = 0; i < options.length() ; i++){
|
||||
JSONObject option = options.getJSONObject(i);
|
||||
PollOptions pollOption = new PollOptions();
|
||||
pollOption.setTitle(option.getString("title"));
|
||||
pollOption.setVotes_count(option.getInt("votes_count"));
|
||||
pollOptions.add(pollOption);
|
||||
}
|
||||
poll.setOptionsList(pollOptions);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return poll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse json response for unique status
|
||||
* @param resobj JSONObject
|
||||
|
@ -3544,6 +3621,26 @@ public class API {
|
|||
attachments.add(attachment);
|
||||
}
|
||||
}
|
||||
if( resobj.has("poll") && !resobj.isNull("poll")){
|
||||
Poll poll = new Poll();
|
||||
poll.setId(resobj.getJSONObject("poll").getString("id"));
|
||||
poll.setExpires_at(Helper.mstStringToDate(context, resobj.getJSONObject("poll").getString("expires_at")));
|
||||
poll.setExpired(resobj.getJSONObject("poll").getBoolean("expired"));
|
||||
poll.setMultiple(resobj.getJSONObject("poll").getBoolean("multiple"));
|
||||
poll.setVotes_count(resobj.getJSONObject("poll").getInt("votes_count"));
|
||||
poll.setVoted(resobj.getJSONObject("poll").getBoolean("voted"));
|
||||
JSONArray options = resobj.getJSONObject("poll").getJSONArray("options");
|
||||
List<PollOptions> pollOptions = new ArrayList<>();
|
||||
for(int i = 0; i < options.length() ; i++){
|
||||
JSONObject option = options.getJSONObject(i);
|
||||
PollOptions pollOption = new PollOptions();
|
||||
pollOption.setTitle(option.getString("title"));
|
||||
pollOption.setVotes_count(option.getInt("votes_count"));
|
||||
pollOptions.add(pollOption);
|
||||
}
|
||||
poll.setOptionsList(pollOptions);
|
||||
status.setPoll(poll);
|
||||
}
|
||||
|
||||
try {
|
||||
status.setCard(parseCardResponse(resobj.getJSONObject("card")));
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.client.Entities;
|
||||
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -25,12 +25,24 @@ public class Poll implements Parcelable {
|
|||
|
||||
private String id;
|
||||
private Date expires_at;
|
||||
private int expires_in;
|
||||
private boolean expired;
|
||||
private boolean multiple;
|
||||
private int votes_count;
|
||||
private boolean voted;
|
||||
private List<PollOptions> optionsList;
|
||||
|
||||
public Poll() {
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getExpires_at() {
|
||||
return expires_at;
|
||||
}
|
||||
|
@ -79,27 +91,14 @@ public class Poll implements Parcelable {
|
|||
this.optionsList = optionsList;
|
||||
}
|
||||
|
||||
|
||||
private class PollOptions{
|
||||
private String title;
|
||||
private String votes_count;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
public int getExpires_in() {
|
||||
return expires_in;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
public void setExpires_in(int expires_in) {
|
||||
this.expires_in = expires_in;
|
||||
}
|
||||
|
||||
public String getVotes_count() {
|
||||
return votes_count;
|
||||
}
|
||||
|
||||
public void setVotes_count(String votes_count) {
|
||||
this.votes_count = votes_count;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
|
@ -110,26 +109,24 @@ public class Poll implements Parcelable {
|
|||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.id);
|
||||
dest.writeLong(this.expires_at != null ? this.expires_at.getTime() : -1);
|
||||
dest.writeInt(this.expires_in);
|
||||
dest.writeByte(this.expired ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.multiple ? (byte) 1 : (byte) 0);
|
||||
dest.writeInt(this.votes_count);
|
||||
dest.writeByte(this.voted ? (byte) 1 : (byte) 0);
|
||||
dest.writeList(this.optionsList);
|
||||
}
|
||||
|
||||
public Poll() {
|
||||
dest.writeTypedList(this.optionsList);
|
||||
}
|
||||
|
||||
protected Poll(Parcel in) {
|
||||
this.id = in.readString();
|
||||
long tmpExpires_at = in.readLong();
|
||||
this.expires_at = tmpExpires_at == -1 ? null : new Date(tmpExpires_at);
|
||||
this.expires_in = in.readInt();
|
||||
this.expired = in.readByte() != 0;
|
||||
this.multiple = in.readByte() != 0;
|
||||
this.votes_count = in.readInt();
|
||||
this.voted = in.readByte() != 0;
|
||||
this.optionsList = new ArrayList<PollOptions>();
|
||||
in.readList(this.optionsList, PollOptions.class.getClassLoader());
|
||||
this.optionsList = in.createTypedArrayList(PollOptions.CREATOR);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Poll> CREATOR = new Parcelable.Creator<Poll>() {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package fr.gouv.etalab.mastodon.client.Entities;
|
||||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class PollOptions implements Parcelable {
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public int getVotes_count() {
|
||||
return votes_count;
|
||||
}
|
||||
|
||||
public void setVotes_count(int votes_count) {
|
||||
this.votes_count = votes_count;
|
||||
}
|
||||
|
||||
private String title;
|
||||
private int votes_count;
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.title);
|
||||
dest.writeInt(this.votes_count);
|
||||
}
|
||||
|
||||
public PollOptions() {
|
||||
}
|
||||
|
||||
protected PollOptions(Parcel in) {
|
||||
this.title = in.readString();
|
||||
this.votes_count = in.readInt();
|
||||
}
|
||||
|
||||
public static final Creator<PollOptions> CREATOR = new Creator<PollOptions>() {
|
||||
@Override
|
||||
public PollOptions createFromParcel(Parcel source) {
|
||||
return new PollOptions(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PollOptions[] newArray(int size) {
|
||||
return new PollOptions[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -132,6 +132,7 @@ public class Status implements Parcelable{
|
|||
private String scheduled_at;
|
||||
private String contentType;
|
||||
private boolean isNotice = false;
|
||||
private Poll poll = null;
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
|
@ -188,6 +189,7 @@ public class Status implements Parcelable{
|
|||
dest.writeString(this.contentType);
|
||||
dest.writeByte(this.showSpoiler ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.isNotice ? (byte) 1 : (byte) 0);
|
||||
dest.writeParcelable(this.poll, flags);
|
||||
}
|
||||
|
||||
protected Status(Parcel in) {
|
||||
|
@ -246,6 +248,7 @@ public class Status implements Parcelable{
|
|||
this.contentType = in.readString();
|
||||
this.showSpoiler = in.readByte() != 0;
|
||||
this.isNotice = in.readByte() != 0;
|
||||
this.poll = in.readParcelable(Poll.class.getClassLoader());
|
||||
}
|
||||
|
||||
public static final Creator<Status> CREATOR = new Creator<Status>() {
|
||||
|
@ -1331,4 +1334,12 @@ public class Status implements Parcelable{
|
|||
public void setNotice(boolean notice) {
|
||||
isNotice = notice;
|
||||
}
|
||||
|
||||
public Poll getPoll() {
|
||||
return poll;
|
||||
}
|
||||
|
||||
public void setPoll(Poll poll) {
|
||||
this.poll = poll;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,10 @@ import android.database.sqlite.SQLiteDatabase;
|
|||
import android.os.Build;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableString;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
|
@ -42,6 +44,7 @@ import java.net.InetSocketAddress;
|
|||
import java.net.PasswordAuthentication;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
|
@ -325,7 +328,7 @@ public class HttpsConnection {
|
|||
postData.append(String.valueOf(param.getValue()));
|
||||
}
|
||||
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
|
||||
|
||||
Log.v(Helper.TAG,"postData! " + postData);
|
||||
if (proxy != null)
|
||||
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
|
||||
else
|
||||
|
@ -426,6 +429,99 @@ public class HttpsConnection {
|
|||
|
||||
}
|
||||
|
||||
|
||||
public String postJson(String urlConnection, int timeout, JsonObject jsonObject, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
|
||||
if( urlConnection.startsWith("https://")) {
|
||||
URL url = new URL(urlConnection);
|
||||
Log.v(Helper.TAG,"--> " +jsonObject);
|
||||
byte[] postDataBytes = new byte[0];
|
||||
postDataBytes = jsonObject.toString().getBytes("UTF-8");
|
||||
if (proxy != null)
|
||||
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
|
||||
else
|
||||
httpsURLConnection = (HttpsURLConnection) url.openConnection();
|
||||
httpsURLConnection.setRequestProperty("User-Agent", Helper.USER_AGENT);
|
||||
httpsURLConnection.setConnectTimeout(timeout * 1000);
|
||||
httpsURLConnection.setDoOutput(true);
|
||||
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
|
||||
httpsURLConnection.setRequestProperty("Content-Type", "application/json");
|
||||
httpsURLConnection.setRequestProperty("Accept", "application/json");
|
||||
httpsURLConnection.setRequestMethod("POST");
|
||||
if (token != null && !token.startsWith("Basic "))
|
||||
httpsURLConnection.setRequestProperty("Authorization", "Bearer " + token);
|
||||
else if( token != null && token.startsWith("Basic "))
|
||||
httpsURLConnection.setRequestProperty("Authorization", token);
|
||||
httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
|
||||
|
||||
|
||||
httpsURLConnection.getOutputStream().write(postDataBytes);
|
||||
String response;
|
||||
if (httpsURLConnection.getResponseCode() >= 200 && httpsURLConnection.getResponseCode() < 400) {
|
||||
getSinceMaxId();
|
||||
response = converToString(httpsURLConnection.getInputStream());
|
||||
} else {
|
||||
String error = null;
|
||||
if( httpsURLConnection.getErrorStream() != null) {
|
||||
InputStream stream = httpsURLConnection.getErrorStream();
|
||||
if (stream == null) {
|
||||
stream = httpsURLConnection.getInputStream();
|
||||
}
|
||||
try (Scanner scanner = new Scanner(stream)) {
|
||||
scanner.useDelimiter("\\Z");
|
||||
error = scanner.next();
|
||||
}catch (Exception e){e.printStackTrace();}
|
||||
}
|
||||
int responseCode = httpsURLConnection.getResponseCode();
|
||||
throw new HttpsConnectionException(responseCode, error);
|
||||
}
|
||||
getSinceMaxId();
|
||||
httpsURLConnection.getInputStream().close();
|
||||
return response;
|
||||
}else {
|
||||
URL url = new URL(urlConnection);
|
||||
byte[] postDataBytes = jsonObject.toString().getBytes("UTF-8");
|
||||
|
||||
if (proxy != null)
|
||||
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
|
||||
else
|
||||
httpURLConnection = (HttpURLConnection) url.openConnection();
|
||||
httpURLConnection.setRequestProperty("User-Agent", Helper.USER_AGENT);
|
||||
httpURLConnection.setConnectTimeout(timeout * 1000);
|
||||
httpURLConnection.setDoOutput(true);
|
||||
httpURLConnection.setRequestMethod("POST");
|
||||
if (token != null && !token.startsWith("Basic "))
|
||||
httpURLConnection.setRequestProperty("Authorization", "Bearer " + token);
|
||||
else if( token != null && token.startsWith("Basic "))
|
||||
httpURLConnection.setRequestProperty("Authorization", token);
|
||||
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
|
||||
|
||||
httpURLConnection.getOutputStream().write(postDataBytes);
|
||||
String response;
|
||||
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
|
||||
getSinceMaxId();
|
||||
response = converToString(httpURLConnection.getInputStream());
|
||||
} else {
|
||||
String error = null;
|
||||
if( httpURLConnection.getErrorStream() != null) {
|
||||
InputStream stream = httpURLConnection.getErrorStream();
|
||||
if (stream == null) {
|
||||
stream = httpURLConnection.getInputStream();
|
||||
}
|
||||
try (Scanner scanner = new Scanner(stream)) {
|
||||
scanner.useDelimiter("\\Z");
|
||||
error = scanner.next();
|
||||
}catch (Exception e){e.printStackTrace();}
|
||||
}
|
||||
int responseCode = httpURLConnection.getResponseCode();
|
||||
throw new HttpsConnectionException(responseCode, error);
|
||||
}
|
||||
getSinceMaxId();
|
||||
httpURLConnection.getInputStream().close();
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String postMisskey(String urlConnection, int timeout, JSONObject paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
|
||||
URL url = new URL(urlConnection);
|
||||
byte[] postDataBytes = paramaters.toString().getBytes("UTF-8");
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
|
@ -46,6 +47,7 @@ import android.text.method.LinkMovementMethod;
|
|||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.URLSpan;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
|
@ -55,12 +57,15 @@ import android.view.ViewGroup;
|
|||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.DatePicker;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TimePicker;
|
||||
|
@ -90,6 +95,8 @@ import java.util.List;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import br.com.felix.horizontalbargraph.HorizontalBar;
|
||||
import br.com.felix.horizontalbargraph.model.BarItem;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.BaseMainActivity;
|
||||
|
@ -113,6 +120,8 @@ import fr.gouv.etalab.mastodon.client.Entities.Card;
|
|||
import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Poll;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.PollOptions;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.TagTimeline;
|
||||
import fr.gouv.etalab.mastodon.fragments.DisplayStatusFragment;
|
||||
|
@ -328,6 +337,16 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
|
|||
LinearLayout status_peertube_container;
|
||||
TextView status_peertube_reply, status_peertube_delete;
|
||||
|
||||
|
||||
//Poll
|
||||
LinearLayout poll_container, single_choice, multiple_choice, rated;
|
||||
RadioGroup radio_group;
|
||||
RadioButton r_choice_1, r_choice_2, r_choice_3, r_choice_4;
|
||||
CheckBox c_choice_1, c_choice_2, c_choice_3, c_choice_4;
|
||||
HorizontalBar choices;
|
||||
TextView number_votes, remaining_time;
|
||||
Button submit_vote;
|
||||
|
||||
public View getView(){
|
||||
return itemView;
|
||||
}
|
||||
|
@ -416,6 +435,23 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
|
|||
status_peertube_reply = itemView.findViewById(R.id.status_peertube_reply);
|
||||
status_peertube_delete = itemView.findViewById(R.id.status_peertube_delete);
|
||||
|
||||
poll_container = itemView.findViewById(R.id.poll_container);
|
||||
single_choice = itemView.findViewById(R.id.single_choice);
|
||||
multiple_choice = itemView.findViewById(R.id.multiple_choice);
|
||||
rated = itemView.findViewById(R.id.rated);
|
||||
radio_group = itemView.findViewById(R.id.radio_group);
|
||||
r_choice_1 = itemView.findViewById(R.id.r_choice_1);
|
||||
r_choice_2 = itemView.findViewById(R.id.r_choice_2);
|
||||
r_choice_3 = itemView.findViewById(R.id.r_choice_3);
|
||||
r_choice_4 = itemView.findViewById(R.id.r_choice_4);
|
||||
c_choice_1 = itemView.findViewById(R.id.c_choice_1);
|
||||
c_choice_2 = itemView.findViewById(R.id.c_choice_2);
|
||||
c_choice_3 = itemView.findViewById(R.id.c_choice_3);
|
||||
c_choice_4 = itemView.findViewById(R.id.c_choice_4);
|
||||
choices = itemView.findViewById(R.id.choices);
|
||||
number_votes = itemView.findViewById(R.id.number_votes);
|
||||
remaining_time = itemView.findViewById(R.id.remaining_time);
|
||||
submit_vote = itemView.findViewById(R.id.submit_vote);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,7 +542,91 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
|
|||
|
||||
holder.status_reply.setText("");
|
||||
//Display a preview for accounts that have replied *if enabled and only for home timeline*
|
||||
if (social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
holder.rated.setVisibility(View.GONE);
|
||||
holder.multiple_choice.setVisibility(View.GONE);
|
||||
holder.single_choice.setVisibility(View.GONE);
|
||||
holder.submit_vote.setVisibility(View.GONE);
|
||||
if( status.getPoll() != null){
|
||||
Poll poll = status.getPoll();
|
||||
int choiceCount = status.getPoll().getOptionsList().size();
|
||||
if( poll.isVoted()){
|
||||
holder.rated.setVisibility(View.VISIBLE);
|
||||
List<BarItem> items = new ArrayList<>();
|
||||
int greaterValue = 0;
|
||||
for(PollOptions pollOption: status.getPoll().getOptionsList()){
|
||||
if( pollOption.getVotes_count() > greaterValue)
|
||||
greaterValue = pollOption.getVotes_count();
|
||||
}
|
||||
for(PollOptions pollOption: status.getPoll().getOptionsList()){
|
||||
double value = ((double)(pollOption.getVotes_count()* 100) / (double)poll.getVotes_count()) ;
|
||||
if( pollOption.getVotes_count() == greaterValue) {
|
||||
BarItem bar = new BarItem(pollOption.getTitle(), value, "%", ContextCompat.getColor(context, R.color.mastodonC4), Color.WHITE);
|
||||
bar.setRounded(true);
|
||||
bar.setHeight1(30);
|
||||
items.add(bar);
|
||||
}else {
|
||||
BarItem bar = new BarItem(pollOption.getTitle(), value, "%", ContextCompat.getColor(context, R.color.mastodonC2), Color.WHITE);
|
||||
bar.setRounded(true);
|
||||
bar.setHeight1(30);
|
||||
items.add(bar);
|
||||
}
|
||||
}
|
||||
holder.choices.init(context).hasAnimation(true).addAll(items).build();
|
||||
}else {
|
||||
if( poll.isMultiple()){
|
||||
Log.v(Helper.TAG,"count: " + choiceCount);
|
||||
holder.multiple_choice.setVisibility(View.VISIBLE);
|
||||
holder.c_choice_3.setVisibility(View.GONE);
|
||||
holder.c_choice_4.setVisibility(View.GONE);
|
||||
if( choiceCount > 2)
|
||||
holder.c_choice_3.setVisibility(View.VISIBLE);
|
||||
if( choiceCount > 3)
|
||||
holder.c_choice_4.setVisibility(View.VISIBLE);
|
||||
int j = 1;
|
||||
for(PollOptions pollOption: status.getPoll().getOptionsList()){
|
||||
if( j == 1 )
|
||||
holder.c_choice_1.setText(pollOption.getTitle());
|
||||
else if( j == 2 )
|
||||
holder.c_choice_2.setText(pollOption.getTitle());
|
||||
else if( j == 3 )
|
||||
holder.c_choice_3.setText(pollOption.getTitle());
|
||||
else if( j == 4 )
|
||||
holder.c_choice_4.setText(pollOption.getTitle());
|
||||
j++;
|
||||
}
|
||||
|
||||
}else {
|
||||
Log.v(Helper.TAG,"count: " + choiceCount);
|
||||
holder.single_choice.setVisibility(View.VISIBLE);
|
||||
holder.r_choice_3.setVisibility(View.GONE);
|
||||
holder.r_choice_4.setVisibility(View.GONE);
|
||||
if( choiceCount > 2)
|
||||
holder.r_choice_3.setVisibility(View.VISIBLE);
|
||||
if( choiceCount > 3)
|
||||
holder.r_choice_4.setVisibility(View.VISIBLE);
|
||||
int j = 1;
|
||||
for(PollOptions pollOption: status.getPoll().getOptionsList()){
|
||||
if( j == 1 )
|
||||
holder.r_choice_1.setText(pollOption.getTitle());
|
||||
else if( j == 2 )
|
||||
holder.r_choice_2.setText(pollOption.getTitle());
|
||||
else if( j == 3 )
|
||||
holder.r_choice_3.setText(pollOption.getTitle());
|
||||
else if( j == 4 )
|
||||
holder.r_choice_4.setText(pollOption.getTitle());
|
||||
j++;
|
||||
}
|
||||
}
|
||||
holder.submit_vote.setVisibility(View.VISIBLE);
|
||||
}
|
||||
holder.poll_container.setVisibility(View.VISIBLE);
|
||||
holder.number_votes.setText(context.getResources().getQuantityString(R.plurals.number_of_vote,status.getPoll().getVotes_count(),status.getPoll().getVotes_count()));
|
||||
holder.remaining_time.setText(context.getString(R.string.poll_finish_at, Helper.dateToStringPoll(poll.getExpires_at())));
|
||||
}else {
|
||||
holder.poll_container.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
|
||||
holder.status_action_container.setVisibility(View.GONE);
|
||||
|
|
|
@ -665,6 +665,18 @@ public class Helper {
|
|||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a date in String -> format yyyy-MM-dd HH:mm:ss
|
||||
* @param date Date
|
||||
* @return String
|
||||
*/
|
||||
public static String dateToStringPoll(Date date) {
|
||||
if( date == null)
|
||||
return null;
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm",Locale.getDefault());
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a date in String -> format yyyy-MM-dd HH:mm:ss
|
||||
* @param date Date
|
||||
|
|
|
@ -725,7 +725,11 @@
|
|||
android:id="@+id/status_peertube_delete"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>/
|
||||
</LinearLayout>
|
||||
<include
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
layout="@layout/layout_poll" />
|
||||
<LinearLayout
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginLeft="60dp"
|
||||
|
|
|
@ -656,7 +656,10 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
layout="@layout/layout_poll" />
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="20dp"
|
||||
|
|
|
@ -657,7 +657,10 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
layout="@layout/layout_poll" />
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="20dp"
|
||||
|
|
|
@ -584,6 +584,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
/>
|
||||
|
||||
<include
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
layout="@layout/layout_poll" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status_toot_app"
|
||||
android:visibility="gone"
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2019 Thomas Schneider
|
||||
|
||||
This file is a part of Mastalab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:id="@+id/poll_container"
|
||||
android:visibility="gone"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
<LinearLayout
|
||||
android:visibility="gone"
|
||||
android:id="@+id/single_choice"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<RadioGroup
|
||||
android:id="@+id/radio_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UselessParent">
|
||||
<RadioButton
|
||||
android:id="@+id/r_choice_1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
/>
|
||||
<RadioButton
|
||||
android:id="@+id/r_choice_2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
/>
|
||||
<RadioButton
|
||||
android:id="@+id/r_choice_3"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
/>
|
||||
<RadioButton
|
||||
android:id="@+id/r_choice_4"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:visibility="gone"
|
||||
android:id="@+id/multiple_choice"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox
|
||||
android:id="@+id/c_choice_1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<CheckBox
|
||||
android:id="@+id/c_choice_2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<CheckBox
|
||||
android:id="@+id/c_choice_3"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<CheckBox
|
||||
android:id="@+id/c_choice_4"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
<Button
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:id="@+id/submit_vote"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:text="@string/vote"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<LinearLayout
|
||||
android:visibility="gone"
|
||||
android:id="@+id/rated"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<br.com.felix.horizontalbargraph.HorizontalBar
|
||||
android:id="@+id/choices"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@+id/number_votes"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<TextView
|
||||
android:text=" - "
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="HardcodedText" />
|
||||
<TextView
|
||||
android:id="@+id/remaining_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:id="@+id/refresh_poll"
|
||||
android:textColor="?colorAccent"
|
||||
android:text="@string/refresh_poll"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -58,7 +58,14 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<Spinner
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"></Spinner>
|
||||
android:id="@+id/poll_choice"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"/>
|
||||
<Spinner
|
||||
android:id="@+id/poll_duration"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -901,15 +901,39 @@
|
|||
<string name="featured_hashtags">Featured hashtags</string>
|
||||
<string name="filter_timeline_with_a_tag">Filter timeline with tags</string>
|
||||
<string name="no_tags">No tags</string>
|
||||
|
||||
<!-- end languages -->
|
||||
|
||||
<string name="poll">Poll</string>
|
||||
<string name="create_poll">Create a poll</string>
|
||||
<string name="poll_choice_1">Choice 1</string>
|
||||
<string name="poll_choice_2">Choice 2</string>
|
||||
<string name="poll_choice_3">Choice 3</string>
|
||||
<string name="poll_choice_4">Choice 4</string>
|
||||
<!-- end languages -->
|
||||
<string name="poll_invalid_choices">You need two choices at least for the poll!</string>
|
||||
<string name="done">Done</string>
|
||||
<string name="poll_finish_at">end at %s</string>
|
||||
<string name="refresh_poll">Refresh poll</string>
|
||||
<string name="vote">Vote</string>
|
||||
|
||||
<plurals name="number_of_vote">
|
||||
<item quantity="one">%d vote</item>
|
||||
<item quantity="other">%d votes</item>
|
||||
</plurals>
|
||||
|
||||
<string-array name="poll_choice_type">
|
||||
<item>Single choice</item>
|
||||
<item>Multiple choices</item>
|
||||
</string-array>
|
||||
<string-array name="poll_duration">
|
||||
<item>5 minutes</item>
|
||||
<item>30 minutes</item>
|
||||
<item>1 hour</item>
|
||||
<item>6 hours</item>
|
||||
<item>1 day</item>
|
||||
<item>3 days</item>
|
||||
<item>7 days</item>
|
||||
</string-array >
|
||||
|
||||
<string-array name="settings_video_mode">
|
||||
<item>Webview</item>
|
||||
|
|
Loading…
Reference in New Issue