mirror of
https://github.com/gitnex-org/gitnex.git
synced 2026-03-22 13:05:25 -05:00
Improve changelog UI, add where to get access token
This commit is contained in:
@@ -4,8 +4,12 @@ import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import io.mikael.urlbuilder.UrlBuilder;
|
||||
import java.net.URI;
|
||||
@@ -61,6 +65,8 @@ public class AddNewAccountActivity extends BaseActivity {
|
||||
spinnerSelectedValue = Protocol.HTTPS.toString();
|
||||
}
|
||||
|
||||
viewBinding.tokenHelper.setOnClickListener(token -> showTokenHelpDialog());
|
||||
|
||||
ArrayAdapter<Protocol> adapterProtocols =
|
||||
new ArrayAdapter<>(ctx, R.layout.list_spinner_items, Protocol.values());
|
||||
|
||||
@@ -84,6 +90,37 @@ public class AddNewAccountActivity extends BaseActivity {
|
||||
});
|
||||
}
|
||||
|
||||
private void showTokenHelpDialog() {
|
||||
|
||||
MaterialAlertDialogBuilder dialogBuilder =
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setMessage(
|
||||
HtmlCompat.fromHtml(
|
||||
getString(R.string.where_to_get_token_message),
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY))
|
||||
.setPositiveButton(R.string.close, null)
|
||||
.setCancelable(true);
|
||||
|
||||
AlertDialog dialog = dialogBuilder.create();
|
||||
dialog.show();
|
||||
|
||||
TextView messageView = dialog.findViewById(android.R.id.message);
|
||||
if (messageView != null) {
|
||||
messageView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
int paddingTop =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
16,
|
||||
getResources().getDisplayMetrics());
|
||||
messageView.setPadding(
|
||||
messageView.getPaddingLeft(),
|
||||
paddingTop,
|
||||
messageView.getPaddingRight(),
|
||||
messageView.getPaddingBottom());
|
||||
}
|
||||
}
|
||||
|
||||
private void processLogin() {
|
||||
|
||||
try {
|
||||
|
||||
@@ -10,10 +10,14 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import io.mikael.urlbuilder.UrlBuilder;
|
||||
import java.io.File;
|
||||
@@ -93,6 +97,8 @@ public class LoginActivity extends BaseActivity {
|
||||
disableProcessButton();
|
||||
}
|
||||
|
||||
activityLoginBinding.tokenHelper.setOnClickListener(token -> showTokenHelpDialog());
|
||||
|
||||
networkStatusObserver.registerNetworkStatusListener(
|
||||
hasNetworkConnection ->
|
||||
runOnUiThread(
|
||||
@@ -138,6 +144,37 @@ public class LoginActivity extends BaseActivity {
|
||||
});
|
||||
}
|
||||
|
||||
private void showTokenHelpDialog() {
|
||||
|
||||
MaterialAlertDialogBuilder dialogBuilder =
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setMessage(
|
||||
HtmlCompat.fromHtml(
|
||||
getString(R.string.where_to_get_token_message),
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY))
|
||||
.setPositiveButton(R.string.close, null)
|
||||
.setCancelable(true);
|
||||
|
||||
AlertDialog dialog = dialogBuilder.create();
|
||||
dialog.show();
|
||||
|
||||
TextView messageView = dialog.findViewById(android.R.id.message);
|
||||
if (messageView != null) {
|
||||
messageView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
int paddingTop =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
16,
|
||||
getResources().getDisplayMetrics());
|
||||
messageView.setPadding(
|
||||
messageView.getPaddingLeft(),
|
||||
paddingTop,
|
||||
messageView.getPaddingRight(),
|
||||
messageView.getPaddingBottom());
|
||||
}
|
||||
}
|
||||
|
||||
private void login() {
|
||||
|
||||
try {
|
||||
|
||||
@@ -526,9 +526,7 @@ public class MainActivity extends BaseActivity
|
||||
if (versionCode > tinyDB.getInt("versionCode")) {
|
||||
|
||||
tinyDB.putInt("versionCode", versionCode);
|
||||
|
||||
ChangeLog changelogDialog = new ChangeLog(this);
|
||||
changelogDialog.showDialog();
|
||||
new ChangeLog(this).showDialog();
|
||||
}
|
||||
|
||||
OnBackPressedCallback onBackPressedCallback =
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package org.mian.gitnex.helpers;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.mian.gitnex.R;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
@@ -18,82 +25,185 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||
*/
|
||||
public class ChangeLog {
|
||||
|
||||
private static final String TAG = "ChangeLog";
|
||||
private static final String CHANGELOG_XML_NODE = "changelog";
|
||||
|
||||
private final Activity changelogActivity;
|
||||
|
||||
public ChangeLog(Activity context) {
|
||||
changelogActivity = context;
|
||||
this.changelogActivity = context;
|
||||
}
|
||||
|
||||
private String ParseReleaseTag(XmlResourceParser aXml)
|
||||
throws XmlPullParserException, IOException {
|
||||
private static class Release {
|
||||
String version;
|
||||
int versioncode;
|
||||
List<Type> types;
|
||||
|
||||
StringBuilder strBuilder =
|
||||
new StringBuilder(aXml.getAttributeValue(null, "version") + "<br>");
|
||||
int eventType = aXml.getEventType();
|
||||
|
||||
while ((eventType != XmlPullParser.END_TAG) || (aXml.getName().equals("change"))) {
|
||||
|
||||
if ((eventType == XmlPullParser.START_TAG) && (aXml.getName().equals("change"))) {
|
||||
eventType = aXml.next();
|
||||
strBuilder.append(aXml.getText()).append("<br>");
|
||||
}
|
||||
eventType = aXml.next();
|
||||
Release(String version, int versioncode) {
|
||||
this.version = version;
|
||||
this.versioncode = versioncode;
|
||||
this.types = new ArrayList<>();
|
||||
}
|
||||
strBuilder.append("<br>");
|
||||
|
||||
return strBuilder.toString();
|
||||
}
|
||||
|
||||
private String getChangelog(int resId, Resources res) {
|
||||
private static class Type {
|
||||
String name;
|
||||
List<String> changes;
|
||||
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
try (XmlResourceParser xml = res.getXml(resId)) {
|
||||
Type(String name) {
|
||||
this.name = name;
|
||||
this.changes = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
private Release parseLatestRelease(@NonNull XmlResourceParser xml) {
|
||||
|
||||
List<Release> releases = new ArrayList<>();
|
||||
Release currentRelease = null;
|
||||
Type currentType = null;
|
||||
|
||||
try {
|
||||
int eventType = xml.getEventType();
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
|
||||
if ((eventType == XmlPullParser.START_TAG) && (xml.getName().equals("release"))) {
|
||||
strBuilder.append(ParseReleaseTag(xml));
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
|
||||
String tagName = xml.getName();
|
||||
if (tagName.equals("release")) {
|
||||
String version = xml.getAttributeValue(null, "version");
|
||||
int versioncode = xml.getAttributeIntValue(null, "versioncode", -1);
|
||||
currentRelease = new Release(version, versioncode);
|
||||
releases.add(currentRelease);
|
||||
} else if (tagName.equals("type") && currentRelease != null) {
|
||||
String typeName = xml.getAttributeValue(null, "name");
|
||||
currentType = new Type(typeName);
|
||||
currentRelease.types.add(currentType);
|
||||
} else if (tagName.equals("change") && currentType != null) {
|
||||
eventType = xml.next();
|
||||
if (eventType == XmlPullParser.TEXT) {
|
||||
String changeText = xml.getText().trim();
|
||||
if (!changeText.isEmpty()) {
|
||||
currentType.changes.add(changeText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
eventType = xml.next();
|
||||
}
|
||||
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
Log.e(TAG, Objects.requireNonNull(e.getMessage()));
|
||||
return new Release("Error", -1);
|
||||
}
|
||||
|
||||
return strBuilder.toString();
|
||||
Release latest = null;
|
||||
for (Release r : releases) {
|
||||
if (latest == null
|
||||
|| (r.versioncode > latest.versioncode && r.versioncode != -1)
|
||||
|| (r.versioncode == -1 && latest.versioncode == -1)) {
|
||||
latest = r;
|
||||
}
|
||||
}
|
||||
return latest != null ? latest : new Release("No releases found", -1);
|
||||
}
|
||||
|
||||
private LinearLayout buildChangelogView(Release release) {
|
||||
|
||||
LinearLayout layout = new LinearLayout(changelogActivity);
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
int paddingHorizontal =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
24,
|
||||
changelogActivity.getResources().getDisplayMetrics());
|
||||
int paddingVertical =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
16,
|
||||
changelogActivity.getResources().getDisplayMetrics());
|
||||
layout.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
|
||||
|
||||
TextView versionView = new TextView(changelogActivity);
|
||||
versionView.setText(
|
||||
HtmlCompat.fromHtml(
|
||||
"<b>" + release.version + "</b>", HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
versionView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
|
||||
LinearLayout.LayoutParams versionParams =
|
||||
new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
versionParams.setMargins(0, 0, 0, 16);
|
||||
versionView.setLayoutParams(versionParams);
|
||||
layout.addView(versionView);
|
||||
|
||||
for (Type type : release.types) {
|
||||
|
||||
TextView typeView = new TextView(changelogActivity);
|
||||
typeView.setText(
|
||||
HtmlCompat.fromHtml(
|
||||
"<b>" + EmojiParser.parseToUnicode(type.name) + "</b>",
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
typeView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
|
||||
LinearLayout.LayoutParams typeParams =
|
||||
new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
typeParams.setMargins(0, 48, 0, 16);
|
||||
typeView.setLayoutParams(typeParams);
|
||||
layout.addView(typeView);
|
||||
|
||||
for (String change : type.changes) {
|
||||
if (!change.isEmpty()) {
|
||||
TextView changeView = new TextView(changelogActivity);
|
||||
changeView.setText(
|
||||
HtmlCompat.fromHtml("• " + change, HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
changeView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
LinearLayout.LayoutParams changeParams =
|
||||
new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
changeParams.setMargins(32, 0, 0, 8);
|
||||
changeView.setLayoutParams(changeParams);
|
||||
layout.addView(changeView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
public void showDialog() {
|
||||
|
||||
String packageName = changelogActivity.getPackageName();
|
||||
Resources res = null;
|
||||
Resources res = changelogActivity.getResources();
|
||||
Release latestRelease;
|
||||
|
||||
try {
|
||||
res = changelogActivity.getPackageManager().getResourcesForApplication(packageName);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, Objects.requireNonNull(e.getMessage()));
|
||||
try (XmlResourceParser xml = res.getXml(R.xml.changelog)) {
|
||||
latestRelease = parseLatestRelease(xml);
|
||||
} catch (Exception e) {
|
||||
latestRelease = new Release("Error loading changelog", -1);
|
||||
}
|
||||
|
||||
assert res != null;
|
||||
int resId = res.getIdentifier(CHANGELOG_XML_NODE, "xml", packageName);
|
||||
ScrollView scrollView = new ScrollView(changelogActivity);
|
||||
scrollView.addView(buildChangelogView(latestRelease));
|
||||
|
||||
String changelogMessage = getChangelog(resId, res);
|
||||
|
||||
MaterialAlertDialogBuilder materialAlertDialogBuilder =
|
||||
MaterialAlertDialogBuilder dialogBuilder =
|
||||
new MaterialAlertDialogBuilder(changelogActivity)
|
||||
.setTitle(R.string.changelogTitle)
|
||||
.setMessage(
|
||||
HtmlCompat.fromHtml(
|
||||
"<small>" + changelogMessage + "</small>",
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY))
|
||||
.setView(scrollView)
|
||||
.setCancelable(false)
|
||||
.setNeutralButton(R.string.close, null);
|
||||
|
||||
materialAlertDialogBuilder.create().show();
|
||||
AlertDialog dialog = dialogBuilder.create();
|
||||
dialog.show();
|
||||
TextView titleView = dialog.findViewById(com.google.android.material.R.id.alertTitle);
|
||||
if (titleView != null) {
|
||||
int extraTopPadding =
|
||||
(int)
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
16,
|
||||
changelogActivity.getResources().getDisplayMetrics());
|
||||
titleView.setPadding(
|
||||
titleView.getPaddingLeft(),
|
||||
titleView.getPaddingTop() + extraTopPadding,
|
||||
titleView.getPaddingRight(),
|
||||
titleView.getPaddingBottom());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,16 @@
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/token_helper"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:textSize="@dimen/dimen14sp"
|
||||
android:autoLink="web"
|
||||
android:text="@string/where_to_get_token_text" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
@@ -148,6 +148,17 @@
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/token_helper"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen16dp"
|
||||
android:layout_marginBottom="@dimen/dimen16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:textSize="@dimen/dimen14sp"
|
||||
android:autoLink="web"
|
||||
android:text="@string/where_to_get_token_text" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/login_button"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
<string name="supportText" translatable="false">Support</string>
|
||||
<string name="supportTextPatreon" translatable="false">Patreon</string>
|
||||
<string name="feedbackText" translatable="false">Feedback</string>
|
||||
<string name="where_to_get_token_text" translatable="false"><u>Where can I get an access token?</u></string>
|
||||
<string name="where_to_get_token_message" translatable="false"><![CDATA[<br>• Log in to your account on your instance (Codeberg, etc.).<br>• Click on your user profile picture, then go to Settings.<br>• Under Applications, create a token with a name of your choice.<br>• Choose All (public, private, and limited).<br>• Under Select permissions, select Read and write for each dropdown.<br><br> Once created, copy and paste or type the token here along with the instance URL.]]></string>
|
||||
|
||||
<!-- menu items -->
|
||||
<string name="navMyRepos">My Repositories</string>
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<changelog>
|
||||
|
||||
<release version="9.0.0-dev" versioncode="895">
|
||||
<change>Under development</change>
|
||||
<type name="Dev">
|
||||
<change>Under development</change>
|
||||
</type>
|
||||
</release>
|
||||
|
||||
</changelog>
|
||||
|
||||
Reference in New Issue
Block a user