added option to change API app name, bug fix

This commit is contained in:
nuclearfog 2023-07-21 19:19:30 +02:00
parent 75be99fe87
commit ab309484e0
No known key found for this signature in database
GPG Key ID: 03488A185C476379
7 changed files with 152 additions and 103 deletions

View File

@ -110,7 +110,7 @@ public class Mastodon implements Connection {
/**
* oauth no redirect (oob)
*/
private static final String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
private static final String REDIRECT_URI = "urn%3aietf%3awg%3aoauth%3a2.0%3aoob";
// Mastodon endpoints see https://docs.joinmastodon.org/methods/
private static final String ENDPOINT_REGISTER_APP = "/api/v1/apps";
@ -178,8 +178,11 @@ public class Mastodon implements Connection {
List<String> params = new ArrayList<>();
params.add("scopes=" + AUTH_SCOPES);
params.add("redirect_uris=" + REDIRECT_URI);
params.add("client_name=" + app_name);
params.add("website=" + app_website);
params.add("website=" + StringUtils.encode(app_website));
if (!connection.getAppName().isEmpty())
params.add("client_name=" + StringUtils.encode(connection.getAppName()));
else
params.add("client_name=" + StringUtils.encode(app_name));
String hostname = connection.useHost() ? connection.getHostname() : DEFAULT_HOST;
try {
Response response = post(hostname, ENDPOINT_REGISTER_APP, null, params);

View File

@ -17,11 +17,12 @@ public class ConnectionUpdate implements Serializable {
private static final long serialVersionUID = 2238181470544567706L;
private Configuration apiConfig;
private Configuration apiConfig = Configuration.MASTODON;
private String hostname = "";
private String consumerKey = "";
private String consumerSecret = "";
private String tempOauth = "";
private String appName = "";
/**
* get host url used by the API
@ -32,6 +33,57 @@ public class ConnectionUpdate implements Serializable {
return hostname;
}
/**
* override host url
*
* @param hostname new host url
*/
public void setHostname(@NonNull String hostname) {
if (!hostname.trim().isEmpty()) {
if (!hostname.startsWith("http"))
this.hostname = "https://" + hostname;
else
this.hostname = hostname;
} else {
this.hostname = "";
}
}
/**
* get app name used by the API access
*
* @return short app name or empty if not set
*/
public String getAppName() {
return appName;
}
/**
* set app name used by the API
*
* @param appname short app name
*/
public void setAppName(@NonNull String appname) {
this.appName = appname;
}
/**
* get configured API type
*
* @return API type
*/
public Configuration getApiType() {
return apiConfig;
}
/**
* override default API type
*/
public void setApiType(Configuration apiConfig) {
this.apiConfig = apiConfig;
}
/**
* get temporary oauth token
*
@ -59,35 +111,6 @@ public class ConnectionUpdate implements Serializable {
return consumerSecret;
}
/**
* get configured API type
*
* @return API type
*/
public Configuration getApiType() {
return apiConfig;
}
/**
* override default API type
*/
public void setApiType(Configuration apiConfig) {
this.apiConfig = apiConfig;
}
/**
* override host url
*
* @param hostname new host url
*/
public void setHost(String hostname) {
if (hostname != null && !hostname.trim().isEmpty() && !hostname.startsWith("http")) {
this.hostname = "https://" + hostname;
} else {
this.hostname = "";
}
}
/**
* @return true if token key pair is set
*/
@ -108,13 +131,9 @@ public class ConnectionUpdate implements Serializable {
* @param consumerKey custom oauth consumer key
* @param consumerSecret custom oauth consumer secret
*/
public void setOauthTokens(String consumerKey, String consumerSecret) {
if (consumerKey != null) {
this.consumerKey = consumerKey;
}
if (consumerSecret != null) {
this.consumerSecret = consumerSecret;
}
public void setOauthTokens(@NonNull String consumerKey, @NonNull String consumerSecret) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
}
/**

View File

@ -28,9 +28,9 @@ import org.nuclearfog.twidda.config.Configuration;
*/
public class ConnectionDialog extends Dialog implements OnCheckedChangeListener, OnClickListener {
private SwitchButton enableApi, enableV2, enableHost;
private TextView apiLabel, v2Label, hostLabel;
private EditText host, api1, api2;
private SwitchButton enableApi, enableV2;
private TextView apiLabel, v2Label, appNameLabel, hostLabel;
private EditText host, api1, api2, appName;
private ConnectionUpdate connection;
@ -51,18 +51,18 @@ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener,
Button discard = findViewById(R.id.dialog_connection_discard);
enableApi = findViewById(R.id.dialog_connection_custom_api);
enableV2 = findViewById(R.id.dialog_connection_use_v2);
enableHost = findViewById(R.id.dialog_connection_custom_host);
apiLabel = findViewById(R.id.dialog_connection_custom_api_label);
v2Label = findViewById(R.id.dialog_connection_use_v2_label);
hostLabel = findViewById(R.id.dialog_connection_custom_host_label);
appNameLabel = findViewById(R.id.dialog_connection_app_name_label);
hostLabel = findViewById(R.id.dialog_connection_hostname_label);
host = findViewById(R.id.dialog_connection_hostname);
api1 = findViewById(R.id.dialog_connection_api1);
api2 = findViewById(R.id.dialog_connection_api2);
appName = findViewById(R.id.dialog_connection_app_name);
AppStyles.setTheme(root);
enableApi.setOnCheckedChangeListener(this);
enableHost.setOnCheckedChangeListener(this);
confirm.setOnClickListener(this);
discard.setOnClickListener(this);
}
@ -78,35 +78,45 @@ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener,
// fall through
case TWITTER1:
// setup Twitter configuration views
if (connection.useTokens()) {
api1.setText(connection.getOauthConsumerToken());
api2.setText(connection.getOauthTokenSecret());
enableApi.setCheckedImmediately(true);
api1.setVisibility(View.VISIBLE);
api2.setVisibility(View.VISIBLE);
api1.setText(connection.getOauthConsumerToken());
api2.setText(connection.getOauthTokenSecret());
enableV2.setVisibility(View.VISIBLE);
v2Label.setVisibility(View.VISIBLE);
} else {
enableApi.setCheckedImmediately(false);
api1.setVisibility(View.INVISIBLE);
api2.setVisibility(View.INVISIBLE);
enableV2.setVisibility(View.INVISIBLE);
v2Label.setVisibility(View.INVISIBLE);
}
// enable Twitter configuration views
enableApi.setVisibility(View.VISIBLE);
apiLabel.setVisibility(View.VISIBLE);
hostLabel.setVisibility(View.GONE);
enableHost.setVisibility(View.GONE);
// disable mastodon configuration views
host.setVisibility(View.GONE);
appNameLabel.setVisibility(View.GONE);
appName.setVisibility(View.GONE);
hostLabel.setVisibility(View.GONE);
break;
case MASTODON:
// setup Mastodon configuration views
if (connection.useHost()) {
enableHost.setCheckedImmediately(true);
host.setVisibility(View.VISIBLE);
host.setText(connection.getHostname());
} else {
enableHost.setCheckedImmediately(false);
host.setVisibility(View.INVISIBLE);
host.setText("");
}
// enable Mastodon configuration views
host.setVisibility(View.VISIBLE);
appNameLabel.setVisibility(View.VISIBLE);
appName.setVisibility(View.VISIBLE);
hostLabel.setVisibility(View.VISIBLE);
enableHost.setVisibility(View.VISIBLE);
// disable Twitter configuration views
enableApi.setVisibility(View.GONE);
apiLabel.setVisibility(View.GONE);
enableV2.setVisibility(View.GONE);
@ -132,47 +142,52 @@ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener,
@Override
public void onClick(View v) {
if (v.getId() == R.id.dialog_connection_confirm) {
String api1Text = api1.getText().toString();
String api2Text = api2.getText().toString();
String hostText = host.getText().toString();
switch (connection.getApiType()) {
case TWITTER1:
case TWITTER2:
if (enableApi.isChecked() && !api1Text.trim().isEmpty() && !api2Text.trim().isEmpty()) {
if (enableV2.isChecked()) {
connection.setApiType(Configuration.TWITTER2);
String api1Text = api1.getText().toString();
String api2Text = api2.getText().toString();
if (enableApi.isChecked()) {
if (!api1Text.trim().isEmpty() && !api2Text.trim().isEmpty()) {
connection.setOauthTokens(api1Text, api2Text);
} else {
connection.setApiType(Configuration.TWITTER1);
if (api1Text.trim().isEmpty()) {
api1.setError(getContext().getString(R.string.info_missing_key));
}
if (api2Text.trim().isEmpty()) {
api2.setError(getContext().getString(R.string.info_missing_key));
}
return;
}
connection.setOauthTokens(api1Text, api2Text);
dismiss();
} else if (!enableApi.isChecked()) {
} else {
connection.setOauthTokens("", "");
}
if (enableV2.isChecked()) {
connection.setApiType(Configuration.TWITTER2);
} else {
if (Tokens.DISABLE_API_V2) {
connection.setApiType(Configuration.TWITTER1);
} else {
connection.setApiType(Configuration.TWITTER2);
}
dismiss();
} else {
if (api1Text.trim().isEmpty()) {
api1.setError(getContext().getString(R.string.info_missing_key));
}
if (api2Text.trim().isEmpty()) {
api2.setError(getContext().getString(R.string.info_missing_key));
}
}
dismiss();
break;
case MASTODON:
if (enableHost.isChecked() && Patterns.WEB_URL.matcher(hostText).matches()) {
connection.setHost(hostText);
dismiss();
} else if (!enableHost.isChecked()) {
connection.setHost("");
String appNameStr = appName.getText().toString();
String hostText = host.getText().toString();
if (hostText.trim().isEmpty() || Patterns.WEB_URL.matcher(hostText).matches()) {
connection.setHostname(hostText);
dismiss();
} else {
host.setError(getContext().getString(R.string.info_missing_host));
}
if (!appNameStr.trim().isEmpty()) {
connection.setAppName(appNameStr);
} else {
connection.setAppName("");
}
break;
}
} else if (v.getId() == R.id.dialog_connection_discard) {
@ -196,12 +211,6 @@ public class ConnectionDialog extends Dialog implements OnCheckedChangeListener,
api1.setVisibility(View.INVISIBLE);
api2.setVisibility(View.INVISIBLE);
}
} else if (buttonView.getId() == R.id.dialog_connection_custom_host) {
if (isChecked) {
host.setVisibility(View.VISIBLE);
} else {
host.setVisibility(View.INVISIBLE);
}
}
}

View File

@ -91,27 +91,16 @@
app:layout_constraintTop_toBottomOf="@id/dialog_connection_custom_api"
app:layout_constraintEnd_toEndOf="parent" />
<com.kyleduo.switchbutton.SwitchButton
android:id="@+id/dialog_connection_custom_host"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dialog_connection_layout_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_api1"
app:layout_constraintEnd_toStartOf="@id/dialog_connection_custom_host_label" />
<TextView
android:id="@+id/dialog_connection_custom_host_label"
android:id="@+id/dialog_connection_hostname_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/dialog_connection_custom_host"
android:lines="1"
android:layout_weight="1"
android:layout_margin="@dimen/dialog_connection_layout_margin"
android:textSize="@dimen/dialog_connection_textsize_label"
app:layout_constraintStart_toEndOf="@id/dialog_connection_custom_host"
app:layout_constraintTop_toTopOf="@id/dialog_connection_custom_host"
app:layout_constraintBottom_toBottomOf="@id/dialog_connection_custom_host"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_api1"
app:layout_constraintEnd_toEndOf="parent" />
<EditText
@ -123,12 +112,39 @@
android:lines="1"
android:layout_weight="1"
android:layout_margin="@dimen/dialog_connection_layout_margin"
android:visibility="invisible"
android:inputType="textUri"
android:importantForAutofill="no"
android:textSize="@dimen/dialog_connection_textsize_input"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_custom_host"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_hostname_label"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/dialog_connection_app_name_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/login_app_name_label"
android:lines="1"
android:layout_margin="@dimen/dialog_connection_layout_margin"
android:textSize="@dimen/dialog_connection_textsize_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_hostname"
app:layout_constraintEnd_toEndOf="parent" />
<EditText
android:id="@+id/dialog_connection_app_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:hint="@string/app_name_api"
android:lines="1"
android:layout_weight="1"
android:layout_margin="@dimen/dialog_connection_layout_margin"
android:inputType="text"
android:importantForAutofill="no"
android:textSize="@dimen/dialog_connection_textsize_input"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_app_name_label"
app:layout_constraintEnd_toEndOf="parent" />
<Button
@ -140,7 +156,7 @@
android:padding="@dimen/dialog_connection_button_padding"
android:layout_margin="@dimen/dialog_connection_layout_margin"
android:textSize="@dimen/dialog_connection_textsize_button"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_hostname"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_app_name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/dialog_connection_confirm"
style="@style/FeedbackButton" />
@ -154,7 +170,7 @@
android:padding="@dimen/dialog_connection_button_padding"
android:layout_margin="@dimen/dialog_connection_layout_margin"
android:textSize="@dimen/dialog_connection_textsize_button"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_hostname"
app:layout_constraintTop_toBottomOf="@id/dialog_connection_app_name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
style="@style/FeedbackButton" />

View File

@ -210,6 +210,7 @@
<string name="menu_add_account">Account hinzufügen</string>
<string name="settings_rt_icon_color">Repost</string>
<string name="settings_follow_req_color">Anfrage Icon</string>
<string name="login_app_name_label">Benutzerdefinierter App-Name</string>
<string name="settings_follow_color">Follow Icon</string>
<string name="settings_enable_toolbar_overlap">Kompakte Profilansicht</string>
<string name="confirm_remove_filter">Filter löschen?</string>

View File

@ -241,7 +241,7 @@
<dimen name="userlist_title_textsize">20sp</dimen>
<!--dimens of dialog_connection.xml-->
<dimen name="dialog_connection_button_height">24sp</dimen>
<dimen name="dialog_connection_button_height">26sp</dimen>
<dimen name="dialog_connection_button_padding">5dp</dimen>
<dimen name="dialog_connection_layout_margin">5dp</dimen>
<dimen name="dialog_connection_root_padding">8dp</dimen>

View File

@ -316,6 +316,7 @@
<string name="button_share">share link</string>
<string name="settings_rt_icon_color">Reposts</string>
<string name="settings_follow_req_color">Follow request</string>
<string name="login_app_name_label">custom app name</string>
<string name="settings_follow_color">Following icon</string>
<string name="account_page">Accounts</string>
<string name="toolbar_title_filter">Status filter</string>