V 1.8.7 added option to add own API key, settings layout fix, fixed error messages

This commit is contained in:
nuclearfog 2021-01-08 15:56:45 +01:00
parent 70fab594b5
commit 79d9c0fb7d
No known key found for this signature in database
GPG Key ID: D5490E4A81F97B14
10 changed files with 246 additions and 67 deletions

View File

@ -9,8 +9,8 @@ android {
applicationId 'org.nuclearfog.twidda'
minSdkVersion 16
targetSdkVersion 30
versionCode 30
versionName '1.8.6'
versionCode 31
versionName '1.8.7'
// limiting language support for smaller APK size
resConfigs 'en', 'de-rDE'
vectorDrawables.useSupportLibrary true

View File

@ -75,13 +75,14 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
private LocationLoader locationAsync;
private LocationAdapter locationAdapter;
private Dialog proxyDialog, databaseDialog, logoutDialog, color_dialog_selector;
private EditText proxyAddr, proxyPort, proxyUser, proxyPass;
private CompoundButton enableProxy, enableAuth, hqImage;
private Dialog connectDialog, databaseDialog, logoutDialog, color_dialog_selector;
private EditText proxyAddr, proxyPort, proxyUser, proxyPass, api_key1, api_key2;
private CompoundButton enableProxy, enableAuth, hqImage, enableAPI;
private SeekBar listSizeSelector;
private Spinner locationSpinner;
private TextView list_size;
private Button[] colorButtons;
private View layout_key, layout_proxy, layout_auth_en, layout_auth;
private View root;
private ColorMode mode = ColorMode.NONE;
@ -103,12 +104,21 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
enableProxy = findViewById(R.id.settings_enable_proxy);
enableAuth = findViewById(R.id.settings_enable_auth);
hqImage = findViewById(R.id.settings_image_hq);
enableAPI = findViewById(R.id.settings_set_custom_keys);
locationSpinner = findViewById(R.id.spinner_woeid);
proxyAddr = findViewById(R.id.edit_proxyadress);
proxyPort = findViewById(R.id.edit_proxyport);
proxyAddr = findViewById(R.id.edit_proxy_address);
proxyPort = findViewById(R.id.edit_proxy_port);
proxyUser = findViewById(R.id.edit_proxyuser);
proxyPass = findViewById(R.id.edit_proxypass);
api_key1 = findViewById(R.id.settings_custom_key1);
api_key2 = findViewById(R.id.settings_custom_key2);
list_size = findViewById(R.id.settings_list_size);
layout_proxy = findViewById(R.id.settings_layout_proxy);
layout_auth_en = findViewById(R.id.settings_layout_auth_enable);
layout_auth = findViewById(R.id.settings_layout_proxy_auth);
layout_key = findViewById(R.id.settings_layout_key);
root = findViewById(R.id.settings_layout);
TypedArray buttons = getResources().obtainTypedArray(R.array.color_button);
@ -125,6 +135,14 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
trend_card.setVisibility(GONE);
user_card.setVisibility(GONE);
}
if (!settings.isProxyEnabled()) {
layout_proxy.setVisibility(GONE);
layout_auth_en.setVisibility(GONE);
layout_auth.setVisibility(GONE);
}
if (!settings.isCustomApiSet()) {
layout_key.setVisibility(GONE);
}
locationAdapter = new LocationAdapter(settings);
locationAdapter.addTop(settings.getTrendLocation());
locationSpinner.setAdapter(locationAdapter);
@ -138,19 +156,21 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
setButtonColors();
toggleImg.setChecked(settings.getImageLoad());
toggleAns.setChecked(settings.getAnswerLoad());
enableAPI.setChecked(settings.isCustomApiSet());
proxyAddr.setText(settings.getProxyHost());
proxyPort.setText(settings.getProxyPort());
proxyUser.setText(settings.getProxyUser());
proxyPass.setText(settings.getProxyPass());
api_key1.setText(settings.getConsumerKey());
api_key2.setText(settings.getConsumerSecret());
list_size.setText(Integer.toString(settings.getListSize()));
listSizeSelector.setProgress(settings.getListSize() / 10 - 1);
enableProxy.setChecked(settings.isProxyEnabled());
enableAuth.setChecked(settings.isProxyAuthSet());
hqImage.setEnabled(settings.getImageLoad());
hqImage.setChecked(settings.getImageQuality());
setProxySetupVisibility(settings.isProxyEnabled(), settings.isProxyAuthSet());
proxyDialog = DialogBuilder.create(this, WRONG_PROXY, this);
connectDialog = DialogBuilder.create(this, WRONG_PROXY, this);
databaseDialog = DialogBuilder.create(this, DEL_DATABASE, this);
logoutDialog = DialogBuilder.create(this, LOGOUT_APP, this);
@ -160,6 +180,7 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
delButton.setOnClickListener(this);
toggleImg.setOnCheckedChangeListener(this);
toggleAns.setOnCheckedChangeListener(this);
enableAPI.setOnCheckedChangeListener(this);
enableProxy.setOnCheckedChangeListener(this);
enableAuth.setOnCheckedChangeListener(this);
hqImage.setOnCheckedChangeListener(this);
@ -181,12 +202,12 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
@Override
public void onBackPressed() {
if (saveProxySettings()) {
if (saveConnectionSettings()) {
TwitterEngine.resetTwitter();
super.onBackPressed();
} else {
if (!proxyDialog.isShowing()) {
proxyDialog.show();
if (!connectDialog.isShowing()) {
connectDialog.show();
}
}
}
@ -356,16 +377,35 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
}
// enable proxy settings
else if (viewId == R.id.settings_enable_proxy) {
setProxySetupVisibility(checked, checked & enableAuth.isChecked());
if (checked) {
layout_proxy.setVisibility(VISIBLE);
layout_auth_en.setVisibility(VISIBLE);
} else {
layout_proxy.setVisibility(GONE);
layout_auth_en.setVisibility(GONE);
enableAuth.setChecked(false);
}
}
//enable proxy authentication
else if (viewId == R.id.settings_enable_auth) {
setProxySetupVisibility(true, checked);
if (checked) {
layout_auth.setVisibility(VISIBLE);
} else {
layout_auth.setVisibility(GONE);
}
}
// enable high quality images
else if (viewId == R.id.settings_image_hq) {
settings.setHighQualityImage(checked);
}
// enable custom API setup
else if (viewId == R.id.settings_set_custom_keys) {
if (checked) {
layout_key.setVisibility(VISIBLE);
} else {
layout_key.setVisibility(GONE);
}
}
}
@ -463,28 +503,12 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
}
}
/**
* set visibility of proxy layouts
*
* @param proxySetup visibility of proxy setup
* @param proxyLogin visibility of proxy login
*/
private void setProxySetupVisibility(boolean proxySetup, boolean proxyLogin) {
int setupVisibility = proxySetup ? VISIBLE : GONE;
int authVisibility = proxyLogin ? VISIBLE : GONE;
proxyAddr.setVisibility(setupVisibility);
proxyPort.setVisibility(setupVisibility);
enableAuth.setVisibility(setupVisibility);
proxyUser.setVisibility(authVisibility);
proxyPass.setVisibility(authVisibility);
}
/**
* check proxy settings and save them if they are correct
*
* @return true if settings are saved successfully
*/
private boolean saveProxySettings() {
private boolean saveConnectionSettings() {
boolean checkPassed = true;
if (enableProxy.isChecked()) {
checkPassed = proxyAddr.length() > 0 && proxyPort.length() > 0;
@ -515,6 +539,17 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O
} else {
settings.clearProxyServer();
}
if (enableAPI.isChecked()) {
if (api_key1.length() > 0 && api_key2.length() > 0) {
String key1 = api_key1.getText().toString();
String key2 = api_key2.getText().toString();
settings.setCustomAPI(key1, key2);
} else {
checkPassed = false;
}
} else {
settings.removeCustomAPI();
}
return checkPassed;
}
}

