mirror of
https://github.com/nuclearfog/Shitter.git
synced 2025-01-30 10:55:06 +01:00
added directmessage media button, added proxy settings for picasso and okhttp
This commit is contained in:
parent
c3ec249efb
commit
7f8fd9e7bc
@ -715,9 +715,11 @@ public class UserProfile extends AppCompatActivity implements OnClickListener, O
|
||||
* @param err Engine Exception
|
||||
*/
|
||||
public void onError(@Nullable ErrorHandler.TwitterError err) {
|
||||
ErrorHandler.handleFailure(this, err); // fixme
|
||||
//if (user == null || (err != null && err.resourceNotFound())) {
|
||||
// finish();
|
||||
//}
|
||||
ErrorHandler.handleFailure(this, err);
|
||||
if (user == null || (err != null
|
||||
&& (err.getErrorType() == ErrorHandler.TwitterError.RESOURCE_NOT_FOUND
|
||||
|| err.getErrorType() == ErrorHandler.TwitterError.USER_NOT_FOUND))) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
@ -171,6 +171,15 @@ public class MessageAdapter extends Adapter<ViewHolder> {
|
||||
}
|
||||
}
|
||||
});
|
||||
vh.mediaButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = vh.getLayoutPosition();
|
||||
if (position != NO_POSITION) {
|
||||
itemClickListener.onClick(data.get(position), OnItemSelected.Action.MEDIA);
|
||||
}
|
||||
}
|
||||
});
|
||||
return vh;
|
||||
} else {
|
||||
final Footer footer = new Footer(parent, settings, false);
|
||||
@ -216,6 +225,11 @@ public class MessageAdapter extends Adapter<ViewHolder> {
|
||||
} else {
|
||||
holder.lockedIcon.setVisibility(GONE);
|
||||
}
|
||||
if (message.getMedia() != null && !message.getMedia().isEmpty()) {
|
||||
holder.mediaButton.setVisibility(VISIBLE);
|
||||
} else {
|
||||
holder.mediaButton.setVisibility(GONE);
|
||||
}
|
||||
if (settings.imagesEnabled() && !sender.getImageUrl().isEmpty()) {
|
||||
String pbLink = sender.getImageUrl();
|
||||
if (!sender.hasDefaultProfileImage())
|
||||
@ -255,6 +269,7 @@ public class MessageAdapter extends Adapter<ViewHolder> {
|
||||
ANSWER,
|
||||
DELETE,
|
||||
PROFILE,
|
||||
MEDIA
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,7 @@ import android.text.method.LinkMovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -27,6 +28,7 @@ public class MessageHolder extends ViewHolder {
|
||||
public final TextView[] textViews = new TextView[5];
|
||||
public final Button[] buttons = new Button[2];
|
||||
public final ImageView profile_img, verifiedIcon, lockedIcon;
|
||||
public final ImageButton mediaButton;
|
||||
|
||||
/**
|
||||
* @param parent Parent view from adapter
|
||||
@ -39,6 +41,7 @@ public class MessageHolder extends ViewHolder {
|
||||
profile_img = itemView.findViewById(R.id.dm_profile_img);
|
||||
verifiedIcon = itemView.findViewById(R.id.dm_user_verified);
|
||||
lockedIcon = itemView.findViewById(R.id.dm_user_locked);
|
||||
mediaButton = itemView.findViewById(R.id.dm_media);
|
||||
textViews[0] = itemView.findViewById(R.id.dm_username);
|
||||
textViews[1] = itemView.findViewById(R.id.dm_screenname);
|
||||
textViews[2] = itemView.findViewById(R.id.dm_receiver);
|
||||
@ -50,6 +53,7 @@ public class MessageHolder extends ViewHolder {
|
||||
receiver_icon.setImageResource(R.drawable.right);
|
||||
verifiedIcon.setImageResource(R.drawable.verify);
|
||||
lockedIcon.setImageResource(R.drawable.lock);
|
||||
mediaButton.setImageResource(R.drawable.image);
|
||||
// theme views
|
||||
for (TextView tv : textViews) {
|
||||
tv.setTextColor(settings.getFontColor());
|
||||
@ -62,6 +66,7 @@ public class MessageHolder extends ViewHolder {
|
||||
}
|
||||
verifiedIcon.setColorFilter(settings.getIconColor(), SRC_IN);
|
||||
lockedIcon.setColorFilter(settings.getIconColor(), SRC_IN);
|
||||
mediaButton.setColorFilter(settings.getIconColor(), SRC_IN);
|
||||
receiver_icon.setColorFilter(settings.getIconColor(), SRC_IN);
|
||||
background.setCardBackgroundColor(settings.getCardColor());
|
||||
// make links clickable
|
||||
|
@ -22,6 +22,13 @@ class TweetV1 implements Tweet {
|
||||
*/
|
||||
static final String EXT_MODE = "tweet_mode=extended";
|
||||
|
||||
/**
|
||||
* include ID of the reteet if available
|
||||
*/
|
||||
static final String INCL_RT_ID = "include_my_retweet=true";
|
||||
|
||||
static final String INCL_ENTITIES = "include_entities=true";
|
||||
|
||||
/**
|
||||
* twitter video/gif MIME
|
||||
*/
|
||||
@ -65,7 +72,7 @@ class TweetV1 implements Tweet {
|
||||
String replyName = json.optString("in_reply_to_screen_name");
|
||||
|
||||
JSONObject user = json.getJSONObject("user");
|
||||
JSONObject quoted_tweet = json.optJSONObject("quoted_status");
|
||||
JSONObject quoted_tweet = json.optJSONObject("retweeted_status");
|
||||
JSONObject user_retweet = json.optJSONObject("current_user_retweet");
|
||||
JSONObject entities = json.optJSONObject("entities");
|
||||
JSONObject extEntities = json.optJSONObject("extended_entities");
|
||||
|
@ -12,6 +12,9 @@ import org.json.JSONObject;
|
||||
import org.nuclearfog.twidda.backend.lists.Directmessages;
|
||||
import org.nuclearfog.twidda.backend.lists.UserLists;
|
||||
import org.nuclearfog.twidda.backend.lists.Users;
|
||||
import org.nuclearfog.twidda.backend.proxy.ProxyAuthenticator;
|
||||
import org.nuclearfog.twidda.backend.proxy.ProxySetup;
|
||||
import org.nuclearfog.twidda.backend.proxy.UserProxy;
|
||||
import org.nuclearfog.twidda.backend.utils.StringTools;
|
||||
import org.nuclearfog.twidda.backend.utils.TLSSocketFactory;
|
||||
import org.nuclearfog.twidda.backend.utils.Tokens;
|
||||
@ -27,6 +30,7 @@ import org.nuclearfog.twidda.model.UserList;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.security.KeyStore;
|
||||
import java.util.ArrayList;
|
||||
@ -122,8 +126,17 @@ public class Twitter {
|
||||
|
||||
|
||||
private Twitter(Context context) {
|
||||
settings = GlobalSettings.getInstance(context);
|
||||
tokens = Tokens.getInstance(context);
|
||||
filterList = new ExcludeDatabase(context);
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
builder.writeTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).connectTimeout(60, TimeUnit.SECONDS);
|
||||
// setup proxy settings
|
||||
builder.proxy(UserProxy.get(settings));
|
||||
builder.proxyAuthenticator(new ProxyAuthenticator(settings));
|
||||
// apply global proxy settings
|
||||
ProxySetup.setConnection(settings);
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
// set TLS 1.2 support for default connections
|
||||
TLSSocketFactory.setSupportTLS();
|
||||
@ -134,14 +147,10 @@ public class Twitter {
|
||||
X509TrustManager manager = (X509TrustManager) factory.getTrustManagers()[0];
|
||||
builder.sslSocketFactory(new TLSSocketFactory(), manager);
|
||||
} catch (Exception e) {
|
||||
// ignore, user default setting
|
||||
// ignore, use default setting
|
||||
}
|
||||
}
|
||||
// todo add proxy settings
|
||||
client = builder.build();
|
||||
tokens = Tokens.getInstance(context);
|
||||
settings = GlobalSettings.getInstance(context);
|
||||
filterList = new ExcludeDatabase(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -604,7 +613,7 @@ public class Twitter {
|
||||
* @return list of tweets
|
||||
*/
|
||||
public List<Tweet> getHomeTimeline(long minId, long maxId) throws TwitterException {
|
||||
List<String> params = new ArrayList<>(5);
|
||||
List<String> params = new ArrayList<>(7);
|
||||
if (minId > 0)
|
||||
params.add("since_id=" + minId);
|
||||
if (maxId > 0)
|
||||
@ -620,7 +629,7 @@ public class Twitter {
|
||||
* @return list of tweets
|
||||
*/
|
||||
public List<Tweet> getMentionTimeline(long minId, long maxId) throws TwitterException {
|
||||
List<String> params = new ArrayList<>(5);
|
||||
List<String> params = new ArrayList<>(7);
|
||||
if (minId > 0)
|
||||
params.add("since_id=" + minId);
|
||||
if (maxId > 1)
|
||||
@ -637,7 +646,7 @@ public class Twitter {
|
||||
* @return list of tweets
|
||||
*/
|
||||
public List<Tweet> getUserTimeline(long userId, long minId, long maxId) throws TwitterException {
|
||||
List<String> params = new ArrayList<>(6);
|
||||
List<String> params = new ArrayList<>(8);
|
||||
if (minId > 0)
|
||||
params.add("since_id=" + minId);
|
||||
if (maxId > 1)
|
||||
@ -655,7 +664,7 @@ public class Twitter {
|
||||
* @return list of tweets
|
||||
*/
|
||||
public List<Tweet> getUserTimeline(String screen_name, long minId, long maxId) throws TwitterException {
|
||||
List<String> params = new ArrayList<>(6);
|
||||
List<String> params = new ArrayList<>(8);
|
||||
if (minId > 0)
|
||||
params.add("since_id=" + minId);
|
||||
if (maxId > 1)
|
||||
@ -673,7 +682,7 @@ public class Twitter {
|
||||
* @return list of tweets
|
||||
*/
|
||||
public List<Tweet> getUserFavorits(long userId, long minId, long maxId) throws TwitterException {
|
||||
List<String> params = new ArrayList<>(6);
|
||||
List<String> params = new ArrayList<>(8);
|
||||
if (minId > 0)
|
||||
params.add("since_id=" + minId);
|
||||
if (maxId > 1)
|
||||
@ -691,7 +700,7 @@ public class Twitter {
|
||||
* @return list of tweets
|
||||
*/
|
||||
public List<Tweet> getUserFavorits(String screen_name, long minId, long maxId) throws TwitterException {
|
||||
List<String> params = new ArrayList<>(6);
|
||||
List<String> params = new ArrayList<>(8);
|
||||
if (minId > 0)
|
||||
params.add("since_id=" + minId);
|
||||
if (maxId > 1)
|
||||
@ -709,7 +718,7 @@ public class Twitter {
|
||||
* @return list of tweets
|
||||
*/
|
||||
public List<Tweet> getUserlistTweets(long listId, long minId, long maxId) throws TwitterException {
|
||||
List<String> params = new ArrayList<>(6);
|
||||
List<String> params = new ArrayList<>(8);
|
||||
if (minId > 0)
|
||||
params.add("since_id=" + minId);
|
||||
if (maxId > 1)
|
||||
@ -1174,8 +1183,8 @@ public class Twitter {
|
||||
if (link.startsWith("https://ton.twitter.com/")) {
|
||||
Response response = get(link, new ArrayList<>(0));
|
||||
if (response.code() == 200) {
|
||||
byte[] data = response.body().bytes();
|
||||
return BitmapFactory.decodeByteArray(data, 0, 0);
|
||||
InputStream is = response.body().byteStream();
|
||||
return BitmapFactory.decodeStream(is);
|
||||
} else {
|
||||
throw new TwitterException(response);
|
||||
}
|
||||
@ -1237,6 +1246,8 @@ public class Twitter {
|
||||
private List<Tweet> getTweets1(String endpoint, List<String> params) throws TwitterException {
|
||||
try {
|
||||
params.add(TweetV1.EXT_MODE);
|
||||
params.add(TweetV1.INCL_RT_ID);
|
||||
params.add(TweetV1.INCL_ENTITIES);
|
||||
params.add("count=" + settings.getListSize());
|
||||
Response response = get(endpoint, params);
|
||||
if (response.body() != null) {
|
||||
@ -1275,6 +1286,8 @@ public class Twitter {
|
||||
private Tweet getTweet(String endpoint, List<String> params) throws TwitterException {
|
||||
try {
|
||||
params.add(TweetV1.EXT_MODE);
|
||||
params.add(TweetV1.INCL_RT_ID);
|
||||
params.add(TweetV1.INCL_ENTITIES);
|
||||
Response response;
|
||||
if (endpoint.equals(SHOW_TWEET)) {
|
||||
response = get(endpoint, params);
|
||||
|
@ -0,0 +1,38 @@
|
||||
package org.nuclearfog.twidda.backend.proxy;
|
||||
|
||||
import org.nuclearfog.twidda.database.GlobalSettings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class hosts {@link UserProxy} and provides the proxy settings on demand
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class AppProxySelector extends ProxySelector {
|
||||
|
||||
private List<Proxy> proxyList;
|
||||
|
||||
|
||||
public AppProxySelector(GlobalSettings settings) {
|
||||
Proxy httpsProxy = UserProxy.get(settings);
|
||||
proxyList = new ArrayList<>(2);
|
||||
proxyList.add(httpsProxy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Proxy> select(URI uri) {
|
||||
return proxyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
// ignore
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package org.nuclearfog.twidda.backend.proxy;
|
||||
|
||||
import org.nuclearfog.twidda.database.GlobalSettings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Authenticator;
|
||||
import java.net.PasswordAuthentication;
|
||||
|
||||
import okhttp3.Credentials;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.Route;
|
||||
|
||||
/**
|
||||
* this class provides proxy authentication
|
||||
* when proxy settings changes, the new setup will be applied immediately
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class ProxyAuthenticator extends Authenticator implements okhttp3.Authenticator {
|
||||
private GlobalSettings settings;
|
||||
|
||||
|
||||
public ProxyAuthenticator(GlobalSettings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
if (settings.isProxyAuthSet()) {
|
||||
String username = settings.getProxyUser();
|
||||
char[] password = settings.getProxyPass().toCharArray();
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
return new PasswordAuthentication("", new char[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request authenticate(Route route, Response response) {
|
||||
if (settings.isProxyAuthSet()) {
|
||||
String credential = Credentials.basic(settings.getProxyUser(), settings.getProxyPass());
|
||||
return response.request().newBuilder().header("Proxy-Authorization", credential).build();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package org.nuclearfog.twidda.backend.proxy;
|
||||
|
||||
import org.nuclearfog.twidda.database.GlobalSettings;
|
||||
|
||||
import java.net.Authenticator;
|
||||
import java.net.ProxySelector;
|
||||
|
||||
/**
|
||||
* This class setups a proxy for libraries which don't support proxy setup
|
||||
* like VideoView
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class ProxySetup {
|
||||
|
||||
private ProxySetup() {
|
||||
}
|
||||
|
||||
/**
|
||||
* initializes the proxy connection with login
|
||||
*
|
||||
* @param settings App settings
|
||||
*/
|
||||
public static void setConnection(GlobalSettings settings) {
|
||||
init(settings);
|
||||
}
|
||||
|
||||
|
||||
private static void init(GlobalSettings settings) {
|
||||
AppProxySelector proxyConnection = new AppProxySelector(settings);
|
||||
ProxyAuthenticator proxyLogin = new ProxyAuthenticator(settings);
|
||||
try {
|
||||
ProxySelector.setDefault(proxyConnection);
|
||||
Authenticator.setDefault(proxyLogin);
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package org.nuclearfog.twidda.backend.proxy;
|
||||
|
||||
import org.nuclearfog.twidda.database.GlobalSettings;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
/**
|
||||
* custom proxy implementation
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class UserProxy extends Proxy {
|
||||
|
||||
private UserProxy(Type type, SocketAddress sa) {
|
||||
super(type, sa);
|
||||
}
|
||||
|
||||
/**
|
||||
* return proxy instance with custom settings
|
||||
* @param settings app settings
|
||||
* @return proxy instance
|
||||
*/
|
||||
public static Proxy get(GlobalSettings settings) {
|
||||
if (settings.isProxyEnabled()) {
|
||||
String proxyHost = settings.getProxyHost();
|
||||
int proxyPort = settings.getProxyPortNumber();
|
||||
InetSocketAddress addr = new InetSocketAddress(proxyHost, proxyPort);
|
||||
return new UserProxy(Type.HTTP, addr);
|
||||
}
|
||||
return Proxy.NO_PROXY;
|
||||
}
|
||||
}
|
@ -147,9 +147,6 @@ public final class ErrorHandler {
|
||||
int REQUEST_FORBIDDEN = 18;
|
||||
int APP_SUSPENDED = 19;
|
||||
int ERROR_API_ACCESS_DENIED = 20;
|
||||
int FILENOTFOUND = 23;
|
||||
int TOKENNOTSET = 22;
|
||||
int BITMAP_FAILURE = 21;
|
||||
|
||||
int getErrorType();
|
||||
|
||||
|
@ -6,6 +6,10 @@ import android.os.Build;
|
||||
import com.squareup.picasso.OkHttp3Downloader;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import org.nuclearfog.twidda.backend.proxy.ProxyAuthenticator;
|
||||
import org.nuclearfog.twidda.backend.proxy.UserProxy;
|
||||
import org.nuclearfog.twidda.database.GlobalSettings;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
@ -29,24 +33,37 @@ public class PicassoBuilder {
|
||||
*/
|
||||
public static Picasso get(Context context) {
|
||||
if (downloader == null) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
try {
|
||||
// try to enable TLS 1.2 support for picasso
|
||||
TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
factory.init((KeyStore) null);
|
||||
X509TrustManager manager = (X509TrustManager) factory.getTrustManagers()[0];
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
builder.sslSocketFactory(new TLSSocketFactory(), manager);
|
||||
downloader = new OkHttp3Downloader(builder.build());
|
||||
} catch (Exception e) {
|
||||
// fallback to default downloader
|
||||
downloader = new OkHttp3Downloader(context);
|
||||
}
|
||||
} else {
|
||||
// use default downloader
|
||||
downloader = new OkHttp3Downloader(context);
|
||||
}
|
||||
GlobalSettings settings = GlobalSettings.getInstance(context);
|
||||
init(settings);
|
||||
}
|
||||
return new Picasso.Builder(context).downloader(downloader).build();
|
||||
}
|
||||
|
||||
|
||||
private static void init(GlobalSettings settings) {
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
|
||||
// setup proxy
|
||||
if (settings.isProxyEnabled()) {
|
||||
builder.proxy(UserProxy.get(settings));
|
||||
if (settings.isProxyAuthSet()) {
|
||||
builder.proxyAuthenticator(new ProxyAuthenticator(settings));
|
||||
}
|
||||
}
|
||||
|
||||
// setup TLS 1.2 support if needed
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
try {
|
||||
TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
factory.init((KeyStore) null);
|
||||
X509TrustManager manager = (X509TrustManager) factory.getTrustManagers()[0];
|
||||
builder.sslSocketFactory(new TLSSocketFactory(), manager);
|
||||
downloader = new OkHttp3Downloader(builder.build());
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
// ignore, try without TLS 1.2 support
|
||||
}
|
||||
}
|
||||
downloader = new OkHttp3Downloader(builder.build());
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
package org.nuclearfog.twidda.backend.utils;
|
||||
|
||||
import org.nuclearfog.twidda.database.GlobalSettings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Authenticator;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Creates a https proxy connection for all connections except Twitter4J
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class ProxySetup {
|
||||
|
||||
private ProxySetup() {
|
||||
}
|
||||
|
||||
/**
|
||||
* initializes the proxy connection with login
|
||||
*
|
||||
* @param settings App settings
|
||||
*/
|
||||
public static void setConnection(GlobalSettings settings) {
|
||||
ProxyConnection proxyConnection;
|
||||
ProxyAuthenticator proxyLogin;
|
||||
|
||||
if (settings.isProxyEnabled()) {
|
||||
proxyConnection = new ProxyConnection(settings);
|
||||
} else {
|
||||
proxyConnection = new ProxyConnection();
|
||||
}
|
||||
if (settings.isProxyAuthSet()) {
|
||||
proxyLogin = new ProxyAuthenticator(settings);
|
||||
} else {
|
||||
proxyLogin = new ProxyAuthenticator();
|
||||
}
|
||||
try {
|
||||
ProxySelector.setDefault(proxyConnection);
|
||||
Authenticator.setDefault(proxyLogin);
|
||||
} catch (SecurityException sErr) {
|
||||
sErr.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connect to a proxy server
|
||||
*/
|
||||
private static class ProxyConnection extends ProxySelector {
|
||||
|
||||
private List<Proxy> proxyList;
|
||||
|
||||
/**
|
||||
* Creates a direct connection without proxy
|
||||
*/
|
||||
ProxyConnection() {
|
||||
proxyList = new ArrayList<>(1);
|
||||
proxyList.add(Proxy.NO_PROXY);
|
||||
}
|
||||
|
||||
/**
|
||||
* set system proxy for all http requests
|
||||
*
|
||||
* @param settings App settings
|
||||
*/
|
||||
ProxyConnection(GlobalSettings settings) {
|
||||
String proxyHost = settings.getProxyHost();
|
||||
int proxyPort = settings.getProxyPortNumber();
|
||||
InetSocketAddress socket = new InetSocketAddress(proxyHost, proxyPort);
|
||||
Proxy httpsProxy = new Proxy(Proxy.Type.HTTP, socket);
|
||||
proxyList = new ArrayList<>(1);
|
||||
proxyList.add(httpsProxy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Proxy> select(URI uri) {
|
||||
return proxyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
// ignore to force using proxy and avoid data leak
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an authenticator for proxy login
|
||||
*/
|
||||
private static class ProxyAuthenticator extends Authenticator {
|
||||
|
||||
private static final String NO_NM = "";
|
||||
private static final char[] NO_PW = {};
|
||||
|
||||
private PasswordAuthentication proxyPass;
|
||||
|
||||
/**
|
||||
* unset all login information for proxy
|
||||
*/
|
||||
ProxyAuthenticator() {
|
||||
proxyPass = new PasswordAuthentication(NO_NM, NO_PW);
|
||||
}
|
||||
|
||||
/**
|
||||
* set proxy login
|
||||
*
|
||||
* @param settings App settings
|
||||
*/
|
||||
ProxyAuthenticator(GlobalSettings settings) {
|
||||
String username = settings.getProxyUser();
|
||||
char[] password = settings.getProxyPass().toCharArray();
|
||||
proxyPass = new PasswordAuthentication(username, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return proxyPass;
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ class DirectMessageDB implements DirectMessage {
|
||||
private long id;
|
||||
private long time;
|
||||
private String text;
|
||||
private String media = "";
|
||||
private User sender;
|
||||
private User receiver;
|
||||
|
||||
@ -50,6 +51,6 @@ class DirectMessageDB implements DirectMessage {
|
||||
|
||||
@Override
|
||||
public String getMedia() {
|
||||
return "";
|
||||
return media;
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.nuclearfog.twidda.R;
|
||||
import org.nuclearfog.twidda.activities.MediaViewer;
|
||||
import org.nuclearfog.twidda.activities.MessageEditor;
|
||||
import org.nuclearfog.twidda.activities.SearchPage;
|
||||
import org.nuclearfog.twidda.activities.TweetActivity;
|
||||
@ -28,6 +29,9 @@ import org.nuclearfog.twidda.model.DirectMessage;
|
||||
|
||||
import static android.os.AsyncTask.Status.RUNNING;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
import static org.nuclearfog.twidda.activities.MediaViewer.KEY_MEDIA_LINK;
|
||||
import static org.nuclearfog.twidda.activities.MediaViewer.KEY_MEDIA_TYPE;
|
||||
import static org.nuclearfog.twidda.activities.MediaViewer.MEDIAVIEWER_IMAGE;
|
||||
import static org.nuclearfog.twidda.activities.MessageEditor.KEY_DM_PREFIX;
|
||||
import static org.nuclearfog.twidda.activities.SearchPage.KEY_SEARCH_QUERY;
|
||||
import static org.nuclearfog.twidda.activities.TweetActivity.KEY_TWEET_ID;
|
||||
@ -149,6 +153,13 @@ public class MessageFragment extends ListFragment implements OnItemSelected, OnC
|
||||
profile.putExtra(KEY_PROFILE_DATA, message.getSender());
|
||||
startActivity(profile);
|
||||
break;
|
||||
|
||||
case MEDIA:
|
||||
Intent mediaIntent = new Intent(requireContext(), MediaViewer.class);
|
||||
mediaIntent.putExtra(KEY_MEDIA_LINK, new String[]{message.getMedia()});
|
||||
mediaIntent.putExtra(KEY_MEDIA_TYPE, MEDIAVIEWER_IMAGE);
|
||||
startActivity(mediaIntent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
app:layout_constraintStart_toEndOf="@id/dm_profile_img"
|
||||
app:layout_constraintTop_toTopOf="@id/dm_username"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dm_username"
|
||||
app:layout_constraintEnd_toStartOf="@id/dm_username"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
@ -52,7 +51,6 @@
|
||||
android:singleLine="true"
|
||||
android:textAlignment="gravity"
|
||||
android:textSize="@dimen/dmitem_textsize_date"
|
||||
app:layout_constraintStart_toEndOf="@id/dm_username"
|
||||
app:layout_constraintTop_toTopOf="@id/dm_username"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dm_username"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
@ -66,9 +64,6 @@
|
||||
app:layout_constraintStart_toEndOf="@id/dm_profile_img"
|
||||
app:layout_constraintTop_toTopOf="@id/dm_screenname"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dm_screenname"
|
||||
app:layout_constraintEnd_toStartOf="@id/dm_screenname"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintVertical_bias="1.0"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
@ -85,7 +80,6 @@
|
||||
app:layout_constraintStart_toEndOf="@id/dm_user_locked"
|
||||
app:layout_constraintTop_toBottomOf="@id/dm_username"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dm_profile_img"
|
||||
app:layout_constraintEnd_toStartOf="@id/dm_receiver_icon"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintHorizontal_chainStyle="packed" />
|
||||
|
||||
@ -95,12 +89,9 @@
|
||||
android:layout_height="@dimen/dmitem_icon_size"
|
||||
android:layout_marginLeft="@dimen/dmitem_padding_drawable"
|
||||
android:layout_marginStart="@dimen/dmitem_padding_drawable"
|
||||
android:layout_marginRight="@dimen/dmitem_padding_drawable"
|
||||
android:layout_marginEnd="@dimen/dmitem_padding_drawable"
|
||||
app:layout_constraintStart_toEndOf="@id/dm_screenname"
|
||||
app:layout_constraintTop_toTopOf="@id/dm_screenname"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dm_screenname"
|
||||
app:layout_constraintEnd_toStartOf="@id/dm_receiver"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
tools:ignore="ContentDescription" />
|
||||
@ -112,6 +103,8 @@
|
||||
android:drawablePadding="@dimen/dmitem_padding_drawable"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/dmitem_textsize_name"
|
||||
android:layout_marginLeft="@dimen/dmitem_padding_drawable"
|
||||
android:layout_marginStart="@dimen/dmitem_padding_drawable"
|
||||
app:layout_constraintStart_toEndOf="@id/dm_receiver_icon"
|
||||
app:layout_constraintTop_toTopOf="@id/dm_screenname"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dm_screenname"
|
||||
@ -133,8 +126,27 @@
|
||||
android:linksClickable="true"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dm_profile_barrier"
|
||||
app:layout_constraintBottom_toTopOf="@id/dm_media"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/dm_media"
|
||||
android:layout_width="@dimen/dmitem_button_media_width"
|
||||
android:layout_height="@dimen/dmitem_button_media_height"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/directmessage_media_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/dm_button_barrier"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/dm_button_barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="dm_answer,dm_delete"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/dm_answer"
|
||||
android:layout_width="wrap_content"
|
||||
@ -148,10 +160,9 @@
|
||||
android:text="@string/dm_answer"
|
||||
android:textSize="@dimen/dmitem_textsize_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dm_message"
|
||||
app:layout_constraintTop_toBottomOf="@id/dm_button_barrier"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/dm_delete"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
style="@style/FeedbackButton" />
|
||||
|
||||
<Button
|
||||
@ -165,10 +176,8 @@
|
||||
android:text="@string/delete_dm"
|
||||
android:textSize="@dimen/dmitem_textsize_button"
|
||||
app:layout_constraintStart_toEndOf="@id/dm_answer"
|
||||
app:layout_constraintTop_toBottomOf="@id/dm_message"
|
||||
app:layout_constraintTop_toBottomOf="@id/dm_button_barrier"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
style="@style/FeedbackButton" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -119,6 +119,8 @@
|
||||
<dimen name="dmitem_button_margin">5dp</dimen>
|
||||
<dimen name="dmitem_margin_layout">5dp</dimen>
|
||||
<dimen name="dmitem_icon_size">16sp</dimen>
|
||||
<dimen name="dmitem_button_media_width">48dp</dimen>
|
||||
<dimen name="dmitem_button_media_height">30dp</dimen>
|
||||
|
||||
<!--dimens of page_login.xml-->
|
||||
<dimen name="loginpage_toolbar_height">@dimen/toolbar_height</dimen>
|
||||
|
@ -38,6 +38,7 @@
|
||||
<string name="confirm_delete_database">clear app data?</string>
|
||||
<string name="tweet_sent_from">"sent from: "</string>
|
||||
<string name="directmessage">Directmessage</string>
|
||||
<string name="directmessage_media_button">media attachment</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="dm_message">Message</string>
|
||||
<string name="confirm_cancel_message">discard message?</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user