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