finalized poll create support
This commit is contained in:
parent
7c19241787
commit
ca38ed95fc
|
@ -586,7 +586,7 @@ public class Mastodon implements Connection {
|
|||
PollUpdate poll = update.getPoll();
|
||||
for (String option : poll.getOptions())
|
||||
params.add("poll[options][]=" + StringTools.encode(option));
|
||||
params.add("poll[expires_in]=" + poll.getValidity());
|
||||
params.add("poll[expires_in]=" + poll.getDuration());
|
||||
params.add("poll[multiple]=" + poll.multipleChoiceEnabled());
|
||||
params.add("poll[hide_totals]=" + poll.hideTotalVotes());
|
||||
}
|
||||
|
|
|
@ -145,9 +145,9 @@ public class MastodonPoll implements Poll {
|
|||
/**
|
||||
* @param json mastodon poll json format
|
||||
*/
|
||||
private MastodonOption(JSONObject json) throws JSONException {
|
||||
voteCount = json.getInt("votes_count");
|
||||
title = json.getString("title");
|
||||
private MastodonOption(JSONObject json) {
|
||||
voteCount = json.optInt("votes_count", 0);
|
||||
title = json.optString("title", "-");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import java.util.List;
|
|||
*/
|
||||
public class PollUpdate {
|
||||
|
||||
private int validity;
|
||||
private int duration;
|
||||
private boolean multipleChoice;
|
||||
private boolean hideTotals;
|
||||
private List<String> options;
|
||||
|
@ -28,8 +28,8 @@ public class PollUpdate {
|
|||
*
|
||||
* @return time until the poll is finnished
|
||||
*/
|
||||
public int getValidity() {
|
||||
return validity;
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,14 +49,37 @@ public class PollUpdate {
|
|||
/**
|
||||
* @return an array of vote options
|
||||
*/
|
||||
public String[] getOptions() {
|
||||
return options.toArray(new String[0]);
|
||||
public List<String> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param duration duration in seconds
|
||||
*/
|
||||
public void setDuration(int duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
|
||||
public void hideVotes(boolean hideTotals) {
|
||||
this.hideTotals = hideTotals;
|
||||
}
|
||||
|
||||
|
||||
public void setMultipleChoice(boolean multipleChoice) {
|
||||
this.multipleChoice = multipleChoice;
|
||||
}
|
||||
|
||||
|
||||
public void setOptions(List<String> options) {
|
||||
this.options.clear();
|
||||
this.options.addAll(options);
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "valid=" + validity + " multiple=" + multipleChoice + "options=" + options.size();
|
||||
return "valid=" + duration + " multiple=" + multipleChoice + "options=" + options.size();
|
||||
}
|
||||
}
|
|
@ -162,8 +162,11 @@ public class StatusUpdate {
|
|||
*
|
||||
* @param poll poll information
|
||||
*/
|
||||
public void addPoll(@NonNull PollUpdate poll) {
|
||||
if (attachment == EMPTY) {
|
||||
public void addPoll(@Nullable PollUpdate poll) {
|
||||
if (poll == null) {
|
||||
this.poll = null;
|
||||
attachment = EMPTY;
|
||||
} else if (attachment == EMPTY) {
|
||||
this.poll = poll;
|
||||
attachment = POLL;
|
||||
attachmentLimitReached = true;
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.nuclearfog.twidda.R;
|
|||
import org.nuclearfog.twidda.backend.async.AsyncExecutor.AsyncCallback;
|
||||
import org.nuclearfog.twidda.backend.async.StatusUpdater;
|
||||
import org.nuclearfog.twidda.backend.async.StatusUpdater.StatusUpdateResult;
|
||||
import org.nuclearfog.twidda.backend.helper.PollUpdate;
|
||||
import org.nuclearfog.twidda.backend.helper.StatusUpdate;
|
||||
import org.nuclearfog.twidda.backend.utils.AppStyles;
|
||||
import org.nuclearfog.twidda.backend.utils.ErrorHandler;
|
||||
|
@ -33,6 +34,8 @@ import org.nuclearfog.twidda.ui.adapter.IconAdapter;
|
|||
import org.nuclearfog.twidda.ui.adapter.IconAdapter.OnMediaClickListener;
|
||||
import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog;
|
||||
import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog.OnConfirmListener;
|
||||
import org.nuclearfog.twidda.ui.dialogs.PollDialog;
|
||||
import org.nuclearfog.twidda.ui.dialogs.PollDialog.PollUpdateCallback;
|
||||
import org.nuclearfog.twidda.ui.dialogs.ProgressDialog;
|
||||
import org.nuclearfog.twidda.ui.dialogs.ProgressDialog.OnProgressStopListener;
|
||||
|
||||
|
@ -42,7 +45,7 @@ import org.nuclearfog.twidda.ui.dialogs.ProgressDialog.OnProgressStopListener;
|
|||
* @author nuclearfog
|
||||
*/
|
||||
public class StatusEditor extends MediaActivity implements OnClickListener, OnProgressStopListener, OnConfirmListener,
|
||||
OnMediaClickListener, AsyncCallback<StatusUpdateResult>, TextWatcher {
|
||||
OnMediaClickListener, AsyncCallback<StatusUpdateResult>, TextWatcher, PollUpdateCallback {
|
||||
|
||||
/**
|
||||
* key to add a statusd ID to reply
|
||||
|
@ -64,7 +67,9 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
|
||||
private ConfirmDialog confirmDialog;
|
||||
private ProgressDialog loadingCircle;
|
||||
private PollDialog pollDialog;
|
||||
private IconAdapter adapter;
|
||||
|
||||
private StatusUpdate statusUpdate = new StatusUpdate();
|
||||
|
||||
|
||||
|
@ -82,6 +87,7 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
ImageView background = findViewById(R.id.popup_status_background);
|
||||
ImageButton statusButton = findViewById(R.id.popup_status_send);
|
||||
ImageButton closeButton = findViewById(R.id.popup_status_close);
|
||||
ImageButton addPoll = findViewById(R.id.popup_status_add_poll);
|
||||
RecyclerView iconList = findViewById(R.id.popup_status_media_icons);
|
||||
EditText statusText = findViewById(R.id.popup_status_input);
|
||||
locationBtn = findViewById(R.id.popup_status_add_location);
|
||||
|
@ -92,6 +98,7 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
settings = GlobalSettings.getInstance(this);
|
||||
loadingCircle = new ProgressDialog(this);
|
||||
confirmDialog = new ConfirmDialog(this);
|
||||
pollDialog = new PollDialog(this, this);
|
||||
AppStyles.setEditorTheme(root, background);
|
||||
|
||||
if (!settings.getLogin().getConfiguration().locationSupported()) {
|
||||
|
@ -109,6 +116,7 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
iconList.setAdapter(adapter);
|
||||
|
||||
closeButton.setOnClickListener(this);
|
||||
addPoll.setOnClickListener(this);
|
||||
statusButton.setOnClickListener(this);
|
||||
mediaBtn.setOnClickListener(this);
|
||||
locationBtn.setOnClickListener(this);
|
||||
|
@ -169,6 +177,10 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
else if (v.getId() == R.id.popup_status_close) {
|
||||
showClosingMsg();
|
||||
}
|
||||
// show poll dialog
|
||||
else if (v.getId() == R.id.popup_status_add_poll) {
|
||||
pollDialog.show(statusUpdate.getPoll());
|
||||
}
|
||||
// Add media to the status
|
||||
else if (v.getId() == R.id.popup_status_add_media) {
|
||||
if (statusUpdate.getAttachmentType() == StatusUpdate.EMPTY) {
|
||||
|
@ -295,6 +307,12 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPollUpdate(@Nullable PollUpdate update) {
|
||||
statusUpdate.addPoll(update);
|
||||
}
|
||||
|
||||
/**
|
||||
* show confirmation dialog when closing edited status
|
||||
*/
|
||||
|
|
|
@ -1,42 +1,139 @@
|
|||
package org.nuclearfog.twidda.ui.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerView.Adapter;
|
||||
|
||||
import org.nuclearfog.twidda.ui.adapter.holder.EditOptionsHolder;
|
||||
import org.nuclearfog.twidda.ui.adapter.holder.EditOptionsHolder.OnOptionChangedListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* RecyclerView adapter used to show option items
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class EditOptionsAdapter extends Adapter {
|
||||
public class EditOptionsAdapter extends Adapter<EditOptionsHolder> implements OnOptionChangedListener {
|
||||
|
||||
/**
|
||||
* minimum option count
|
||||
*/
|
||||
private static final int MIN_OPTIONS = 2;
|
||||
|
||||
public EditOptionsAdapter(Context context) {}
|
||||
/**
|
||||
* maximum option count
|
||||
*/
|
||||
private static final int MAX_OPTIONS = 4;
|
||||
|
||||
private LinkedList<String> options;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public EditOptionsAdapter() {
|
||||
options = new LinkedList<>();
|
||||
for (int i = 0 ; i < MIN_OPTIONS ; i++)
|
||||
options.add("");
|
||||
options.add(null);
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return null;
|
||||
public EditOptionsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new EditOptionsHolder(parent, this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
|
||||
public void onBindViewHolder(@NonNull EditOptionsHolder holder, int position) {
|
||||
if (position < MIN_OPTIONS) {
|
||||
holder.setState(position, EditOptionsHolder.STATE_LOCKED);
|
||||
} else if (options.get(position) != null) {
|
||||
holder.setState(position, EditOptionsHolder.STATE_ACTIVE);
|
||||
} else {
|
||||
holder.setState(position, EditOptionsHolder.STATE_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return 0;
|
||||
return options.size();
|
||||
}
|
||||
|
||||
|
||||
public interface OnOptionChangedListener {
|
||||
@Override
|
||||
public void onOptionAdd(int position) {
|
||||
if (options.size() < MAX_OPTIONS) {
|
||||
// add empty item
|
||||
options.add(position, "");
|
||||
notifyItemInserted(position);
|
||||
// update upper items
|
||||
notifyItemRangeChanged(position + 1, MAX_OPTIONS - position - 1);
|
||||
} else {
|
||||
options.set(position, "");
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onOptionRemove(int position) {
|
||||
if (position < MAX_OPTIONS - 1) {
|
||||
// remove item
|
||||
options.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
// update upper items
|
||||
notifyItemRangeChanged(position, MAX_OPTIONS - position);
|
||||
// add placeholder item
|
||||
if (options.peekLast() != null) {
|
||||
options.add(null);
|
||||
notifyItemInserted(options.size());
|
||||
}
|
||||
} else {
|
||||
options.set(position, null);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void OnOptionChange(int position, String name) {
|
||||
options.set(position, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* set option names
|
||||
*
|
||||
* @param newOptions list of option name strings
|
||||
*/
|
||||
public void setOptions(List<String> newOptions) {
|
||||
options.clear();
|
||||
options.addAll(newOptions);
|
||||
for (int i = options.size() ; i < MIN_OPTIONS; i++) {
|
||||
options.add("");
|
||||
}
|
||||
options.add(null);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* get option names
|
||||
*
|
||||
* @return list of option name strings
|
||||
*/
|
||||
public List<String> getOptions() {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String option : options) {
|
||||
if (option != null && !option.trim().isEmpty()) {
|
||||
result.add(option);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -114,40 +114,40 @@ public class IconAdapter extends Adapter<IconHolder> implements OnHolderClickLis
|
|||
}
|
||||
|
||||
/**
|
||||
* add a single image icon
|
||||
* append image icon at the end
|
||||
*/
|
||||
public void addImageItem() {
|
||||
if (invert) {
|
||||
items.add(0, IconHolder.TYPE_IMAGE);
|
||||
notifyItemInserted(0);
|
||||
} else {
|
||||
items.add(IconHolder.TYPE_IMAGE);
|
||||
notifyItemInserted(items.size() - 1);
|
||||
}
|
||||
appendItem(IconHolder.TYPE_IMAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* add a single gif item
|
||||
*/
|
||||
public void addGifItem() {
|
||||
if (invert) {
|
||||
items.add(0, IconHolder.TYPE_GIF);
|
||||
notifyItemInserted(0);
|
||||
} else {
|
||||
items.add(IconHolder.TYPE_GIF);
|
||||
notifyItemInserted(items.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add a single video item
|
||||
* append video icon at the end
|
||||
*/
|
||||
public void addVideoItem() {
|
||||
appendItem(IconHolder.TYPE_VIDEO);
|
||||
}
|
||||
|
||||
/**
|
||||
* append GIF icon at the end
|
||||
*/
|
||||
public void addGifItem() {
|
||||
appendItem(IconHolder.TYPE_GIF);
|
||||
}
|
||||
|
||||
/**
|
||||
* append location icon at the end
|
||||
*/
|
||||
public void addLocation() {
|
||||
appendItem(IconHolder.TYPE_LOCATION);
|
||||
}
|
||||
|
||||
|
||||
public void appendItem(int itemType) {
|
||||
if (invert) {
|
||||
items.add(0, IconHolder.TYPE_VIDEO);
|
||||
items.add(0, itemType);
|
||||
notifyItemInserted(0);
|
||||
} else {
|
||||
items.add(IconHolder.TYPE_VIDEO);
|
||||
items.add(itemType);
|
||||
notifyItemInserted(items.size() - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
package org.nuclearfog.twidda.ui.adapter.holder;
|
||||
|
||||
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.EditText;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
|
||||
import org.nuclearfog.twidda.R;
|
||||
import org.nuclearfog.twidda.backend.utils.AppStyles;
|
||||
import org.nuclearfog.twidda.config.GlobalSettings;
|
||||
|
||||
/**
|
||||
* ViewHolder implementation for {@link org.nuclearfog.twidda.ui.adapter.EditOptionsAdapter}
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class EditOptionsHolder extends ViewHolder implements OnClickListener, TextWatcher {
|
||||
|
||||
/**
|
||||
* indicates that the item is locked and can't be removed
|
||||
*/
|
||||
public static final int STATE_LOCKED = 1;
|
||||
|
||||
/**
|
||||
* indicates that the item is activated & removable
|
||||
*/
|
||||
public static final int STATE_ACTIVE = 2;
|
||||
|
||||
/**
|
||||
* indicates that the item is disabled (placeholder)
|
||||
*/
|
||||
public static final int STATE_DISABLED = 3;
|
||||
|
||||
|
||||
private EditText option_name;
|
||||
private ImageButton option_button;
|
||||
|
||||
private OnOptionChangedListener listener;
|
||||
private GlobalSettings settings;
|
||||
|
||||
private int state = STATE_LOCKED;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public EditOptionsHolder(ViewGroup parent, OnOptionChangedListener listener) {
|
||||
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_option_edit, parent, false));
|
||||
settings = GlobalSettings.getInstance(parent.getContext());
|
||||
this.listener = listener;
|
||||
|
||||
option_name = itemView.findViewById(R.id.item_option_edit_name);
|
||||
option_button = itemView.findViewById(R.id.item_option_edit_action);
|
||||
AppStyles.setTheme((ViewGroup) itemView);
|
||||
|
||||
option_button.setOnClickListener(this);
|
||||
option_name.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = getLayoutPosition();
|
||||
if (position != NO_POSITION) {
|
||||
if (v.getId() == R.id.item_option_edit_action) {
|
||||
switch (state) {
|
||||
case STATE_ACTIVE:
|
||||
listener.onOptionRemove(position);
|
||||
option_button.setImageResource(R.drawable.add);
|
||||
AppStyles.setButtonColor(option_button, settings.getIconColor());
|
||||
option_name.setEnabled(true);
|
||||
break;
|
||||
|
||||
case STATE_DISABLED:
|
||||
listener.onOptionAdd(position);
|
||||
AppStyles.setButtonColor(option_button, settings.getIconColor());
|
||||
option_name.setEnabled(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
int position = getLayoutPosition();
|
||||
if (position != NO_POSITION) {
|
||||
listener.OnOptionChange(position, s.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set option state and option hint
|
||||
*
|
||||
* @param position position of the item
|
||||
* @param state state to set {@link #STATE_LOCKED,#STATE_ACTIVE,#STATE_DISABLED}
|
||||
*/
|
||||
public void setState(int position, int state) {
|
||||
this.state = state;
|
||||
switch (state) {
|
||||
case STATE_LOCKED:
|
||||
option_name.setEnabled(true);
|
||||
option_button.setImageResource(R.drawable.circle);
|
||||
break;
|
||||
|
||||
case STATE_ACTIVE:
|
||||
option_name.setEnabled(true);
|
||||
option_button.setImageResource(R.drawable.cross);
|
||||
break;
|
||||
|
||||
case STATE_DISABLED:
|
||||
option_name.setEnabled(false);
|
||||
option_button.setImageResource(R.drawable.add);
|
||||
break;
|
||||
}
|
||||
AppStyles.setButtonColor(option_button, settings.getIconColor());
|
||||
String hint = option_name.getContext().getString(R.string.dialog_poll_option_edit_hint, position + 1);
|
||||
option_name.setHint(hint);
|
||||
}
|
||||
|
||||
/**
|
||||
* listener for option changes
|
||||
*/
|
||||
public interface OnOptionChangedListener {
|
||||
|
||||
/**
|
||||
* called when an option is added
|
||||
*
|
||||
* @param position position where to insert the new item
|
||||
*/
|
||||
void onOptionAdd(int position);
|
||||
|
||||
/**
|
||||
* called when an option is removed
|
||||
*
|
||||
* @param position position of the old item
|
||||
*/
|
||||
void onOptionRemove(int position);
|
||||
|
||||
/**
|
||||
* called when the option name changes
|
||||
*
|
||||
* @param position position of the item
|
||||
* @param name new option name
|
||||
*/
|
||||
void OnOptionChange(int position, String name);
|
||||
}
|
||||
}
|
|
@ -2,28 +2,118 @@ package org.nuclearfog.twidda.ui.dialogs;
|
|||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.kyleduo.switchbutton.SwitchButton;
|
||||
|
||||
import org.nuclearfog.twidda.R;
|
||||
import org.nuclearfog.twidda.backend.helper.PollUpdate;
|
||||
import org.nuclearfog.twidda.backend.utils.AppStyles;
|
||||
import org.nuclearfog.twidda.ui.adapter.EditOptionsAdapter;
|
||||
|
||||
/**
|
||||
* Dialog class used to show poll editor
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class PollDialog extends Dialog {
|
||||
public class PollDialog extends Dialog implements OnClickListener {
|
||||
|
||||
private EditOptionsAdapter optionAdapter;
|
||||
private SwitchButton multiple_choice, hide_votes;
|
||||
private Spinner timeUnitSelector;
|
||||
private EditText durationInput;
|
||||
|
||||
private PollUpdateCallback callback;
|
||||
private PollUpdate poll;
|
||||
|
||||
|
||||
public PollDialog(@NonNull Context context) {
|
||||
public PollDialog(@NonNull Context context, PollUpdateCallback callback) {
|
||||
super(context, R.style.PollDialog);
|
||||
this.callback = callback;
|
||||
setContentView(R.layout.dialog_poll);
|
||||
ViewGroup root = findViewById(R.id.dialog_poll_root);
|
||||
RecyclerView optionsList = findViewById(R.id.dialog_poll_option_list);
|
||||
Button confirm = findViewById(R.id.dialog_poll_create);
|
||||
durationInput = findViewById(R.id.dialog_poll_duration_input);
|
||||
timeUnitSelector = findViewById(R.id.dialog_poll_duration_timeunit);
|
||||
multiple_choice = findViewById(R.id.dialog_poll_mul_choice);
|
||||
hide_votes = findViewById(R.id.dialog_poll_hide_total);
|
||||
|
||||
ArrayAdapter<String> timeUnitAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_dropdown_item);
|
||||
timeUnitAdapter.addAll(context.getResources().getStringArray(R.array.timeunits));
|
||||
timeUnitSelector.setAdapter(timeUnitAdapter);
|
||||
timeUnitSelector.setSelected(true);
|
||||
|
||||
optionAdapter = new EditOptionsAdapter();
|
||||
optionsList.setAdapter(optionAdapter);
|
||||
AppStyles.setTheme(root);
|
||||
|
||||
confirm.setOnClickListener(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getId() == R.id.dialog_poll_create) {
|
||||
String durationStr = durationInput.getText().toString();
|
||||
if (durationStr.matches("\\d{1,3}")) {
|
||||
int duration = Integer.parseInt(durationStr);
|
||||
switch (timeUnitSelector.getSelectedItemPosition()) {
|
||||
// minutes
|
||||
case 0:
|
||||
poll.setDuration(duration * 60);
|
||||
break;
|
||||
|
||||
public void show(@NonNull PollUpdate poll) {
|
||||
// hours
|
||||
case 1:
|
||||
poll.setDuration(duration * 3600);
|
||||
break;
|
||||
|
||||
// days
|
||||
case 2:
|
||||
poll.setDuration(duration * 86400);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// default 24h
|
||||
poll.setDuration(86400);
|
||||
}
|
||||
poll.setMultipleChoice(multiple_choice.isChecked());
|
||||
poll.hideVotes(hide_votes.isChecked());
|
||||
poll.setOptions(optionAdapter.getOptions());
|
||||
callback.onPollUpdate(poll);
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void show(@Nullable PollUpdate poll) {
|
||||
if (!isShowing()) {
|
||||
if (poll != null) {
|
||||
optionAdapter.setOptions(poll.getOptions());
|
||||
multiple_choice.setCheckedImmediately(poll.multipleChoiceEnabled());
|
||||
hide_votes.setCheckedImmediately(poll.hideTotalVotes());
|
||||
this.poll = poll;
|
||||
} else {
|
||||
this.poll = new PollUpdate();
|
||||
}
|
||||
super.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface PollUpdateCallback {
|
||||
|
||||
void onPollUpdate(@Nullable PollUpdate update);
|
||||
}
|
||||
}
|
|
@ -77,7 +77,6 @@ public class NotificationFragment extends ListFragment implements OnNotification
|
|||
if (!adapter.isEmpty())
|
||||
sinceId = adapter.getItemId(0);
|
||||
load(sinceId, 0L, 0);
|
||||
setRefresh(true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,6 +85,7 @@ public class NotificationFragment extends ListFragment implements OnNotification
|
|||
adapter = new NotificationAdapter(requireContext(), this);
|
||||
setAdapter(adapter);
|
||||
load(0L, 0L, 0);
|
||||
setRefresh(true);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/dialog_poll_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/dialog_poll_root_layout_padding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_poll_title"
|
||||
|
@ -11,6 +13,7 @@
|
|||
android:layout_marginBottom="@dimen/dialog_poll_layout_margins"
|
||||
android:text="@string/dialog_poll_title"
|
||||
android:textSize="@dimen/dialog_poll_title_textsize"
|
||||
android:lines="1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/dialog_poll_option_list"
|
||||
|
@ -19,29 +22,84 @@
|
|||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/dialog_poll_option_list"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_height="@dimen/dialog_poll_list_height"
|
||||
android:layout_marginBottom="@dimen/dialog_poll_layout_margins"
|
||||
android:orientation="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dialog_poll_title"
|
||||
app:layout_constraintBottom_toTopOf="@id/dialog_poll_list_barrier"
|
||||
app:layout_constraintBottom_toTopOf="@id/dialog_poll_switch_barrier"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/dialog_poll_switch_barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="dialog_poll_mul_choice, dialog_poll_mul_choice_label, dialog_poll_hide_total, dialog_poll_hide_total_label"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_poll_mul_choice_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_poll_mc"
|
||||
android:lines="1"
|
||||
android:gravity="end"
|
||||
android:textSize="@dimen/dialog_poll_textsize_small"
|
||||
android:layout_marginEnd="@dimen/dialog_poll_layout_margins"
|
||||
app:layout_constraintHorizontal_weight="4"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/dialog_poll_mul_choice"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dialog_poll_mul_choice"
|
||||
app:layout_constraintEnd_toStartOf="@id/dialog_poll_mul_choice" />
|
||||
|
||||
<com.kyleduo.switchbutton.SwitchButton
|
||||
android:id="@+id/dialog_poll_mul_choice"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toEndOf="@id/dialog_poll_mul_choice_label"
|
||||
app:layout_constraintBottom_toTopOf="@id/dialog_poll_list_barrier"
|
||||
app:layout_constraintEnd_toStartOf="@id/dialog_poll_hide_total_label"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_poll_hide_total_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_poll_hide"
|
||||
android:lines="1"
|
||||
android:gravity="end"
|
||||
android:textSize="@dimen/dialog_poll_textsize_small"
|
||||
android:layout_marginEnd="@dimen/dialog_poll_layout_margins"
|
||||
app:layout_constraintHorizontal_weight="3"
|
||||
app:layout_constraintStart_toEndOf="@id/dialog_poll_mul_choice"
|
||||
app:layout_constraintTop_toTopOf="@id/dialog_poll_hide_total"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dialog_poll_hide_total"
|
||||
app:layout_constraintEnd_toStartOf="@id/dialog_poll_hide_total"/>
|
||||
|
||||
<com.kyleduo.switchbutton.SwitchButton
|
||||
android:id="@+id/dialog_poll_hide_total"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toEndOf="@id/dialog_poll_hide_total_label"
|
||||
app:layout_constraintBottom_toTopOf="@id/dialog_poll_list_barrier"
|
||||
app:layout_constraintEnd_toStartOf="@id/dialog_poll_switch_placeholder"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/dialog_poll_switch_placeholder"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintStart_toEndOf="@id/dialog_poll_hide_total"
|
||||
app:layout_constraintTop_toTopOf="@id/dialog_poll_hide_total"
|
||||
app:layout_constraintBottom_toTopOf="@id/dialog_poll_list_barrier"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/dialog_poll_list_barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="dialog_poll_duration_input,dialog_poll_duration_label,dialog_poll_duration_timeunit"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_poll_duration_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_poll_duration_label"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dialog_poll_option_list"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/dialog_poll_duration_input"/>
|
||||
app:constraint_referenced_ids="dialog_poll_duration_input,dialog_poll_duration_timeunit,dialog_poll_create"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_poll_duration_input"
|
||||
|
@ -54,8 +112,10 @@
|
|||
android:hint="@string/dialog_poll_duration_hint"
|
||||
android:layout_marginStart="@dimen/dialog_poll_layout_margins"
|
||||
android:layout_marginEnd="@dimen/dialog_poll_layout_margins"
|
||||
app:layout_constraintStart_toEndOf="@id/dialog_poll_duration_label"
|
||||
app:layout_constraintTop_toBottomOf="@id/dialog_poll_option_list"
|
||||
android:lines="1"
|
||||
app:layout_constraintHorizontal_weight="2"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dialog_poll_list_barrier"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/dialog_poll_duration_timeunit" />
|
||||
|
||||
|
@ -63,9 +123,23 @@
|
|||
android:id="@+id/dialog_poll_duration_timeunit"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintHorizontal_weight="3"
|
||||
app:layout_constraintStart_toEndOf="@id/dialog_poll_duration_input"
|
||||
app:layout_constraintTop_toBottomOf="@id/dialog_poll_option_list"
|
||||
app:layout_constraintTop_toBottomOf="@id/dialog_poll_list_barrier"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
app:layout_constraintEnd_toStartOf="@id/dialog_poll_create" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_poll_create"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dialog_poll_button_height"
|
||||
android:text="@string/dialog_poll_button"
|
||||
android:lines="1"
|
||||
app:layout_constraintHorizontal_weight="2"
|
||||
app:layout_constraintStart_toEndOf="@id/dialog_poll_duration_timeunit"
|
||||
app:layout_constraintTop_toBottomOf="@id/dialog_poll_list_barrier"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
style="@style/FeedbackButton" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="@dimen/item_option_edit_layout_padding">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/item_option_edit_action"
|
||||
android:layout_width="@dimen/item_option_edit_button_size"
|
||||
android:layout_height="@dimen/item_option_edit_button_size"
|
||||
android:padding="@dimen/item_option_edit_drawable_padding"
|
||||
android:src="@drawable/add"
|
||||
style="@style/FeedbackButton" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/item_option_edit_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:background="@android:color/transparent"
|
||||
android:enabled="false"
|
||||
android:lines="1"
|
||||
android:layout_marginStart="@dimen/item_option_edit_layout_margin"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -17,7 +17,7 @@
|
|||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintWidth_percent="0.85"
|
||||
app:layout_constraintHeight_percent="0.4"
|
||||
app:layout_constraintHeight_percent="0.5"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<EditText
|
||||
|
@ -65,12 +65,11 @@
|
|||
android:contentDescription="@string/status_add_image"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/attachment"
|
||||
app:layout_constraintStart_toEndOf="@id/popup_status_media_icons"
|
||||
app:layout_constraintBottom_toBottomOf="@id/popup_status_background"
|
||||
app:layout_constraintEnd_toStartOf="@id/popup_status_add_location"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintDimensionRatio="1.0"
|
||||
app:layout_constraintWidth_percent="0.1"
|
||||
app:layout_constraintWidth_percent="@dimen/popup_status_button_size"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<ProgressBar
|
||||
|
@ -94,12 +93,27 @@
|
|||
android:contentDescription="@string/send_status"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/location"
|
||||
app:layout_constraintStart_toEndOf="@id/popup_status_add_media"
|
||||
app:layout_constraintBottom_toBottomOf="@id/popup_status_background"
|
||||
app:layout_constraintEnd_toStartOf="@id/popup_status_add_poll"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintDimensionRatio="1.0"
|
||||
app:layout_constraintWidth_percent="@dimen/popup_status_button_size"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/popup_status_add_poll"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:padding="@dimen/popup_status_button_padding"
|
||||
android:layout_marginBottom="@dimen/popup_status_margin_layout"
|
||||
android:layout_marginEnd="@dimen/popup_status_button_margin"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/poll"
|
||||
app:layout_constraintBottom_toBottomOf="@id/popup_status_background"
|
||||
app:layout_constraintEnd_toStartOf="@id/popup_status_send"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintDimensionRatio="1.0"
|
||||
app:layout_constraintWidth_percent="0.1"
|
||||
app:layout_constraintWidth_percent="@dimen/popup_status_button_size"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<ImageButton
|
||||
|
@ -112,12 +126,11 @@
|
|||
android:contentDescription="@string/send_status"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/post"
|
||||
app:layout_constraintStart_toEndOf="@id/popup_status_add_location"
|
||||
app:layout_constraintBottom_toBottomOf="@id/popup_status_background"
|
||||
app:layout_constraintEnd_toStartOf="@id/popup_status_close"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintDimensionRatio="1.0"
|
||||
app:layout_constraintWidth_percent="0.1"
|
||||
app:layout_constraintWidth_percent="@dimen/popup_status_button_size"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<ImageButton
|
||||
|
@ -130,12 +143,11 @@
|
|||
android:contentDescription="@string/status_close"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/cross"
|
||||
app:layout_constraintStart_toEndOf="@id/popup_status_send"
|
||||
app:layout_constraintBottom_toBottomOf="@id/popup_status_background"
|
||||
app:layout_constraintEnd_toEndOf="@id/popup_status_background"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintDimensionRatio="1.0"
|
||||
app:layout_constraintWidth_percent="0.1"
|
||||
app:layout_constraintWidth_percent="@dimen/popup_status_button_size"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -54,4 +54,10 @@
|
|||
<item>@drawable/follower</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="timeunits">
|
||||
<item>minutes</item>
|
||||
<item>hours</item>
|
||||
<item>days</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
|
@ -161,6 +161,7 @@
|
|||
<dimen name="popup_status_button_margin">7dp</dimen>
|
||||
<dimen name="popup_status_icon_list_margin">7dp</dimen>
|
||||
<dimen name="popup_status_button_padding">7dp</dimen>
|
||||
<dimen name="popup_status_button_size">0.09</dimen>
|
||||
|
||||
<!--dimens of popup_message.xml-->
|
||||
<dimen name="popup_message_margin_background">10dp</dimen>
|
||||
|
@ -241,8 +242,12 @@
|
|||
<dimen name="dialog_connection_textsizte_normal">13sp</dimen>
|
||||
|
||||
<!--dimens of dialog_poll.xml-->
|
||||
<dimen name="dialog_poll_list_height">200sp</dimen>
|
||||
<dimen name="dialog_poll_root_layout_padding">5dp</dimen>
|
||||
<dimen name="dialog_poll_layout_margins">3dp</dimen>
|
||||
<dimen name="dialog_poll_textsize_small">12sp</dimen>
|
||||
<dimen name="dialog_poll_title_textsize">18sp</dimen>
|
||||
<dimen name="dialog_poll_button_height">20sp</dimen>
|
||||
|
||||
<!--dimens of tabitem.xml-->
|
||||
<dimen name="tabitem_icon_size">22sp</dimen>
|
||||
|
@ -274,10 +279,16 @@
|
|||
<!-- dimens of item_icon.xml -->
|
||||
<dimen name="item_icon_indicator_margin">2dp</dimen>
|
||||
|
||||
<!-- dimens of item_option -->
|
||||
<!-- dimens of item_option.xml -->
|
||||
<dimen name="item_option_icon_size">20sp</dimen>
|
||||
<dimen name="item_option_text_size">13sp</dimen>
|
||||
<dimen name="item_option_layout_padding">5dp</dimen>
|
||||
<dimen name="item_option_button_margin">10dp</dimen>
|
||||
|
||||
<!--dimens of item_option_edit.xml -->
|
||||
<dimen name="item_option_edit_layout_padding">3dp</dimen>
|
||||
<dimen name="item_option_edit_button_size">24dp</dimen>
|
||||
<dimen name="item_option_edit_drawable_padding">2dp</dimen>
|
||||
<dimen name="item_option_edit_layout_margin">5dp</dimen>
|
||||
|
||||
</resources>
|
|
@ -222,8 +222,12 @@
|
|||
<string name="profile_bio">Bio</string>
|
||||
<string name="connection_discard">discard</string>
|
||||
<string name="dialog_poll_title">create poll</string>
|
||||
<string name="dialog_poll_button">create</string>
|
||||
<string name="dialog_poll_mc">multiple choice</string>
|
||||
<string name="dialog_poll_hide">hide votes</string>
|
||||
<string name="dialog_poll_option_edit_hint">Option %1$d</string>
|
||||
<string name="dialog_poll_duration_label">Duration:</string>
|
||||
<string name="dialog_poll_duration_hint">count</string>
|
||||
<string name="dialog_poll_duration_hint">Duration</string>
|
||||
<string name="confirm_discard">discard changes?</string>
|
||||
<string name="user_data">User data</string>
|
||||
<string name="follows_you">follows you</string>
|
||||
|
|
Loading…
Reference in New Issue