View File

@ -29,6 +29,7 @@ public class EngineException extends Exception {
NO_CONNECTION,
IMAGE_NOT_LOADED,
ACCOUNT_UPDATE_FAILED,
ERROR_API_ACCESS_DENIED,
ERROR_NOT_DEFINED
}
@ -104,6 +105,10 @@ public class EngineException extends Exception {
errorType = ErrorType.NO_DM_TO_USER;
break;
case 261:
errorType = ErrorType.ERROR_API_ACCESS_DENIED;
break;
case 354:
errorType = ErrorType.DM_TOO_LONG;
break;

View File

@ -73,8 +73,13 @@ public class TwitterEngine {
*/
private void initTwitter() {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(Constants.TWITTER_CONSUMER_KEY);
builder.setOAuthConsumerSecret(Constants.TWITTER_CONSUMER_SECRET);
if (settings.isCustomApiSet()) {
builder.setOAuthConsumerKey(settings.getConsumerKey());
builder.setOAuthConsumerSecret(settings.getConsumerSecret());
} else {
builder.setOAuthConsumerKey(Constants.TWITTER_CONSUMER_KEY);
builder.setOAuthConsumerSecret(Constants.TWITTER_CONSUMER_SECRET);
}
// Twitter4J has its own proxy settings
if (settings.isProxyEnabled()) {
builder.setHttpProxyHost(settings.getProxyHost());

View File

@ -60,9 +60,9 @@ public final class DialogBuilder {
case WRONG_PROXY:
title = R.string.info_error;
message = R.string.error_wrong_proxy_settings;
posButton = R.string.confirm_discard_button;
negButton = R.string.dialog_button_cancel;
message = R.string.error_wrong_connection_settings;
posButton = R.string.dialog_button_cancel;
negButton = R.string.confirm_back;
break;
case DEL_DATABASE:

View File

@ -97,7 +97,7 @@ public final class ErrorHandler {
break;
case ACCESS_TOKEN_DEAD:
Toast.makeText(context, R.string.error_cant_login, Toast.LENGTH_SHORT).show();
Toast.makeText(context, R.string.error_corrupt_api_key, Toast.LENGTH_SHORT).show();
break;
case TWEET_CANT_REPLY:
@ -112,6 +112,10 @@ public final class ErrorHandler {
case ACCOUNT_UPDATE_FAILED:
Toast.makeText(context, R.string.error_acc_update, Toast.LENGTH_LONG).show();
break;
case ERROR_API_ACCESS_DENIED:
Toast.makeText(context, R.string.error_api_access_denied, Toast.LENGTH_LONG).show();
break;
}
} else {
Toast.makeText(context, R.string.error_not_defined, Toast.LENGTH_SHORT).show();

View File

@ -81,6 +81,9 @@ public class GlobalSettings {
private static final String PROXY_PASS = "proxy_pass";
private static final String TREND_LOC = "location";
private static final String TREND_ID = "world_id";
private static final String CUSTOM_CONSUMER_KEY_SET = "custom_api_keys";
private static final String CUSTOM_CONSUMER_KEY_1 = "api_key1";
private static final String CUSTOM_CONSUMER_KEY_2 = "api_key2";
// file name of the preferences
private static final String APP_SETTINGS = "settings";
@ -104,13 +107,15 @@ public class GlobalSettings {
private SharedPreferences settings;
private TrendLocation location;
private String key1, key2;
private String api_key1, api_key2;
private String auth_key1, auth_key2;
private boolean loadImage;
private boolean hqImages;
private boolean loadAnswer;
private boolean loggedIn;
private boolean isProxyEnabled;
private boolean isProxyAuthSet;
private boolean isCustomAPIkeySet;
private int indexFont;
private int background_color;
private int font_color;
@ -604,11 +609,29 @@ public class GlobalSettings {
*/
public String[] getCurrentUserAccessToken() {
String[] out = new String[2];
out[0] = key1;
out[1] = key2;
out[0] = auth_key1;
out[1] = auth_key2;
return out;
}
/**
* get Consumer keys
*
* @return key string
*/
public String getConsumerKey() {
return api_key1;
}
/**
* get consumer key secret
*
* @return key string
*/
public String getConsumerSecret() {
return api_key2;
}
/**
* get current users ID
*
@ -627,8 +650,8 @@ public class GlobalSettings {
*/
public void setConnection(String key1, String key2, long userId) {
loggedIn = true;
this.key1 = key1;
this.key2 = key2;
this.auth_key1 = key1;
this.auth_key2 = key2;
this.userId = userId;
Editor e = settings.edit();
@ -639,6 +662,48 @@ public class GlobalSettings {
e.apply();
}
/**
* sets custom API consumer keys
*
* @param key1 consumer key
* @param key2 consumer key secret
*/
public void setCustomAPI(String key1, String key2) {
isCustomAPIkeySet = true;
this.api_key1 = key1;
this.api_key2 = key2;
Editor e = settings.edit();
e.putBoolean(CUSTOM_CONSUMER_KEY_SET, true);
e.putString(CUSTOM_CONSUMER_KEY_1, key1);
e.putString(CUSTOM_CONSUMER_KEY_2, key2);
e.apply();
}
/**
* remove all API keys
*/
public void removeCustomAPI() {
isCustomAPIkeySet = false;
this.api_key1 = "";
this.api_key2 = "";
Editor e = settings.edit();
e.remove(CUSTOM_CONSUMER_KEY_SET);
e.remove(CUSTOM_CONSUMER_KEY_1);
e.remove(CUSTOM_CONSUMER_KEY_2);
e.apply();
}
/**
* check if custom API consumer keys are set
*
* @return true if custom API keys are set
*/
public boolean isCustomApiSet() {
return isCustomAPIkeySet;
}
/**
* Remove all user content from Shared Preferences
*/
@ -663,8 +728,11 @@ public class GlobalSettings {
loadAnswer = settings.getBoolean(ANSWER_LOAD, DEFAULT_DATA_USAGE);
hqImages = settings.getBoolean(IMAGE_QUALITY, DEFAULT_DATA_USAGE);
loggedIn = settings.getBoolean(LOGGED_IN, false);
key1 = settings.getString(AUTH_KEY1, "");
key2 = settings.getString(AUTH_KEY2, "");
isCustomAPIkeySet = settings.getBoolean(CUSTOM_CONSUMER_KEY_SET, false);
api_key1 = settings.getString(CUSTOM_CONSUMER_KEY_1, "");
api_key2 = settings.getString(CUSTOM_CONSUMER_KEY_2, "");
auth_key1 = settings.getString(AUTH_KEY1, "");
auth_key2 = settings.getString(AUTH_KEY2, "");
userId = settings.getLong(USER_ID, 0);
isProxyEnabled = settings.getBoolean(PROXY_SET, false);
isProxyAuthSet = settings.getBoolean(AUTH_SET, false);

View File

@ -399,14 +399,14 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/proxy_settings"
android:text="@string/settings_connections"
android:textSize="@dimen/settings_textsize" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
android:gravity="center_vertical"
android:orientation="horizontal">
<com.kyleduo.switchbutton.SwitchButton
android:id="@+id/settings_enable_proxy"
@ -424,12 +424,14 @@
</LinearLayout>
<LinearLayout
android:id="@+id/settings_layout_proxy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/edit_proxyadress"
android:id="@+id/edit_proxy_address"
style="@style/TextInput"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
@ -438,11 +440,11 @@
android:inputType="number|numberDecimal"
android:maxLength="15"
android:singleLine="true"
tools:ignore="Autofill"
style="@style/TextInput" />
tools:ignore="Autofill" />
<EditText
android:id="@+id/edit_proxyport"
android:id="@+id/edit_proxy_port"
style="@style/TextInput"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
@ -450,16 +452,16 @@
android:inputType="number"
android:maxLength="5"
android:singleLine="true"
tools:ignore="Autofill"
style="@style/TextInput" />
tools:ignore="Autofill" />
</LinearLayout>
<LinearLayout
android:id="@+id/settings_layout_auth_enable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
android:gravity="center_vertical"
android:orientation="horizontal">
<com.kyleduo.switchbutton.SwitchButton
android:id="@+id/settings_enable_auth"
@ -477,31 +479,83 @@
</LinearLayout>
<LinearLayout
android:id="@+id/settings_layout_proxy_auth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/edit_proxyuser"
style="@style/TextInput"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:hint="@string/edit_proxyuser"
android:inputType="textPersonName"
android:singleLine="true"
tools:ignore="Autofill"
style="@style/TextInput" />
tools:ignore="Autofill" />
<EditText
android:id="@+id/edit_proxypass"
style="@style/TextInput"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:hint="@string/proxy_password"
android:inputType="textPassword"
android:singleLine="true"
tools:ignore="Autofill"
style="@style/TextInput" />
tools:ignore="Autofill" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.kyleduo.switchbutton.SwitchButton
android:id="@+id/settings_set_custom_keys"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/settings_switch_margin" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="@string/settings_setup_custom_keys"
android:textSize="@dimen/settings_textsize_small" />
</LinearLayout>
<LinearLayout
android:id="@+id/settings_layout_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/settings_custom_key1"
style="@style/TextInput"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:hint="@string/settings_key1_hint"
android:inputType="textPassword"
android:singleLine="true"
tools:ignore="Autofill" />
<EditText
android:id="@+id/settings_custom_key2"
style="@style/TextInput"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:hint="@string/settings_key2_hint"
android:inputType="textPassword"
android:singleLine="true"
tools:ignore="Autofill" />
</LinearLayout>

View File

@ -87,7 +87,7 @@
<string name="info_tweet_favored">Tweet favorisiert!</string>
<string name="info_tweet_unfavored">tweet aus den favoriten entfernt!</string>
<string name="proxy_port">Port</string>
<string name="proxy_settings">Proxy Einstellung</string>
<string name="settings_connections">Verbindungseinsellungen</string>
<string name="login_verifier">Login</string>
<string name="settings_button_popup">Popup</string>
<string name="login_pin">PIN eingeben</string>
@ -132,8 +132,7 @@
<string name="error_cant_load_video">Video kann nicht abgespielt werden!</string>
<string name="settings_enable_proxy">Proxy aktivieren</string>
<string name="settings_enable_proxy_auth">Proxy Authentifizierung aktivieren</string>
<string name="error_wrong_proxy_settings">Falsche Proxy Einstellungen</string>
<string name="confirm_discard_button">verwerfen</string>
<string name="error_wrong_connection_settings">Falsche Verbindung angegeben!</string>
<string name="error_open_link">Link konnte nicht geöffnet werden!</string>
<string name="tweet_sensitive_media">Sensible Inhalte</string>
<string name="info_phone_tls_support">TLS 1.2 wird nicht unterstützt. Die App wird möglicherweise nicht funktionieren!</string>
@ -182,8 +181,13 @@
<string name="dialog_button_cancel">Abbrechen</string>
<string name="dialog_button_ok">OK</string>
<string name="error_cant_reply_to_tweet">Tweet ist nicht für Antworten freigegeben!</string>
<string name="error_cant_login">App ist nicht eingeloggt, Bitte neu einloggen!</string>
<string name="error_corrupt_api_key">Fehler, API Schlüssel ist fehlerhaft!</string>
<string name="error_acc_update">Account Informationen konnten nicht aktualisiert werden! Bitte Eingaben überprüfen.</string>
<string name="settings_color_card">Kartenfarbe</string>
<string name="settings_icon_color">Symbolfarbe</string>
<string name="settings_key1_hint">Consumer Key</string>
<string name="settings_key2_hint">Consumer Secret</string>
<string name="settings_setup_custom_keys">Eigene API Schlüssel verwenden</string>
<string name="error_api_access_denied">Fehler, API Zugang wurde abgelehnt!</string>
<string name="confirm_back">Zurück</string>
</resources>

View File

@ -48,11 +48,13 @@
<string name="user_data">User data</string>
<string name="follows_you">follows you</string>
<string name="settings_enable_ans_load">load Tweet replies automatically</string>
<string name="proxy_settings">Proxy settings</string>
<string name="settings_connections">Connection settings</string>
<string name="settings_hint_proxy_ip">enter IP address</string>
<string name="proxy_port">Port</string>
<string name="edit_proxyuser">Username</string>
<string name="proxy_password">Password</string>
<string name="settings_key1_hint">Consumer key</string>
<string name="settings_key2_hint">Consumer secret</string>
<string name="settings_info_link" translatable="false">https://github.com/nuclearfog/Shitter</string>
<string name="confirm_mute">mute user?</string>
<string name="item_list_pb_desc">Profile of the list owner</string>
@ -77,7 +79,8 @@
<string name="item_image_save">save image</string>
<string name="settings_enable_proxy">enable proxy</string>
<string name="settings_enable_proxy_auth">enable proxy authentication</string>
<string name="confirm_discard_button">discard</string>
<string name="settings_setup_custom_keys">setup custom API keys</string>
<string name="confirm_back">back</string>
<string name="tweet_sensitive_media">Potentially sensitive content</string>
<string name="login_info">3 steps to login</string>
<string name="login_first_opt" translatable="false">1.</string>
@ -107,7 +110,7 @@
<string name="info_login_to_twitter">login to Twitter</string>
<string name="info_twitter_login_link">Please click the link below to login</string>
<string name="info_phone_tls_support">Phone does not support TLS 1.2. App will probably not work!</string>
<string name="error_wrong_proxy_settings">Wrong proxy settings</string>
<string name="error_wrong_connection_settings">Wrong connection settings!</string>
<string name="info_cant_add_video">can\'t add video</string>
<string name="info_get_link">get Twitter PIN from browser first. Please press the first button!</string>
<string name="info_gps_attached">GPS position added</string>
@ -166,7 +169,7 @@
<string name="error_list_title_empty">Empty list title!</string>
<string name="error_username_format">Wrong username format!</string>
<string name="error_cant_reply_to_tweet">You can\'t reply to this Tweet!</string>
<string name="error_cant_login">can\'t login to Twitter, please Re-Login!</string>
<string name="error_corrupt_api_key">Error, corrupt API key!</string>
<string name="error_acc_update">Account update failed! Please check your input!</string>
<string name="error_not_defined">Not defined Error!</string>
@ -202,4 +205,5 @@
<string name="dialog_button_ok">OK</string>
<string name="settings_color_card">Card color</string>
<string name="settings_icon_color">Icon color</string>
<string name="error_api_access_denied">Error, API access denied!</string>
</resources>