diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml
index a3ca8a8c..a2bb053c 100644
--- a/.idea/assetWizardSettings.xml
+++ b/.idea/assetWizardSettings.xml
@@ -19,8 +19,8 @@
diff --git a/app/build.gradle b/app/build.gradle
index 2e9f7422..aa811840 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,7 +8,7 @@ android {
applicationId 'org.nuclearfog.twidda'
minSdkVersion 16
targetSdkVersion 29
- versionCode 14
+ versionCode 15
versionName '1.7.7'
vectorDrawables.useSupportLibrary true
}
diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/TweetDetail.java b/app/src/main/java/org/nuclearfog/twidda/activity/TweetDetail.java
index 4d4e3ab4..9ce4e963 100644
--- a/app/src/main/java/org/nuclearfog/twidda/activity/TweetDetail.java
+++ b/app/src/main/java/org/nuclearfog/twidda/activity/TweetDetail.java
@@ -37,7 +37,6 @@ import org.nuclearfog.twidda.backend.TweetLoader.Action;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.ErrorHandler;
import org.nuclearfog.twidda.backend.helper.FontTool;
-import org.nuclearfog.twidda.backend.helper.StringTools;
import org.nuclearfog.twidda.backend.items.Tweet;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.database.GlobalSettings;
@@ -48,6 +47,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static android.os.AsyncTask.Status.RUNNING;
+import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.widget.Toast.LENGTH_SHORT;
import static org.nuclearfog.twidda.activity.MediaViewer.KEY_MEDIA_LINK;
@@ -61,6 +61,8 @@ import static org.nuclearfog.twidda.activity.TweetPopup.KEY_TWEETPOPUP_REPLYID;
import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_ID;
import static org.nuclearfog.twidda.activity.UserDetail.KEY_USERDETAIL_MODE;
import static org.nuclearfog.twidda.activity.UserDetail.USERLIST_RETWEETS;
+import static org.nuclearfog.twidda.backend.engine.EngineException.ErrorType.NOT_AUTHORIZED;
+import static org.nuclearfog.twidda.backend.engine.EngineException.ErrorType.RESOURCE_NOT_FOUND;
import static org.nuclearfog.twidda.fragment.TweetFragment.RETURN_TWEET_CHANGED;
@@ -74,10 +76,10 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener,
private TweetLoader statusAsync;
private GlobalSettings settings;
- private View header, footer, videoButton, imageButton;
+ private View header, footer;
private TextView tweet_api, tweetDate, tweetText, scrName, usrName, tweetLocName;
private Button rtwButton, favButton, replyName, tweetLocGPS;
- private ImageView profile_img;
+ private ImageView profile_img, mediaButton;
@Nullable
private Tweet tweet;
@@ -105,8 +107,7 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener,
tweet_api = findViewById(R.id.used_api);
tweetLocName = findViewById(R.id.tweet_location_name);
tweetLocGPS = findViewById(R.id.tweet_location_coordinate);
- imageButton = findViewById(R.id.image_attach);
- videoButton = findViewById(R.id.video_attach);
+ mediaButton = findViewById(R.id.tweet_media_attach);
Bundle param = getIntent().getExtras();
Uri link = getIntent().getData();
@@ -137,8 +138,7 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener,
favButton.setOnLongClickListener(this);
profile_img.setOnClickListener(this);
tweetLocGPS.setOnClickListener(this);
- videoButton.setOnClickListener(this);
- imageButton.setOnClickListener(this);
+ mediaButton.setOnClickListener(this);
}
@@ -265,25 +265,23 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener,
break;
}
- case R.id.image_attach:
+ case R.id.tweet_media_attach:
if (tweet != null) {
- Intent mediaIntent = new Intent(getApplicationContext(), MediaViewer.class);
+ Intent mediaIntent = new Intent(this, MediaViewer.class);
mediaIntent.putExtra(KEY_MEDIA_LINK, tweet.getMediaLinks());
- mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_IMAGE);
- startActivity(mediaIntent);
- }
- break;
+ switch (tweet.getMediaType()) {
+ case IMAGE:
+ mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_IMAGE);
+ break;
- case R.id.video_attach:
- if (tweet != null) {
- String[] links = tweet.getMediaLinks();
- StringTools.FileType ext = StringTools.getFileType(links[0]);
- Intent mediaIntent = new Intent(getApplicationContext(), MediaViewer.class);
- if (ext == StringTools.FileType.VIDEO)
- mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_ANGIF);
- else
- mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_VIDEO);
- mediaIntent.putExtra(KEY_MEDIA_LINK, links);
+ case VIDEO:
+ mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_VIDEO);
+ break;
+
+ case GIF:
+ mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_ANGIF);
+ break;
+ }
startActivity(mediaIntent);
}
break;
@@ -371,13 +369,25 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener,
replyName.append(tweet.getReplyName());
replyName.setVisibility(VISIBLE);
}
- if (tweet.hasMedia()) {
- String[] links = tweet.getMediaLinks();
- StringTools.FileType ext = StringTools.getFileType(links[0]);
- if (ext == StringTools.FileType.IMAGE)
- imageButton.setVisibility(VISIBLE);
- else
- videoButton.setVisibility(VISIBLE);
+ switch (tweet.getMediaType()) {
+ case IMAGE:
+ mediaButton.setVisibility(VISIBLE);
+ mediaButton.setImageResource(R.drawable.image);
+ break;
+
+ case VIDEO:
+ mediaButton.setVisibility(VISIBLE);
+ mediaButton.setImageResource(R.drawable.video);
+ break;
+
+ case GIF:
+ mediaButton.setVisibility(VISIBLE);
+ mediaButton.setImageResource(R.drawable.images);
+ break;
+
+ default:
+ mediaButton.setVisibility(GONE);
+ break;
}
if (settings.getImageLoad()) {
String pbLink = author.getImageLink();
@@ -433,8 +443,12 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener,
* @param error Engine Exception
*/
public void onError(EngineException error) {
- boolean hardFailure = ErrorHandler.handleFailure(this, error);
- if (tweet == null || hardFailure) {
+ ErrorHandler.handleFailure(this, error);
+ EngineException.ErrorType errorType = error.getErrorType();
+ if (errorType == RESOURCE_NOT_FOUND || errorType == NOT_AUTHORIZED) {
+ setResult(RETURN_TWEET_CHANGED);
+ finish();
+ } else if (tweet == null) {
finish();
}
}
diff --git a/app/src/main/java/org/nuclearfog/twidda/activity/TweetPopup.java b/app/src/main/java/org/nuclearfog/twidda/activity/TweetPopup.java
index 3f1ec9fb..a644ae0f 100644
--- a/app/src/main/java/org/nuclearfog/twidda/activity/TweetPopup.java
+++ b/app/src/main/java/org/nuclearfog/twidda/activity/TweetPopup.java
@@ -29,8 +29,6 @@ import org.nuclearfog.twidda.backend.TweetUploader;
import org.nuclearfog.twidda.backend.engine.EngineException;
import org.nuclearfog.twidda.backend.helper.ErrorHandler;
import org.nuclearfog.twidda.backend.helper.FontTool;
-import org.nuclearfog.twidda.backend.helper.StringTools;
-import org.nuclearfog.twidda.backend.helper.StringTools.FileType;
import org.nuclearfog.twidda.backend.items.TweetHolder;
import org.nuclearfog.twidda.database.GlobalSettings;
@@ -60,18 +58,20 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
public static final String KEY_TWEETPOPUP_REPLYID = "tweet_replyID";
public static final String KEY_TWEETPOPUP_PREFIX = "tweet_prefix";
- private static final int NONE = 0;
- private static final int IMAGE = 1;
- private static final int VIDEO = 2;
- private static final int GIF = 3;
+ private enum MediaType {
+ NONE,
+ GIF,
+ IMAGE,
+ VIDEO,
+ }
private static final String[] PERM_STORAGE = {READ_EXTERNAL_STORAGE};
private static final String[] PERM_LOCATION = {ACCESS_FINE_LOCATION};
private static final String[] GET_MEDIA = {MediaStore.Images.Media.DATA};
private static final String TYPE_IMAGE = "image/*";
private static final String TYPE_VIDEO = "video/*";
- private static final int PICK_MEDIA = 3;
- private static final int CHECK_PERM = 4;
+ private static final int REQ_PICK_MEDIA = 3;
+ private static final int REQ_CHECK_PERM = 4;
private static final int MAX_IMAGES = 4;
@Nullable
@@ -85,7 +85,8 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
private EditText tweetText;
private String addition = "";
private long inReplyId = 0;
- private int mode = NONE;
+
+ private MediaType selectedFormat = MediaType.NONE;
@Override
protected void onCreate(Bundle b) {
@@ -150,42 +151,46 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
@Override
protected void onActivityResult(int reqCode, int returnCode, Intent intent) {
super.onActivityResult(reqCode, returnCode, intent);
- if (reqCode == PICK_MEDIA && returnCode == RESULT_OK) {
+ if (reqCode == REQ_PICK_MEDIA && returnCode == RESULT_OK) {
if (intent != null && intent.getData() != null) {
Cursor cursor = getContentResolver().query(intent.getData(), GET_MEDIA, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int index = cursor.getColumnIndex(GET_MEDIA[0]);
String path = cursor.getString(index);
- FileType type = StringTools.getFileType(path);
-
- switch (type) {
- case IMAGE:
- if (mode == NONE)
- mode = IMAGE;
- if (mediaPath.size() < MAX_IMAGES && mode == IMAGE) {
- mediaPath.add(path);
- previewBtn.setVisibility(VISIBLE);
- String count = Integer.toString(mediaPath.size());
- imgCount.setText(count);
- if (mediaPath.size() == MAX_IMAGES)
- mediaBtn.setVisibility(INVISIBLE);
+ String extension = path.substring(path.lastIndexOf('.') + 1).toLowerCase();
+ switch (extension) {
+ case "jpg":
+ case "jpeg":
+ case "png":
+ if (selectedFormat == MediaType.NONE)
+ selectedFormat = MediaType.IMAGE;
+ if (selectedFormat == MediaType.IMAGE) {
+ if (mediaPath.size() < MAX_IMAGES) {
+ mediaPath.add(path);
+ previewBtn.setVisibility(VISIBLE);
+ String count = Integer.toString(mediaPath.size());
+ imgCount.setText(count);
+ if (mediaPath.size() == MAX_IMAGES)
+ mediaBtn.setVisibility(INVISIBLE);
+ }
+ } else {
+ Toast.makeText(this, R.string.info_cant_add_video, LENGTH_SHORT).show();
}
break;
- case ANGIF:
- if (mode == NONE)
- mode = GIF;
- if (mode == GIF) {
+ case "gif":
+ if (selectedFormat == MediaType.NONE) {
+ selectedFormat = MediaType.GIF;
mediaPath.add(path);
previewBtn.setVisibility(VISIBLE);
mediaBtn.setVisibility(INVISIBLE);
}
break;
- case VIDEO:
- if (mode == NONE)
- mode = VIDEO;
- if (mode == VIDEO) {
+ case "mp4":
+ case "3gp":
+ if (selectedFormat == MediaType.NONE) {
+ selectedFormat = MediaType.VIDEO;
mediaPath.add(path);
previewBtn.setVisibility(VISIBLE);
mediaBtn.setVisibility(INVISIBLE);
@@ -205,7 +210,7 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == CHECK_PERM && permissions.length > 0 && grantResults.length > 0) {
+ if (requestCode == REQ_CHECK_PERM && permissions.length > 0 && grantResults.length > 0) {
switch (permissions[0]) {
case READ_EXTERNAL_STORAGE:
if (grantResults[0] == PERMISSION_GRANTED)
@@ -230,8 +235,10 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
Toast.makeText(this, R.string.error_empty_tweet, LENGTH_SHORT).show();
} else if (locationProg.getVisibility() == INVISIBLE) {
TweetHolder tweet = new TweetHolder(tweetStr, inReplyId);
- if (!mediaPath.isEmpty())
- tweet.addMedia(mediaPath.toArray(new String[0]));
+ if (selectedFormat == MediaType.IMAGE || selectedFormat == MediaType.GIF)
+ tweet.addMedia(mediaPath.toArray(new String[0]), TweetHolder.MediaType.IMAGE);
+ else if (selectedFormat == MediaType.VIDEO)
+ tweet.addMedia(mediaPath.toArray(new String[0]), TweetHolder.MediaType.VIDEO);
if (location != null)
tweet.addLocation(location);
uploaderAsync = new TweetUploader(this, tweet);
@@ -251,7 +258,7 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
Intent image = new Intent(this, MediaViewer.class);
image.putExtra(KEY_MEDIA_LINK, mediaPath.toArray(new String[0]));
- switch (mode) {
+ switch (selectedFormat) {
case IMAGE:
image.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_IMG_STORAGE);
startActivity(image);
@@ -288,17 +295,6 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
locationBtn.setVisibility(VISIBLE);
}
-
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- }
-
-
- @Override
- public void onProviderEnabled(String provider) {
- }
-
-
@Override
public void onProviderDisabled(String provider) {
if (location == null)
@@ -307,6 +303,15 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
locationBtn.setVisibility(VISIBLE);
}
+ @Override
+ public void onProviderEnabled(String provider) {
+ }
+
+ @Override
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ }
+
+
@Override
public void onDismiss(DialogInterface dialog) {
if (uploaderAsync != null && uploaderAsync.getStatus() == RUNNING) {
@@ -382,26 +387,20 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
boolean accessGranted = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(PERM_STORAGE[0]) != PERMISSION_GRANTED) {
- requestPermissions(PERM_STORAGE, CHECK_PERM);
+ requestPermissions(PERM_STORAGE, REQ_CHECK_PERM);
accessGranted = false;
}
}
if (accessGranted) {
- if (mode == NONE) {
- Intent mediaIntent = new Intent(ACTION_PICK);
- mediaIntent.setDataAndType(EXTERNAL_CONTENT_URI, TYPE_IMAGE + TYPE_VIDEO);
- if (mediaIntent.resolveActivity(getPackageManager()) != null)
- startActivityForResult(mediaIntent, PICK_MEDIA);
- else
- Toast.makeText(getApplicationContext(), R.string.error_no_media_app, LENGTH_SHORT).show();
- } else if (mode == IMAGE) {
- Intent imageIntent = new Intent(ACTION_PICK);
- imageIntent.setDataAndType(EXTERNAL_CONTENT_URI, TYPE_IMAGE);
- if (imageIntent.resolveActivity(getPackageManager()) != null)
- startActivityForResult(imageIntent, PICK_MEDIA);
- else
- Toast.makeText(getApplicationContext(), R.string.error_no_media_app, LENGTH_SHORT).show();
- }
+ Intent mediaSelect = new Intent(ACTION_PICK);
+ if (selectedFormat == MediaType.IMAGE)
+ mediaSelect.setDataAndType(EXTERNAL_CONTENT_URI, TYPE_IMAGE);
+ else
+ mediaSelect.setDataAndType(EXTERNAL_CONTENT_URI, TYPE_IMAGE + TYPE_VIDEO);
+ if (mediaSelect.resolveActivity(getPackageManager()) != null)
+ startActivityForResult(mediaSelect, REQ_PICK_MEDIA);
+ else
+ Toast.makeText(getApplicationContext(), R.string.error_no_media_app, LENGTH_SHORT).show();
}
}
@@ -413,14 +412,14 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
boolean accessGranted = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(PERM_LOCATION[0]) != PERMISSION_GRANTED) {
- requestPermissions(PERM_LOCATION, CHECK_PERM);
+ requestPermissions(PERM_LOCATION, REQ_CHECK_PERM);
accessGranted = false;
}
}
if (accessGranted) {
if (mLocation != null && mLocation.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
- Toast.makeText(this, R.string.info_get_location, LENGTH_SHORT).show();
mLocation.requestSingleUpdate(LocationManager.GPS_PROVIDER, this, null);
+ Toast.makeText(this, R.string.info_get_location, LENGTH_SHORT).show();
locationProg.setVisibility(VISIBLE);
locationBtn.setVisibility(INVISIBLE);
} else {
diff --git a/app/src/main/java/org/nuclearfog/twidda/adapter/ListAdapter.java b/app/src/main/java/org/nuclearfog/twidda/adapter/ListAdapter.java
index ac9d3ec9..afc9e93a 100644
--- a/app/src/main/java/org/nuclearfog/twidda/adapter/ListAdapter.java
+++ b/app/src/main/java/org/nuclearfog/twidda/adapter/ListAdapter.java
@@ -17,14 +17,15 @@ import com.squareup.picasso.Picasso;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.helper.FontTool;
-import org.nuclearfog.twidda.backend.helper.StringTools;
import org.nuclearfog.twidda.backend.items.TwitterList;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.database.GlobalSettings;
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import static android.view.View.GONE;
@@ -158,7 +159,7 @@ public class ListAdapter extends Adapter {
vh.title.setText(item.getTitle());
vh.ownername.setText(owner.getScreenname());
vh.description.setText(item.getDescription());
- vh.createdAt.setText(StringTools.getTimeString(item.getCreatedAt()));
+ vh.createdAt.setText(getTimeString(item.getCreatedAt()));
vh.memberCount.setText(formatter.format(item.getMemberCount()));
vh.subscriberCount.setText(formatter.format(item.getSubscriberCount()));
if (settings.getImageLoad()) {
@@ -185,6 +186,29 @@ public class ListAdapter extends Adapter {
}
+ private String getTimeString(long time) {
+ long diff = new Date().getTime() - time;
+ long seconds = diff / 1000;
+ long minutes = seconds / 60;
+ long hours = minutes / 60;
+ long days = hours / 24;
+ long weeks = days / 7;
+ if (weeks > 4) {
+ Date tweetDate = new Date(time);
+ return SimpleDateFormat.getDateInstance().format(tweetDate);
+ }
+ if (weeks > 0)
+ return weeks + " w";
+ if (days > 0)
+ return days + " d";
+ if (hours > 0)
+ return hours + " h";
+ if (minutes > 0)
+ return minutes + " m";
+ return seconds + " s";
+ }
+
+
static class ListHolder extends ViewHolder {
final ImageView pb_image;
final Button followList, deleteList;
diff --git a/app/src/main/java/org/nuclearfog/twidda/adapter/MessageAdapter.java b/app/src/main/java/org/nuclearfog/twidda/adapter/MessageAdapter.java
index 40fabfc7..436b8bd4 100644
--- a/app/src/main/java/org/nuclearfog/twidda/adapter/MessageAdapter.java
+++ b/app/src/main/java/org/nuclearfog/twidda/adapter/MessageAdapter.java
@@ -20,13 +20,14 @@ import org.nuclearfog.tag.Tagger;
import org.nuclearfog.tag.Tagger.OnTagClickListener;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.helper.FontTool;
-import org.nuclearfog.twidda.backend.helper.StringTools;
import org.nuclearfog.twidda.backend.items.Message;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.database.GlobalSettings;
import java.lang.ref.WeakReference;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
@@ -134,7 +135,7 @@ public class MessageAdapter extends Adapter {
vh.message.setText(text);
vh.username.setText(sender.getUsername());
vh.screenname.setText(sender.getScreenname());
- vh.createdAt.setText(StringTools.getTimeString(message.getTime()));
+ vh.createdAt.setText(getTimeString(message.getTime()));
vh.receivername.setText(message.getReceiver().getScreenname());
if (sender.isVerified())
@@ -154,6 +155,29 @@ public class MessageAdapter extends Adapter {
}
+ private String getTimeString(long time) {
+ long diff = new Date().getTime() - time;
+ long seconds = diff / 1000;
+ long minutes = seconds / 60;
+ long hours = minutes / 60;
+ long days = hours / 24;
+ long weeks = days / 7;
+ if (weeks > 4) {
+ Date tweetDate = new Date(time);
+ return SimpleDateFormat.getDateInstance().format(tweetDate);
+ }
+ if (weeks > 0)
+ return weeks + " w";
+ if (days > 0)
+ return days + " d";
+ if (hours > 0)
+ return hours + " h";
+ if (minutes > 0)
+ return minutes + " m";
+ return seconds + " s";
+ }
+
+
static class MessageHolder extends ViewHolder {
final ImageView profile_img;
final TextView username;
diff --git a/app/src/main/java/org/nuclearfog/twidda/adapter/TweetAdapter.java b/app/src/main/java/org/nuclearfog/twidda/adapter/TweetAdapter.java
index 73fd0cd1..4f637f29 100644
--- a/app/src/main/java/org/nuclearfog/twidda/adapter/TweetAdapter.java
+++ b/app/src/main/java/org/nuclearfog/twidda/adapter/TweetAdapter.java
@@ -18,14 +18,15 @@ import com.squareup.picasso.Picasso;
import org.nuclearfog.tag.Tagger;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.helper.FontTool;
-import org.nuclearfog.twidda.backend.helper.StringTools;
import org.nuclearfog.twidda.backend.items.Tweet;
import org.nuclearfog.twidda.backend.items.TwitterUser;
import org.nuclearfog.twidda.database.GlobalSettings;
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
@@ -131,7 +132,7 @@ public class TweetAdapter extends Adapter {
vh.screenname.setText(user.getScreenname());
vh.retweet.setText(formatter.format(tweet.getRetweetCount()));
vh.favorite.setText(formatter.format(tweet.getFavorCount()));
- vh.time.setText(StringTools.getTimeString(tweet.getTime()));
+ vh.time.setText(getTimeString(tweet.getTime()));
if (tweet.retweeted())
vh.retweet.setCompoundDrawablesWithIntrinsicBounds(R.drawable.retweet_enabled, 0, 0, 0);
else
@@ -158,6 +159,28 @@ public class TweetAdapter extends Adapter {
vh.profile.setImageResource(0);
}
+ private String getTimeString(long time) {
+ long diff = new Date().getTime() - time;
+ long seconds = diff / 1000;
+ long minutes = seconds / 60;
+ long hours = minutes / 60;
+ long days = hours / 24;
+ long weeks = days / 7;
+ if (weeks > 4) {
+ Date tweetDate = new Date(time);
+ return SimpleDateFormat.getDateInstance().format(tweetDate);
+ }
+ if (weeks > 0)
+ return weeks + " w";
+ if (days > 0)
+ return days + " d";
+ if (hours > 0)
+ return hours + " h";
+ if (minutes > 0)
+ return minutes + " m";
+ return seconds + " s";
+ }
+
static class ItemHolder extends ViewHolder {
final TextView username, screenname, tweet, retweet;
final TextView favorite, retweeter, time;
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/MessageListLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/MessageListLoader.java
index 81e8ea72..476e0c26 100644
--- a/app/src/main/java/org/nuclearfog/twidda/backend/MessageListLoader.java
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/MessageListLoader.java
@@ -76,13 +76,13 @@ public class MessageListLoader extends AsyncTask> {
messageId = param[0];
id = messageId;
mTwitter.deleteMessage(messageId);
- db.deleteDm(messageId);
+ db.deleteMessage(messageId);
break;
}
} catch (EngineException twException) {
this.twException = twException;
if (twException.getErrorType() == RESOURCE_NOT_FOUND)
- db.deleteDm(messageId);
+ db.deleteMessage(messageId);
} catch (Exception exception) {
exception.printStackTrace();
}
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/TweetLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/TweetLoader.java
index 3146881d..f9ea16f6 100644
--- a/app/src/main/java/org/nuclearfog/twidda/backend/TweetLoader.java
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/TweetLoader.java
@@ -114,7 +114,8 @@ public class TweetLoader extends AsyncTask {
if (ui.get() != null) {
if (tweet != null) {
ui.get().onAction(tweet, action);
- } else if (twException != null) {
+ }
+ if (twException != null) {
ui.get().onError(twException);
}
}
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/engine/EngineException.java b/app/src/main/java/org/nuclearfog/twidda/backend/engine/EngineException.java
index 57010626..1a49f5dc 100644
--- a/app/src/main/java/org/nuclearfog/twidda/backend/engine/EngineException.java
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/engine/EngineException.java
@@ -26,7 +26,7 @@ public class EngineException extends Exception {
ERROR_NOT_DEFINED
}
- private final ErrorType messageResource;
+ private final ErrorType errorType;
private int retryAfter;
@@ -40,61 +40,61 @@ public class EngineException extends Exception {
case 88:
case 420: //
case 429: // Rate limit exceeded!
- messageResource = ErrorType.RATE_LIMIT_EX;
+ errorType = ErrorType.RATE_LIMIT_EX;
retryAfter = error.getRetryAfter();
break;
case 17:
case 50: // USER not found
case 63: // USER suspended
- messageResource = ErrorType.USER_NOT_FOUND;
+ errorType = ErrorType.USER_NOT_FOUND;
break;
case 32:
- messageResource = ErrorType.REQ_TOKEN_EXPIRED;
+ errorType = ErrorType.REQ_TOKEN_EXPIRED;
break;
case 34: //
case 144: // TWEET not found
- messageResource = ErrorType.RESOURCE_NOT_FOUND;
+ errorType = ErrorType.RESOURCE_NOT_FOUND;
break;
case 150:
- messageResource = ErrorType.CANT_SEND_DM;
+ errorType = ErrorType.CANT_SEND_DM;
break;
case 136:
case 179:
- messageResource = ErrorType.NOT_AUTHORIZED;
+ errorType = ErrorType.NOT_AUTHORIZED;
break;
case 186:
- messageResource = ErrorType.TWEET_TOO_LONG;
+ errorType = ErrorType.TWEET_TOO_LONG;
break;
case 187:
- messageResource = ErrorType.DUPLICATE_TWEET;
+ errorType = ErrorType.DUPLICATE_TWEET;
break;
case 349:
- messageResource = ErrorType.NO_DM_TO_USER;
+ errorType = ErrorType.NO_DM_TO_USER;
break;
case 354:
- messageResource = ErrorType.DM_TOO_LONG;
+ errorType = ErrorType.DM_TOO_LONG;
break;
case 89:
- messageResource = ErrorType.TOKEN_EXPIRED;
+ errorType = ErrorType.TOKEN_EXPIRED;
break;
default:
if (error.getStatusCode() == 401) {
- messageResource = ErrorType.NOT_AUTHORIZED;
+ errorType = ErrorType.NOT_AUTHORIZED;
} else if (error.isCausedByNetworkIssue()) {
- messageResource = ErrorType.NO_CONNECTION;
+ errorType = ErrorType.NO_CONNECTION;
} else {
- messageResource = ErrorType.ERROR_NOT_DEFINED;
+ errorType = ErrorType.ERROR_NOT_DEFINED;
}
break;
}
@@ -107,15 +107,15 @@ public class EngineException extends Exception {
EngineException(int errorCode) {
switch (errorCode) {
case FILENOTFOUND:
- messageResource = ErrorType.NO_MEDIA_FOUND;
+ errorType = ErrorType.NO_MEDIA_FOUND;
break;
case TOKENNOTSET:
- messageResource = ErrorType.NO_LINK_DEFINED;
+ errorType = ErrorType.NO_LINK_DEFINED;
break;
default:
- messageResource = ErrorType.ERROR_NOT_DEFINED;
+ errorType = ErrorType.ERROR_NOT_DEFINED;
break;
}
}
@@ -125,7 +125,7 @@ public class EngineException extends Exception {
* @return type of error {@link ErrorType}
*/
public ErrorType getErrorType() {
- return messageResource;
+ return errorType;
}
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/engine/TwitterEngine.java b/app/src/main/java/org/nuclearfog/twidda/backend/engine/TwitterEngine.java
index 70d5d002..b07c96b1 100644
--- a/app/src/main/java/org/nuclearfog/twidda/backend/engine/TwitterEngine.java
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/engine/TwitterEngine.java
@@ -547,11 +547,11 @@ public class TwitterEngine {
mStatus.setInReplyToStatusId(tweet.getReplyId());
if (tweet.hasLocation())
mStatus.setLocation(new GeoLocation(tweet.getLatitude(), tweet.getLongitude()));
- if (tweet.hasImages()) {
- long[] ids = uploadImages(tweet.getImageLink());
+ if (tweet.getMediaType() == TweetHolder.MediaType.IMAGE) {
+ long[] ids = uploadImages(tweet.getMediaLinks());
mStatus.setMediaIds(ids);
- } else if (tweet.hasVideo()) {
- long id = uploadVideo(tweet.getVideoLink());
+ } else if (tweet.getMediaType() == TweetHolder.MediaType.VIDEO) {
+ long id = uploadVideo(tweet.getMediaLink());
mStatus.setMediaIds(id);
}
twitter.updateStatus(mStatus);
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/helper/ErrorHandler.java b/app/src/main/java/org/nuclearfog/twidda/backend/helper/ErrorHandler.java
index d1008aea..b4a2523b 100644
--- a/app/src/main/java/org/nuclearfog/twidda/backend/helper/ErrorHandler.java
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/helper/ErrorHandler.java
@@ -19,9 +19,8 @@ public abstract class ErrorHandler {
*
* @param context current activity context
* @param error Error exception throwed by TwitterEngine
- * @return true if its a hard failure
*/
- public static boolean handleFailure(@NonNull Context context, @NonNull EngineException error) {
+ public static void handleFailure(@NonNull Context context, @NonNull EngineException error) {
switch (error.getErrorType()) {
case RATE_LIMIT_EX:
int timeToWait = error.getTimeToWait();
@@ -38,7 +37,7 @@ public abstract class ErrorHandler {
case USER_NOT_FOUND:
Toast.makeText(context, R.string.error_user_not_found, Toast.LENGTH_SHORT).show();
- return true;
+ break;
case REQ_TOKEN_EXPIRED:
Toast.makeText(context, R.string.error_request_token, Toast.LENGTH_SHORT).show();
@@ -46,7 +45,7 @@ public abstract class ErrorHandler {
case RESOURCE_NOT_FOUND:
Toast.makeText(context, R.string.error_not_found, Toast.LENGTH_SHORT).show();
- return true;
+ break;
case CANT_SEND_DM:
Toast.makeText(context, R.string.error_send_dm_to_user, Toast.LENGTH_SHORT).show();
@@ -54,7 +53,7 @@ public abstract class ErrorHandler {
case NOT_AUTHORIZED:
Toast.makeText(context, R.string.error_not_authorized, Toast.LENGTH_SHORT).show();
- return true;
+ break;
case TWEET_TOO_LONG:
Toast.makeText(context, R.string.error_status_length, Toast.LENGTH_SHORT).show();
@@ -93,6 +92,5 @@ public abstract class ErrorHandler {
Toast.makeText(context, error.getMessage(), Toast.LENGTH_SHORT).show();
break;
}
- return false;
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/helper/StringTools.java b/app/src/main/java/org/nuclearfog/twidda/backend/helper/StringTools.java
deleted file mode 100644
index 2a12b09f..00000000
--- a/app/src/main/java/org/nuclearfog/twidda/backend/helper/StringTools.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package org.nuclearfog.twidda.backend.helper;
-
-import androidx.annotation.NonNull;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-public abstract class StringTools {
-
- public enum FileType {
- IMAGE,
- VIDEO,
- STREAM,
- ANGIF,
- NONE
- }
-
- public static String getTimeString(long time) {
- long diff = new Date().getTime() - time;
- long seconds = diff / 1000;
- long minutes = seconds / 60;
- long hours = minutes / 60;
- long days = hours / 24;
- long weeks = days / 7;
- if (weeks > 4) {
- Date tweetDate = new Date(time);
- return SimpleDateFormat.getDateInstance().format(tweetDate);
- }
- if (weeks > 0)
- return weeks + " w";
- if (days > 0)
- return days + " d";
- if (hours > 0)
- return hours + " h";
- if (minutes > 0)
- return minutes + " m";
- return seconds + " s";
- }
-
- public static FileType getFileType(String path) {
- String ext = getExtension(path);
- switch (ext) {
- case "png":
- case "jpg":
- case "jpeg":
- return FileType.IMAGE;
-
- case "mp4":
- case "3gp":
- return FileType.VIDEO;
-
- case "m3u8":
- return FileType.STREAM;
-
- case "gif":
- return FileType.ANGIF;
-
- default:
- return FileType.NONE;
- }
- }
-
- private static String getExtension(@NonNull String path) {
- String filename = getFilename(path);
- String ext = "";
- int start = lastIndexOf(filename, '.') + 1;
- if (start > 0 && start < filename.length()) {
- int end = lastIndexOf(filename, '?');
- if (end > 0)
- ext = filename.substring(start, end);
- else
- ext = filename.substring(start);
- ext = asciiLowerCase(ext);
- }
- return ext;
- }
-
- private static String getFilename(@NonNull String path) {
- String filename = "";
- int end = lastIndexOf(path, '/') + 1;
- if (end > 0 && end < path.length())
- filename = path.substring(end);
- return filename;
- }
-
- private static String asciiLowerCase(String ext) {
- StringBuilder result = new StringBuilder();
- for (int index = 0; index < ext.length(); index++) {
- char current = ext.charAt(index);
- if (current >= 'A' && current <= 'Z')
- current += 0x20;
- result.append(current);
- }
- return result.toString();
- }
-
- private static int lastIndexOf(String text, char symbol) {
- int position = 0;
- for (int index = 0; index < text.length(); index++) {
- if (text.charAt(index) == symbol)
- position = index;
- }
- return position;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/items/Tweet.java b/app/src/main/java/org/nuclearfog/twidda/backend/items/Tweet.java
index 526da2f1..bb29eaa8 100644
--- a/app/src/main/java/org/nuclearfog/twidda/backend/items/Tweet.java
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/items/Tweet.java
@@ -11,6 +11,13 @@ import twitter4j.URLEntity;
public class Tweet {
+ public enum MediaType {
+ IMAGE,
+ VIDEO,
+ GIF,
+ NONE
+ }
+
private static final String PHOTO = "photo";
private static final String VIDEO = "video";
private static final String ANGIF = "animated_gif";
@@ -38,6 +45,8 @@ public class Tweet {
private final String locationName;
private final String locationCoordinates;
+ private final MediaType mediaType;
+
/**
* Tweet Constructor
@@ -66,7 +75,6 @@ public class Tweet {
tweet = getText(status);
time = status.getCreatedAt().getTime();
replyID = status.getInReplyToStatusId();
- medias = getMediaLinks(status);
myRetweetId = status.getCurrentUserRetweetId();
replyUserId = status.getInReplyToUserId();
@@ -74,7 +82,7 @@ public class Tweet {
String api = "" + status.getSource();
int start = api.indexOf('>') + 1;
int end = api.lastIndexOf('<');
- if (start > 0 && end > 0)
+ if (start > 0 && end > start)
api = api.substring(start, end);
source = api;
@@ -96,6 +104,37 @@ public class Tweet {
embedded = new Tweet(status.getRetweetedStatus());
else
embedded = null;
+
+ MediaEntity[] mediaEntities = status.getMediaEntities();
+ medias = new String[mediaEntities.length];
+ if (medias.length == 0) {
+ mediaType = MediaType.NONE;
+ } else {
+ switch (mediaEntities[0].getType()) {
+ case PHOTO:
+ mediaType = MediaType.IMAGE;
+ for (int i = 0; i < mediaEntities.length; i++)
+ medias[i] = mediaEntities[i].getMediaURLHttps();
+ break;
+
+ case VIDEO:
+ mediaType = MediaType.VIDEO;
+ for (MediaEntity.Variant type : mediaEntities[0].getVideoVariants()) {
+ if (type.getContentType().equals(MEDIA_VIDEO))
+ medias[0] = type.getUrl();
+ }
+ break;
+
+ case ANGIF:
+ mediaType = MediaType.GIF;
+ medias[0] = mediaEntities[0].getVideoVariants()[0].getUrl();
+ break;
+
+ default:
+ mediaType = MediaType.NONE;
+ break;
+ }
+ }
}
/**
@@ -119,7 +158,7 @@ public class Tweet {
* @param place location full place name
*/
public Tweet(long tweetID, int retweetCount, int favoriteCount, TwitterUser user, String tweet, long time,
- String replyName, long replyUserId, String[] medias, String source, long replyID,
+ String replyName, long replyUserId, String[] medias, MediaType mediaType, String source, long replyID,
Tweet embedded, long myRetweetId, boolean retweeted, boolean favored, String place, String geo) {
this.tweetID = tweetID;
@@ -130,6 +169,7 @@ public class Tweet {
this.replyID = replyID;
this.embedded = embedded;
this.medias = medias;
+ this.mediaType = mediaType;
this.retweeted = retweeted;
this.favored = favored;
this.myRetweetId = myRetweetId;
@@ -260,12 +300,12 @@ public class Tweet {
}
/**
- * check if tweet contains media
+ * check tweet media type
*
- * @return true if tweet contains media
+ * @return media type or NONE if there isnt any media
*/
- public boolean hasMedia() {
- return medias != null && medias.length > 0;
+ public MediaType getMediaType() {
+ return mediaType;
}
/**
@@ -304,35 +344,6 @@ public class Tweet {
return locationCoordinates;
}
- /**
- * @param status Twitter4J status
- * @return Array of Medialinks
- */
- private String[] getMediaLinks(Status status) {
- MediaEntity[] mediaEntities = status.getMediaEntities();
- String[] medias = new String[mediaEntities.length];
- for (int i = 0; i < medias.length; i++) {
- MediaEntity mediaEntity = mediaEntities[i];
- switch (mediaEntity.getType()) {
- case PHOTO:
- medias[i] = mediaEntity.getMediaURLHttps();
- break;
-
- case VIDEO:
- for (MediaEntity.Variant type : mediaEntity.getVideoVariants()) {
- if (type.getContentType().equals(MEDIA_VIDEO))
- medias[i] = type.getUrl();
- }
- break;
-
- case ANGIF:
- medias[i] = mediaEntity.getVideoVariants()[0].getUrl();
- break;
- }
- }
- return medias;
- }
-
/**
* Resolve shortened tweet links
*
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/items/TweetHolder.java b/app/src/main/java/org/nuclearfog/twidda/backend/items/TweetHolder.java
index 573bf452..e96bce4f 100644
--- a/app/src/main/java/org/nuclearfog/twidda/backend/items/TweetHolder.java
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/items/TweetHolder.java
@@ -4,18 +4,21 @@ import android.location.Location;
import androidx.annotation.NonNull;
-import org.nuclearfog.twidda.backend.helper.StringTools;
-import org.nuclearfog.twidda.backend.helper.StringTools.FileType;
public class TweetHolder {
+ public enum MediaType {
+ IMAGE,
+ VIDEO,
+ NONE
+ }
+
private final String text;
private final long replyId;
- private String[] imageLink;
- private String videoLink;
+ private String[] mediaLinks;
private double longitude, latitude;
- private boolean hasImage = false;
- private boolean hasVideo = false;
+
+ private MediaType mType = MediaType.NONE;
private boolean hasLocation = false;
@@ -25,23 +28,9 @@ public class TweetHolder {
}
- public void addMedia(String[] mediaLinks) {
- FileType type = StringTools.getFileType(mediaLinks[0]);
-
- switch (type) {
- case VIDEO:
- imageLink = new String[0];
- videoLink = mediaLinks[0];
- hasVideo = true;
- break;
-
- case ANGIF:
- case IMAGE:
- videoLink = "";
- imageLink = mediaLinks;
- hasImage = true;
- break;
- }
+ public void addMedia(String[] mediaLinks, MediaType mType) {
+ this.mediaLinks = mediaLinks;
+ this.mType = mType;
}
public void addLocation(Location location) {
@@ -58,12 +47,16 @@ public class TweetHolder {
return replyId;
}
- public String getVideoLink() {
- return videoLink;
+ public MediaType getMediaType() {
+ return mType;
}
- public String[] getImageLink() {
- return imageLink;
+ public String[] getMediaLinks() {
+ return mediaLinks;
+ }
+
+ public String getMediaLink() {
+ return mediaLinks[0];
}
public double getLongitude() {
@@ -74,14 +67,6 @@ public class TweetHolder {
return latitude;
}
- public boolean hasImages() {
- return hasImage;
- }
-
- public boolean hasVideo() {
- return hasVideo;
- }
-
public boolean hasLocation() {
return hasLocation;
}
@@ -93,8 +78,6 @@ public class TweetHolder {
@NonNull
@Override
public String toString() {
- return "to=" + replyId + ", location added=" + hasLocation + ", image added=" + hasImage + ", video added=" + hasVideo
- + "\n" + text;
-
+ return "to=" + replyId + "\nTweet=" + text;
}
}
\ No newline at end of file
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 96b0d744..006a3dc8 100644
--- a/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java
+++ b/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java
@@ -20,18 +20,22 @@ import static android.database.sqlite.SQLiteDatabase.CONFLICT_REPLACE;
public class AppDatabase {
- private static final int FAV_MASK = 1; // FAVORITE MASK
- private static final int RTW_MASK = 1 << 1; // RETWEET MASK
- private static final int HOM_MASK = 1 << 2; // HOME TWEET MASK
- private static final int MEN_MASK = 1 << 3; // MENTION MASK
- private static final int UTW_MASK = 1 << 4; // USER TWEETS
- private static final int RPL_MASK = 1 << 5; // TWEET ANSWERS
+ private static final int FAV_MASK = 1; // tweet is favored by user
+ private static final int RTW_MASK = 1 << 1; // tweet is retweeted by user
+ private static final int HOM_MASK = 1 << 2; // tweet is from home timeline
+ private static final int MEN_MASK = 1 << 3; // tweet is from mention timeline
+ private static final int UTW_MASK = 1 << 4; // tweet is from an users timeline
+ private static final int RPL_MASK = 1 << 5; // tweet is from a reply timeline
- private static final int VER_MASK = 1; // USER VERIFIED MASK
- private static final int LCK_MASK = 1 << 1; // USER LOCKED MASK
- private static final int FRQ_MASK = 1 << 2; // USER REQUEST FOLLOW
- private static final int EXCL_USR = 1 << 3; // EXCLUDE USERS TWEETS
- private static final int DEF_IMG = 1 << 4; // DEFAULT PROFILE IMAGE
+ private static final int MEDIA_IMAGE_MASK = 1 << 6; // tweet contains images
+ private static final int MEDIA_VIDEO_MASK = 1 << 7; // tweet contains a video
+ private static final int MEDIA_ANGIF_MASK = 1 << 8; // tweet contains an animation
+
+ private static final int VER_MASK = 1; // user is verified
+ private static final int LCK_MASK = 1 << 1; // user is private
+ private static final int FRQ_MASK = 1 << 2; // a follow request is pending
+ private static final int EXCL_USR = 1 << 3; // user excluded from mention timeline
+ private static final int DEF_IMG = 1 << 4; // user has a default profile image
private final int limit; // DATABASE ENTRY limit
private final long homeId;
@@ -165,18 +169,6 @@ public class AppDatabase {
commit(db);
}
- /**
- * get user information
- *
- * @param userId ID of user
- * @return user information or null if not found
- */
- @Nullable
- public TwitterUser getUser(long userId) {
- SQLiteDatabase db = getDbRead();
- return getUser(userId, db);
- }
-
/**
* load home timeline
*
@@ -275,6 +267,18 @@ public class AppDatabase {
return tweetList;
}
+ /**
+ * get user information
+ *
+ * @param userId ID of user
+ * @return user information or null if not found
+ */
+ @Nullable
+ public TwitterUser getUser(long userId) {
+ SQLiteDatabase db = getDbRead();
+ return getUser(userId, db);
+ }
+
/**
* load status
*
@@ -421,7 +425,7 @@ public class AppDatabase {
*
* @param id Direct Message ID
*/
- public void deleteDm(long id) {
+ public void deleteMessage(long id) {
final String[] messageId = {Long.toString(id)};
SQLiteDatabase db = getDbWrite();
@@ -543,15 +547,22 @@ public class AppDatabase {
String geo = cursor.getString(cursor.getColumnIndex("geo"));
long replyUserId = cursor.getLong(cursor.getColumnIndex("replyUserID"));
int statusregister = cursor.getInt(cursor.getColumnIndex("statusregister"));
- boolean favorited = (statusregister & FAV_MASK) > 0;
- boolean retweeted = (statusregister & RTW_MASK) > 0;
+ boolean favorited = (statusregister & FAV_MASK) != 0;
+ boolean retweeted = (statusregister & RTW_MASK) != 0;
String[] medias = parseMedia(medialinks);
+ Tweet.MediaType mediaType = Tweet.MediaType.NONE;
+ if ((statusregister & MEDIA_IMAGE_MASK) != 0)
+ mediaType = Tweet.MediaType.IMAGE;
+ else if ((statusregister & MEDIA_VIDEO_MASK) != 0)
+ mediaType = Tweet.MediaType.VIDEO;
+ else if ((statusregister & MEDIA_ANGIF_MASK) != 0)
+ mediaType = Tweet.MediaType.GIF;
TwitterUser user = getUser(cursor);
Tweet embeddedTweet = null;
if (retweetId > 1)
embeddedTweet = getStatus(retweetId);
return new Tweet(tweetId, retweet, favorit, user, tweettext, time, replyname, replyUserId, medias,
- source, replyStatusId, embeddedTweet, retweeterId, retweeted, favorited, place, geo);
+ mediaType, source, replyStatusId, embeddedTweet, retweeterId, retweeted, favorited, place, geo);
}
@@ -654,6 +665,19 @@ public class AppDatabase {
} else {
statusRegister &= ~RTW_MASK;
}
+ switch (tweet.getMediaType()) {
+ case IMAGE:
+ statusRegister |= MEDIA_IMAGE_MASK;
+ break;
+
+ case VIDEO:
+ statusRegister |= MEDIA_VIDEO_MASK;
+ break;
+
+ case GIF:
+ statusRegister |= MEDIA_ANGIF_MASK;
+ break;
+ }
status.put("media", getMediaLinks(tweet));
status.put("statusregister", statusRegister);
diff --git a/app/src/main/java/org/nuclearfog/twidda/database/GlobalSettings.java b/app/src/main/java/org/nuclearfog/twidda/database/GlobalSettings.java
index faf42918..b1d1115a 100644
--- a/app/src/main/java/org/nuclearfog/twidda/database/GlobalSettings.java
+++ b/app/src/main/java/org/nuclearfog/twidda/database/GlobalSettings.java
@@ -9,7 +9,7 @@ import org.nuclearfog.twidda.backend.items.TrendLocation;
import static android.content.Context.MODE_PRIVATE;
-public final class GlobalSettings {
+public class GlobalSettings {
public static final Typeface[] fonts = {Typeface.DEFAULT, Typeface.MONOSPACE,
Typeface.SERIF, Typeface.create("sans-serif-thin", Typeface.NORMAL)};
diff --git a/app/src/main/res/drawable/images.xml b/app/src/main/res/drawable/images.xml
new file mode 100644
index 00000000..2a44abeb
--- /dev/null
+++ b/app/src/main/res/drawable/images.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/item_trend.xml b/app/src/main/res/layout/item_trend.xml
index 09dc8993..d4af8dc1 100644
--- a/app/src/main/res/layout/item_trend.xml
+++ b/app/src/main/res/layout/item_trend.xml
@@ -23,7 +23,7 @@
android:textSize="@dimen/textsize_trendname" />
diff --git a/app/src/main/res/layout/page_settings.xml b/app/src/main/res/layout/page_settings.xml
index d3f8e0f1..71094ae8 100644
--- a/app/src/main/res/layout/page_settings.xml
+++ b/app/src/main/res/layout/page_settings.xml
@@ -153,7 +153,7 @@
android:id="@+id/load_dialog"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
- android:layout_height="@dimen/button_settings"
+ android:layout_height="@dimen/button_settings_height"
android:layout_marginStart="@dimen/button_margin"
android:layout_marginLeft="@dimen/button_margin"
android:layout_marginEnd="@dimen/button_margin"
@@ -229,7 +229,7 @@
android:id="@+id/delete_db"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
- android:layout_height="@dimen/button_settings"
+ android:layout_height="@dimen/button_settings_height"
android:layout_margin="@dimen/button_margin"
android:layout_weight="1"
android:background="@drawable/button"
@@ -240,7 +240,7 @@
android:id="@+id/logout"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
- android:layout_height="@dimen/button_settings"
+ android:layout_height="@dimen/button_settings_height"
android:layout_margin="@dimen/button_margin"
android:layout_weight="1"
android:background="@drawable/button"
diff --git a/app/src/main/res/layout/page_tweet.xml b/app/src/main/res/layout/page_tweet.xml
index 59e5e006..5ff94e1d 100644
--- a/app/src/main/res/layout/page_tweet.xml
+++ b/app/src/main/res/layout/page_tweet.xml
@@ -112,26 +112,14 @@
android:visibility="gone" />
-
-
+ android:visibility="gone" />
+ app:srcCompat="@drawable/twitter4j_badge"
+ android:contentDescription="@string/badge_twitter4j" />
Proxy Login
Proxy port muss gesetzt werden!
Proxy Passort darf nicht leer sein!
- Videovorschau Button
Fehler beim Öffnen des links!
Bild konnte nicht geladen werden!
Direktnachricht konnte nicht an diesen Nutzer gesendet werden!
@@ -146,4 +145,5 @@
App und Drittanbieter Lizenz:
Github Seite:
Zu viele Anfragen! Bitte 15 Minuten warten!
+ Video konnte nicht hinzugefügt werden!
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 6b170a59..720eb6d1 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -2,22 +2,18 @@
45dp
2dp
-
80dp
- 40dp
- 36dp
- 56dp
-
+ 40sp
+ 36sp
+ 56sp
5dp
16dp
5dp
2dp
10dp
-
20dp
5dp
10dp
-
150dp
5dp
300dp
@@ -39,23 +35,22 @@
11sp
9
3
-
40dp
- 40dp
- 30dp
- 36dp
+ 40sp
+ 30sp
+ 36sp
5dp
5dp
- 20dp
+ 20sp
40dp
40dp
36dp
64dp
10dp
- 20dp
+ 20sp
5dp
30dp
- 20dp
+ 20sp
4dp
5dp
10dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index daf44472..93ce5979 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -73,7 +73,6 @@
Link copied to clipboard!
link
image preview button
- video preview button
close direct message
user not found!
cannot send dm to user!
@@ -148,4 +147,6 @@
http://www.apache.org/licenses/LICENSE-2.0
App on GitHub:
Too many requests! Please wait 15 minutes.
+ Can\'t add video!
+ Twitter4J Badge
\ No newline at end of file