removed unnecessary code, bug fix, layout fix
This commit is contained in:
parent
5229d05ef1
commit
6ff138e971
|
@ -19,8 +19,8 @@
|
|||
<option name="values">
|
||||
<map>
|
||||
<entry key="assetSourceType" value="FILE" />
|
||||
<entry key="outputName" value="list" />
|
||||
<entry key="sourceFile" value="$USER_HOME$/Dokumente/Rest/Entypo SVG/list.svg" />
|
||||
<entry key="outputName" value="images" />
|
||||
<entry key="sourceFile" value="$USER_HOME$/Dokumente/Rest/Entypo SVG/images.svg" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
|
|
@ -8,7 +8,7 @@ android {
|
|||
applicationId 'org.nuclearfog.twidda'
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 29
|
||||
versionCode 14
|
||||
versionCode 15
|
||||
versionName '1.7.7'
|
||||
vectorDrawables.useSupportLibrary true
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<ListAdapter.ListHolder> {
|
|||
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<ListAdapter.ListHolder> {
|
|||
}
|
||||
|
||||
|
||||
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;
|
||||
|
|
|
@ -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<MessageAdapter.MessageHolder> {
|
|||
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<MessageAdapter.MessageHolder> {
|
|||
}
|
||||
|
||||
|
||||
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;
|
||||
|
|
|
@ -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<TweetAdapter.ItemHolder> {
|
|||
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<TweetAdapter.ItemHolder> {
|
|||
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;
|
||||
|
|
|
@ -76,13 +76,13 @@ public class MessageListLoader extends AsyncTask<Long, Void, List<Message>> {
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -114,7 +114,8 @@ public class TweetLoader extends AsyncTask<Long, Tweet, Tweet> {
|
|||
if (ui.get() != null) {
|
||||
if (tweet != null) {
|
||||
ui.get().onAction(tweet, action);
|
||||
} else if (twException != null) {
|
||||
}
|
||||
if (twException != null) {
|
||||
ui.get().onError(twException);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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)};
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:pathData="M17.125,6.17l-2.046,-5.635c-0.151,-0.416 -0.595,-0.637 -0.989,-0.492L0.492,5.006C0.098,5.15 -0.101,5.603 0.051,6.019l2.156,5.941V8.777c0,-1.438 1.148,-2.607 2.56,-2.607H8.36l4.285,-3.008l2.479,3.008H17.125zM19.238,8H4.767c-0.42,0 -0.762,0.334 -0.762,0.777v9.42C4.006,18.641 4.348,19 4.767,19h14.471C19.658,19 20,18.641 20,18.197v-9.42C20,8.334 19.658,8 19.238,8zM18,17H6v-2l1.984,-4.018l2.768,3.436l2.598,-2.662l3.338,-1.205L18,14V17z"
|
||||
android:fillColor="#FFFFFF" />
|
||||
</vector>
|
|
@ -23,7 +23,7 @@
|
|||
android:textSize="@dimen/textsize_trendname" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_weight="8"
|
||||
android:layout_weight="7"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -112,26 +112,14 @@
|
|||
android:visibility="gone" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/image_attach"
|
||||
android:id="@+id/tweet_media_attach"
|
||||
android:layout_width="@dimen/button_media_width"
|
||||
android:layout_height="@dimen/button_media_height"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="@dimen/tweet_media_button_margin"
|
||||
android:background="@drawable/button"
|
||||
android:contentDescription="@string/image_preview_button"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/image" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/video_attach"
|
||||
android:layout_width="@dimen/button_media_width"
|
||||
android:layout_height="@dimen/button_media_height"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="@dimen/tweet_media_button_margin"
|
||||
android:background="@drawable/button"
|
||||
android:contentDescription="@string/video_preview_button"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/video" />
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
android:textSize="@dimen/settings_info_appname_font" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/twitter4j_badge" />
|
||||
app:srcCompat="@drawable/twitter4j_badge"
|
||||
android:contentDescription="@string/badge_twitter4j" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -109,7 +109,6 @@
|
|||
<string name="proxy_authentication">Proxy Login</string>
|
||||
<string name="error_empty_port">Proxy port muss gesetzt werden!</string>
|
||||
<string name="error_empty_pass">Proxy Passort darf nicht leer sein!</string>
|
||||
<string name="video_preview_button">Videovorschau Button</string>
|
||||
<string name="error_open_link">Fehler beim Öffnen des links!</string>
|
||||
<string name="error_image_download">Bild konnte nicht geladen werden!</string>
|
||||
<string name="error_dm_send">Direktnachricht konnte nicht an diesen Nutzer gesendet werden!</string>
|
||||
|
@ -146,4 +145,5 @@
|
|||
<string name="settings_3rd_party_license">App und Drittanbieter Lizenz:</string>
|
||||
<string name="settings_info_github">Github Seite:</string>
|
||||
<string name="error_rate_limit">Zu viele Anfragen! Bitte 15 Minuten warten!</string>
|
||||
<string name="info_cant_add_video">Video konnte nicht hinzugefügt werden!</string>
|
||||
</resources>
|
|
@ -2,22 +2,18 @@
|
|||
<resources>
|
||||
<dimen name="toolbar_height">45dp</dimen>
|
||||
<dimen name="divider">2dp</dimen>
|
||||
|
||||
<dimen name="profile_image">80dp</dimen>
|
||||
<dimen name="profile_middle">40dp</dimen>
|
||||
<dimen name="profile_small">36dp</dimen>
|
||||
<dimen name="tweet_profile">56dp</dimen>
|
||||
|
||||
<dimen name="profile_middle">40sp</dimen>
|
||||
<dimen name="profile_small">36sp</dimen>
|
||||
<dimen name="tweet_profile">56sp</dimen>
|
||||
<dimen name="margin_dm_icon">5dp</dimen>
|
||||
<dimen name="margin_tweet_icon">16dp</dimen>
|
||||
<dimen name="margin_layout">5dp</dimen>
|
||||
<dimen name="margin_layout_tweet">2dp</dimen>
|
||||
<dimen name="margin_side">10dp</dimen>
|
||||
|
||||
<dimen name="padding_editprofile">20dp</dimen>
|
||||
<dimen name="padding_drawable">5dp</dimen>
|
||||
<dimen name="padding_side">10dp</dimen>
|
||||
|
||||
<dimen name="text_bio_height">150dp</dimen>
|
||||
<dimen name="text_settings">5dp</dimen>
|
||||
<dimen name="text_input_width">300dp</dimen>
|
||||
|
@ -39,23 +35,22 @@
|
|||
<dimen name="textsize_settings_small">11sp</dimen>
|
||||
<integer name="text_tweet_lines">9</integer>
|
||||
<integer name="text_bio_lines">3</integer>
|
||||
|
||||
<dimen name="button_dm">40dp</dimen>
|
||||
<dimen name="button_settings_color">40dp</dimen>
|
||||
<dimen name="button_settings">30dp</dimen>
|
||||
<dimen name="button_load">36dp</dimen>
|
||||
<dimen name="button_settings_color">40sp</dimen>
|
||||
<dimen name="button_settings_height">30sp</dimen>
|
||||
<dimen name="button_load">36sp</dimen>
|
||||
<dimen name="button_margin">5dp</dimen>
|
||||
<dimen name="button_padding">5dp</dimen>
|
||||
<dimen name="button_height">20dp</dimen>
|
||||
<dimen name="button_height">20sp</dimen>
|
||||
<dimen name="button_size">40dp</dimen>
|
||||
<dimen name="button_tweet_size">40dp</dimen>
|
||||
<dimen name="button_media_height">36dp</dimen>
|
||||
<dimen name="button_media_width">64dp</dimen>
|
||||
<dimen name="preview_margin">10dp</dimen>
|
||||
<dimen name="dm_item_button_height">20dp</dimen>
|
||||
<dimen name="dm_item_button_height">20sp</dimen>
|
||||
<dimen name="tweet_media_button_margin">5dp</dimen>
|
||||
<dimen name="tweet_location_progress_size">30dp</dimen>
|
||||
<dimen name="list_button_height">20dp</dimen>
|
||||
<dimen name="list_button_height">20sp</dimen>
|
||||
<dimen name="listitem_margin">4dp</dimen>
|
||||
<dimen name="list_padding">5dp</dimen>
|
||||
<dimen name="list_bar_padding">10dp</dimen>
|
||||
|
|
|
@ -73,7 +73,6 @@
|
|||
<string name="info_clipboard">Link copied to clipboard!</string>
|
||||
<string name="profile_link">link</string>
|
||||
<string name="image_preview_button">image preview button</string>
|
||||
<string name="video_preview_button">video preview button</string>
|
||||
<string name="close_dm">close direct message</string>
|
||||
<string name="error_user_not_found">user not found!</string>
|
||||
<string name="error_send_dm_to_user">cannot send dm to user!</string>
|
||||
|
@ -148,4 +147,6 @@
|
|||
<string name="settings_info_license_link" translatable="false">http://www.apache.org/licenses/LICENSE-2.0</string>
|
||||
<string name="settings_info_github">App on GitHub:</string>
|
||||
<string name="error_rate_limit">Too many requests! Please wait 15 minutes.</string>
|
||||
<string name="info_cant_add_video">Can\'t add video!</string>
|
||||
<string name="badge_twitter4j" translatable="false">Twitter4J Badge</string>
|
||||
</resources>
|
Loading…
Reference in New Issue