Fixes crash due to unexpected GIFV attachments.

Also when composing a reply it defaults the visibility to the status being replied to. Also, public timeline visibility is no longer in the options list when replying, it never had an effect and was just erroneously left there.
This commit is contained in:
Vavassor 2017-03-05 19:58:36 -05:00
parent b0b84509cd
commit 96d9444e0b
4 changed files with 52 additions and 6 deletions

View File

@ -89,6 +89,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
@ -345,6 +346,12 @@ public class ComposeActivity extends BaseActivity {
String[] mentionedUsernames = null;
if (intent != null) {
inReplyToId = intent.getStringExtra("in_reply_to_id");
String replyVisibility = intent.getStringExtra("reply_visibility");
if (replyVisibility != null) {
/* Override any remembered visibilty and instead adopt the visibility of the status
* to which this replies. */
statusVisibility = replyVisibility;
}
mentionedUsernames = intent.getStringArrayExtra("mentioned_usernames");
}
@ -363,7 +370,7 @@ public class ComposeActivity extends BaseActivity {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int left = STATUS_CHARACTER_LIMIT - s.length();
charactersLeft.setText(Integer.toString(left));
charactersLeft.setText(String.format(Locale.getDefault(), "%d", left));
}
@Override
@ -435,7 +442,7 @@ public class ComposeActivity extends BaseActivity {
public void onClick(View v) {
ComposeOptionsFragment fragment = ComposeOptionsFragment.newInstance(
statusVisibility, statusMarkSensitive, statusHideText,
showMarkSensitive,
showMarkSensitive, inReplyToId != null,
new ComposeOptionsFragment.Listener() {
@Override
public int describeContents() {
@ -498,6 +505,11 @@ public class ComposeActivity extends BaseActivity {
@Override
protected void onPause() {
super.onPause();
if (inReplyToId != null) {
/* Don't save the visibility setting for replies because they adopt the visibility of
* the status they reply to and that behaviour needs to be kept separate. */
return;
}
SharedPreferences preferences = getSharedPreferences(
getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();

View File

@ -9,6 +9,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
public class ComposeOptionsFragment extends BottomSheetDialogFragment {
@ -21,7 +22,7 @@ public class ComposeOptionsFragment extends BottomSheetDialogFragment {
private Listener listener;
public static ComposeOptionsFragment newInstance(String visibility, boolean markSensitive,
boolean hideText, boolean showMarkSensitive, Listener listener) {
boolean hideText, boolean showMarkSensitive, boolean isReply, Listener listener) {
Bundle arguments = new Bundle();
ComposeOptionsFragment fragment = new ComposeOptionsFragment();
arguments.putParcelable("listener", listener);
@ -29,6 +30,7 @@ public class ComposeOptionsFragment extends BottomSheetDialogFragment {
arguments.putBoolean("markSensitive", markSensitive);
arguments.putBoolean("hideText", hideText);
arguments.putBoolean("showMarkSensitive", showMarkSensitive);
arguments.putBoolean("isReply", isReply);
fragment.setArguments(arguments);
return fragment;
}
@ -45,9 +47,15 @@ public class ComposeOptionsFragment extends BottomSheetDialogFragment {
boolean statusMarkSensitive = arguments.getBoolean("markSensitive");
boolean statusHideText = arguments.getBoolean("hideText");
boolean showMarkSensitive = arguments.getBoolean("showMarkSensitive");
boolean isReply = arguments.getBoolean("isReply");
RadioGroup radio = (RadioGroup) rootView.findViewById(R.id.radio_visibility);
int radioCheckedId = R.id.radio_public;
int radioCheckedId;
if (!isReply) {
radioCheckedId = R.id.radio_public;
} else {
radioCheckedId = R.id.radio_unlisted;
}
if (statusVisibility != null) {
if (statusVisibility.equals("unlisted")) {
radioCheckedId = R.id.radio_unlisted;
@ -78,6 +86,10 @@ public class ComposeOptionsFragment extends BottomSheetDialogFragment {
listener.onVisibilityChanged(visibility);
}
});
if (isReply) {
RadioButton publicButton = (RadioButton) rootView.findViewById(R.id.radio_public);
publicButton.setEnabled(false);
}
CheckBox markSensitive = (CheckBox) rootView.findViewById(R.id.compose_mark_sensitive);
if (showMarkSensitive) {

View File

@ -121,6 +121,7 @@ public class SFragment extends Fragment {
mentionedUsernames.remove(loggedInUsername);
Intent intent = new Intent(getContext(), ComposeActivity.class);
intent.putExtra("in_reply_to_id", inReplyToId);
intent.putExtra("reply_visibility", status.getVisibility().toString().toLowerCase());
intent.putExtra("mentioned_usernames", mentionedUsernames.toArray(new String[0]));
startActivity(intent);
}
@ -252,6 +253,12 @@ public class SFragment extends Fragment {
startActivity(intent);
break;
}
case UNKNOWN: {
/* Intentionally do nothing. This case is here is to handle when new attachment
* types are added to the API before code is added here to handle them. So, the
* best fallback is to just show the preview and ignore requests to view them. */
break;
}
}
}

View File

@ -15,6 +15,7 @@
package com.keylesspalace.tusky;
import android.support.annotation.Nullable;
import android.text.Spanned;
import org.json.JSONArray;
@ -177,6 +178,8 @@ public class Status {
return status.id.equals(this.id);
}
@SuppressWarnings("SimpleDateFormat") // UTC needs to not specify a Locale
@Nullable
private static Date parseDate(String dateTime) {
Date date;
String s = dateTime.replace("Z", "+00:00");
@ -190,6 +193,18 @@ public class Status {
return date;
}
private static MediaAttachment.Type parseMediaType(@Nullable String type) {
if (type == null) {
return MediaAttachment.Type.UNKNOWN;
}
switch (type.toUpperCase()) {
case "IMAGE": return MediaAttachment.Type.IMAGE;
case "GIFV":
case "VIDEO": return MediaAttachment.Type.VIDEO;
default: return MediaAttachment.Type.UNKNOWN;
}
}
public static Status parse(JSONObject object, boolean isReblog) throws JSONException {
String id = object.getString("id");
String content = object.getString("content");
@ -239,8 +254,7 @@ public class Status {
String url = attachment.getString("url");
String previewUrl = attachment.getString("preview_url");
String type = attachment.getString("type");
attachments[i] = new MediaAttachment(url, previewUrl,
MediaAttachment.Type.valueOf(type.toUpperCase()));
attachments[i] = new MediaAttachment(url, previewUrl, parseMediaType(type));
}
}
@ -289,6 +303,7 @@ public class Status {
enum Type {
IMAGE,
VIDEO,
UNKNOWN,
}
private String url;