diff --git a/app/src/main/java/org/nuclearfog/twidda/activities/TweetActivity.java b/app/src/main/java/org/nuclearfog/twidda/activities/TweetActivity.java index d597d0d0..e8ae3f34 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activities/TweetActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/activities/TweetActivity.java @@ -372,15 +372,15 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, Intent mediaIntent = new Intent(this, MediaViewer.class); mediaIntent.putExtra(KEY_MEDIA_URI, clickedTweet.getMediaLinks()); switch (clickedTweet.getMediaType()) { - case Tweet.MIME_PHOTO: + case Tweet.MEDIA_PHOTO: mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_IMAGE); break; - case Tweet.MIME_VIDEO: + case Tweet.MEDIA_VIDEO: mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_VIDEO); break; - case Tweet.MIME_ANGIF: + case Tweet.MEDIA_GIF: mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_ANGIF); break; } @@ -554,17 +554,17 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, sensitive_media.setVisibility(GONE); } switch (tweetUpdate.getMediaType()) { - case Tweet.MIME_PHOTO: + case Tweet.MEDIA_PHOTO: mediaButton.setVisibility(VISIBLE); mediaButton.setImageResource(R.drawable.image); break; - case Tweet.MIME_VIDEO: + case Tweet.MEDIA_VIDEO: mediaButton.setVisibility(VISIBLE); mediaButton.setImageResource(R.drawable.video); break; - case Tweet.MIME_ANGIF: + case Tweet.MEDIA_GIF: mediaButton.setVisibility(VISIBLE); mediaButton.setImageResource(R.drawable.gif); break; @@ -592,7 +592,7 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, tweetLocName.setVisibility(GONE); } String location = tweetUpdate.getLocationCoordinates(); - if (location != null && !location.isEmpty()) { + if (!location.isEmpty()) { tweetLocGPS.setVisibility(VISIBLE); tweetLocGPS.setText(location); } else { diff --git a/app/src/main/java/org/nuclearfog/twidda/activities/UserProfile.java b/app/src/main/java/org/nuclearfog/twidda/activities/UserProfile.java index 63f1a1cc..e1cee466 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activities/UserProfile.java +++ b/app/src/main/java/org/nuclearfog/twidda/activities/UserProfile.java @@ -603,13 +603,18 @@ public class UserProfile extends AppCompatActivity implements OnClickListener, O NumberFormat formatter = NumberFormat.getIntegerInstance(); Spanned bio = Tagger.makeTextWithLinks(user.getDescription(), settings.getHighlightColor(), this); - tabTweetCount[0].setText(formatter.format(user.getTweetCount())); - tabTweetCount[1].setText(formatter.format(user.getFavoriteCount())); following.setText(formatter.format(user.getFollowing())); follower.setText(formatter.format(user.getFollower())); username.setText(user.getUsername()); screenName.setText(user.getScreenname()); - + if (user.getTweetCount() >= 0) + tabTweetCount[0].setText(formatter.format(user.getTweetCount())); + else + tabTweetCount[0].setText(""); + if (user.getFavoriteCount() >= 0) + tabTweetCount[1].setText(formatter.format(user.getFavoriteCount())); + else + tabTweetCount[1].setText(""); if (user_createdAt.getVisibility() != VISIBLE) { String date = SimpleDateFormat.getDateTimeInstance().format(user.getCreatedAt()); user_createdAt.setVisibility(VISIBLE); diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/TweetV1.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/TweetV1.java index e816848f..aed5de0c 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/TweetV1.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/TweetV1.java @@ -12,6 +12,8 @@ import org.nuclearfog.twidda.backend.utils.StringTools; import org.nuclearfog.twidda.model.Tweet; import org.nuclearfog.twidda.model.User; +import java.util.Locale; + /** * API v 1.1 implementation of a tweet * @@ -42,10 +44,8 @@ class TweetV1 implements Tweet { private static final String MIME_V_MP4 = "video/mp4"; private long id; - private String text; - private User author; private long timestamp; - private String source; + private User author; private Tweet embeddedTweet; private long replyUserId; private long replyId; @@ -55,12 +55,14 @@ class TweetV1 implements Tweet { private boolean isSensitive; private boolean isRetweeted; private boolean isFavorited; + private String[] mediaLinks; private String userMentions; + private String coordinates; + private String text; + private String source; private String location = ""; private String replyName = ""; - private String coordinates = ""; - private String[] mediaLinks = {}; - private String mediaType = ""; + private String mediaType = MEDIA_NONE; TweetV1(JSONObject json, long twitterId) throws JSONException { @@ -75,27 +77,15 @@ class TweetV1 implements Tweet { isSensitive = json.optBoolean("possibly_sensitive"); timestamp = StringTools.getTime1(json.optString("created_at")); source = StringTools.getSource(json.optString("source")); + coordinates = getLocation(json); + mediaLinks = addMedia(json); text = createText(json); String replyName = json.optString("in_reply_to_screen_name"); - String userMentions = StringTools.getUserMentions(text); - JSONObject locationJson = json.optJSONObject("place"); - JSONObject coordinateJson = json.optJSONObject("coordinates"); JSONObject quoted_tweet = json.optJSONObject("retweeted_status"); JSONObject user_retweet = json.optJSONObject("current_user_retweet"); - JSONObject extEntities = json.optJSONObject("extended_entities"); - if (coordinateJson != null) { - if (coordinateJson.optString("type").equals("Point")) { - JSONArray coordinateArray = coordinateJson.optJSONArray("coordinates"); - if (coordinateArray != null && coordinateArray.length() == 2) { - double lon = coordinateArray.getDouble(0); - double lat = coordinateArray.getDouble(1); - coordinates = lon + "," + lat; - } - } - } if (locationJson != null) { location = locationJson.optString("full_name"); } @@ -103,9 +93,9 @@ class TweetV1 implements Tweet { this.replyName = '@' + replyName; } if (author.isCurrentUser()) { - this.userMentions = userMentions; + this.userMentions = StringTools.getUserMentions(text); } else { - this.userMentions = author.getScreenname() + ' ' + userMentions; + this.userMentions = author.getScreenname() + ' ' + StringTools.getUserMentions(text); } if (user_retweet != null) retweetId = user_retweet.optLong("id"); @@ -114,10 +104,11 @@ class TweetV1 implements Tweet { isRetweeted = embeddedTweet.isRetweeted(); isFavorited = embeddedTweet.isFavorited(); } - if (extEntities != null) { - addMedia(extEntities); + // remove short media link + int linkPos = text.lastIndexOf("https://t.co/"); + if (linkPos >= 0) { + text = text.substring(0, linkPos); } - } @Override @@ -275,63 +266,58 @@ class TweetV1 implements Tweet { /** * add media links to tweet if any */ - private void addMedia(JSONObject json) { + private String[] addMedia(JSONObject json) { try { - JSONArray media = json.getJSONArray("media"); + JSONObject extEntities = json.getJSONObject("extended_entities"); + JSONArray media = extEntities.getJSONArray("media"); if (media.length() > 0) { // determine MIME type JSONObject mediaItem = media.getJSONObject(0); - mediaLinks = new String[media.length()]; + String[] links = new String[media.length()]; String mime = mediaItem.getString("type"); switch (mime) { - case MIME_PHOTO: - mediaType = MIME_PHOTO; + case MEDIA_PHOTO: + mediaType = MEDIA_PHOTO; // get media URLs - for (int pos = 0; pos < mediaLinks.length; pos++) { + for (int pos = 0; pos < links.length; pos++) { JSONObject item = media.getJSONObject(pos); if (item != null) { - mediaLinks[pos] = item.getString("media_url_https"); + links[pos] = item.getString("media_url_https"); } } - break; + return links; - case MIME_VIDEO: - mediaType = MIME_VIDEO; + case MEDIA_VIDEO: + mediaType = MEDIA_VIDEO; JSONObject video = mediaItem.getJSONObject("video_info"); JSONArray videoVariants = video.getJSONArray("variants"); for (int pos = 0; pos < videoVariants.length(); pos++) { JSONObject variant = videoVariants.getJSONObject(pos); if (MIME_V_MP4.equals(variant.getString("content_type"))) { - mediaLinks[0] = variant.getString("url"); + links[0] = variant.getString("url"); break; } } - break; + return links; - case MIME_ANGIF: - mediaType = MIME_ANGIF; + case MEDIA_GIF: + mediaType = MEDIA_GIF; JSONObject gif = mediaItem.getJSONObject("video_info"); JSONObject gifVariant = gif.getJSONArray("variants").getJSONObject(0); if (MIME_V_MP4.equals(gifVariant.getString("content_type"))) { - mediaLinks[0] = gifVariant.getString("url"); - break; + links[0] = gifVariant.getString("url"); } - break; + return links; default: - mediaType = MIME_NONE; + mediaType = MEDIA_NONE; break; } - // remove short media link - int linkPos = text.lastIndexOf("https://t.co/"); - if (linkPos >= 0) { - text = text.substring(0, linkPos); - } - } } catch (JSONException e) { - // ignore + // ignore, return empty array } + return new String[0]; } /** @@ -367,4 +353,29 @@ class TweetV1 implements Tweet { } return builder.toString(); } + + /** + * create location coordinate string to use for uri link + * + * @param json root tweet json + * @return location uri scheme or empty string if tweet has no location information + */ + private String getLocation(JSONObject json) { + try { + JSONObject coordinateJson = json.optJSONObject("coordinates"); + if (coordinateJson != null) { + if (coordinateJson.optString("type").equals("Point")) { + JSONArray coordinateArray = coordinateJson.optJSONArray("coordinates"); + if (coordinateArray != null && coordinateArray.length() == 2) { + double lon = coordinateArray.getDouble(0); + double lat = coordinateArray.getDouble(1); + return String.format(Locale.US, "%.6f,%.6f", lat, lon); + } + } + } + } catch (JSONException e) { + // ignore, use empty string + } + return ""; + } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/UserV2.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/UserV2.java index 9369b3d6..0de55848 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/UserV2.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/UserV2.java @@ -66,7 +66,7 @@ class UserV2 implements User { } // not yet implemented in API 2.0 - favorCount = 0; + favorCount = -1; followReqSent = false; defaultImage = false; } diff --git a/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java b/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java index 090e1b23..61e742e1 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java @@ -745,11 +745,11 @@ public class AppDatabase { } else { statusRegister &= ~MEDIA_SENS_MASK; } - if (Tweet.MIME_PHOTO.equals(tweet.getMediaType())) { + if (Tweet.MEDIA_PHOTO.equals(tweet.getMediaType())) { statusRegister |= MEDIA_IMAGE_MASK; - } else if (Tweet.MIME_VIDEO.equals(tweet.getMediaType())) { + } else if (Tweet.MEDIA_VIDEO.equals(tweet.getMediaType())) { statusRegister |= MEDIA_VIDEO_MASK; - } else if (Tweet.MIME_ANGIF.equals(tweet.getMediaType())) { + } else if (Tweet.MEDIA_GIF.equals(tweet.getMediaType())) { statusRegister |= MEDIA_ANGIF_MASK; } ContentValues status = new ContentValues(16); diff --git a/app/src/main/java/org/nuclearfog/twidda/database/DatabaseAdapter.java b/app/src/main/java/org/nuclearfog/twidda/database/DatabaseAdapter.java index 65fad331..5e609651 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/DatabaseAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/DatabaseAdapter.java @@ -223,13 +223,6 @@ public class DatabaseAdapter { databasePath = c.getDatabasePath(DB_NAME); db = c.openOrCreateDatabase(databasePath.toString(), MODE_PRIVATE, null); initTables(); - updateTable(); - } - - /** - * update old table versions if necessary - */ - private void updateTable() { } /** diff --git a/app/src/main/java/org/nuclearfog/twidda/database/TweetImpl.java b/app/src/main/java/org/nuclearfog/twidda/database/TweetImpl.java index 8231ae17..2b707401 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/TweetImpl.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/TweetImpl.java @@ -78,13 +78,13 @@ class TweetImpl implements Tweet { String userMentions = StringTools.getUserMentions(text); // get media type if ((tweetRegister & MEDIA_ANGIF_MASK) == MEDIA_ANGIF_MASK) { - mediaType = MIME_ANGIF; + mediaType = MEDIA_GIF; } else if ((tweetRegister & MEDIA_IMAGE_MASK) == MEDIA_IMAGE_MASK) { - mediaType = MIME_PHOTO; + mediaType = MEDIA_PHOTO; } else if ((tweetRegister & MEDIA_VIDEO_MASK) == MEDIA_VIDEO_MASK) { - mediaType = MIME_VIDEO; + mediaType = MEDIA_VIDEO; } else { - mediaType = MIME_NONE; + mediaType = MEDIA_NONE; } if (author.isCurrentUser()) { this.userMentions = userMentions; diff --git a/app/src/main/java/org/nuclearfog/twidda/model/Tweet.java b/app/src/main/java/org/nuclearfog/twidda/model/Tweet.java index 6664f486..d407ec72 100644 --- a/app/src/main/java/org/nuclearfog/twidda/model/Tweet.java +++ b/app/src/main/java/org/nuclearfog/twidda/model/Tweet.java @@ -8,28 +8,31 @@ import androidx.annotation.Nullable; import java.io.Serializable; /** - * Interface class for all tweet implementations + * Interface class used for all tweet implementations * * @author nuclearfog */ public interface Tweet extends Serializable { /** - * twitter MIME type for a photo + * returned when the tweet contains one or more images */ - String MIME_PHOTO = "photo"; + String MEDIA_PHOTO = "photo"; /** - * twitter MIME type for a video + * returned when the tweet contains a video */ - String MIME_VIDEO = "video"; + String MEDIA_VIDEO = "video"; /** - * twitter MIME type for a gif + * returned when the tweet contains an animated gif */ - String MIME_ANGIF = "animated_gif"; + String MEDIA_GIF = "animated_gif"; - String MIME_NONE = "*/*"; + /** + * returned when the tweet doesn't contain any media + */ + String MEDIA_NONE = "*/*"; /** * @return tweet ID