mirror of
https://github.com/gitnex-org/gitnex.git
synced 2026-03-22 05:59:54 -05:00
Implement instance providers on login and new account
This commit is contained in:
@@ -47,7 +47,7 @@ import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* @author M M Arif
|
||||
* @author mmarif
|
||||
*/
|
||||
public class LoginActivity extends BaseActivity {
|
||||
|
||||
@@ -59,8 +59,8 @@ public class LoginActivity extends BaseActivity {
|
||||
private int defaultPagingNumber = 25;
|
||||
private final String DATABASE_NAME = "gitnex";
|
||||
private boolean hasShownInitialNetworkError = false;
|
||||
private String mode;
|
||||
private int btnText;
|
||||
private String selectedProvider = "gitea";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@@ -70,12 +70,11 @@ public class LoginActivity extends BaseActivity {
|
||||
activityLoginBinding = ActivityLoginBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityLoginBinding.getRoot());
|
||||
|
||||
mode = getIntent().getStringExtra("mode");
|
||||
String mode = getIntent().getStringExtra("mode");
|
||||
if (mode == null) {
|
||||
mode = "login";
|
||||
btnText = R.string.btnLogin;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
btnText = R.string.addNewAccountText;
|
||||
}
|
||||
|
||||
@@ -95,6 +94,10 @@ public class LoginActivity extends BaseActivity {
|
||||
new ArrayAdapter<>(
|
||||
LoginActivity.this, R.layout.list_spinner_items, Protocol.values());
|
||||
|
||||
ArrayAdapter<CharSequence> adapterProviders =
|
||||
ArrayAdapter.createFromResource(
|
||||
this, R.array.provider_options, R.layout.list_spinner_items);
|
||||
|
||||
activityLoginBinding.instanceUrl.setText(getIntent().getStringExtra("instanceUrl"));
|
||||
String scheme = getIntent().getStringExtra("scheme");
|
||||
if (scheme != null && scheme.equals("http")) {
|
||||
@@ -110,7 +113,6 @@ public class LoginActivity extends BaseActivity {
|
||||
activityLoginBinding.httpsSpinner.setOnItemClickListener(
|
||||
(parent, view, position, id) -> {
|
||||
selectedProtocol = String.valueOf(parent.getItemAtPosition(position));
|
||||
|
||||
if (selectedProtocol.equals(String.valueOf(Protocol.HTTP))) {
|
||||
SnackBar.warning(
|
||||
ctx,
|
||||
@@ -119,6 +121,17 @@ public class LoginActivity extends BaseActivity {
|
||||
}
|
||||
});
|
||||
|
||||
activityLoginBinding.providerSpinner.setAdapter(adapterProviders);
|
||||
activityLoginBinding.providerSpinner.setSelection(0);
|
||||
activityLoginBinding.providerSpinner.setText(adapterProviders.getItem(0), false);
|
||||
activityLoginBinding.providerSpinner.setOnItemClickListener(
|
||||
(parent, view, position, id) -> {
|
||||
selectedProvider =
|
||||
position == 0
|
||||
? "gitea"
|
||||
: position == 1 || position == 2 ? "forgejo" : "infer";
|
||||
});
|
||||
|
||||
if (AppUtil.hasNetworkConnection(ctx)) {
|
||||
enableProcessButton();
|
||||
} else {
|
||||
@@ -135,8 +148,7 @@ public class LoginActivity extends BaseActivity {
|
||||
enableProcessButton();
|
||||
} else {
|
||||
disableProcessButton();
|
||||
activityLoginBinding.loginButton.setText(
|
||||
btnText);
|
||||
activityLoginBinding.loginButton.setText(btnText);
|
||||
if (hasShownInitialNetworkError) {
|
||||
SnackBar.error(
|
||||
ctx,
|
||||
@@ -207,6 +219,15 @@ public class LoginActivity extends BaseActivity {
|
||||
|
||||
try {
|
||||
|
||||
if (selectedProvider == null || selectedProvider.isEmpty()) {
|
||||
SnackBar.error(
|
||||
ctx,
|
||||
findViewById(android.R.id.content),
|
||||
getString(R.string.provider_empty_error));
|
||||
enableProcessButton();
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedProtocol == null) {
|
||||
|
||||
SnackBar.error(
|
||||
@@ -217,12 +238,32 @@ public class LoginActivity extends BaseActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Objects.requireNonNull(activityLoginBinding.instanceUrl.getText())
|
||||
.toString()
|
||||
.isEmpty()) {
|
||||
|
||||
SnackBar.error(
|
||||
ctx, findViewById(android.R.id.content), getString(R.string.emptyFieldURL));
|
||||
enableProcessButton();
|
||||
return;
|
||||
}
|
||||
|
||||
String loginToken =
|
||||
Objects.requireNonNull(activityLoginBinding.loginTokenCode.getText())
|
||||
.toString()
|
||||
.replaceAll("[\\uFEFF|#]", "")
|
||||
.trim();
|
||||
|
||||
if (loginToken.isEmpty()) {
|
||||
|
||||
SnackBar.error(
|
||||
ctx,
|
||||
findViewById(android.R.id.content),
|
||||
getString(R.string.loginTokenError));
|
||||
enableProcessButton();
|
||||
return;
|
||||
}
|
||||
|
||||
URI rawInstanceUrl =
|
||||
UrlBuilder.fromString(
|
||||
UrlHelper.fixScheme(
|
||||
@@ -241,24 +282,6 @@ public class LoginActivity extends BaseActivity {
|
||||
.withPath(PathsHelper.join(rawInstanceUrl.getPath(), "/api/v1/"))
|
||||
.toUri();
|
||||
|
||||
if (activityLoginBinding.instanceUrl.getText().toString().isEmpty()) {
|
||||
|
||||
SnackBar.error(
|
||||
ctx, findViewById(android.R.id.content), getString(R.string.emptyFieldURL));
|
||||
enableProcessButton();
|
||||
return;
|
||||
}
|
||||
|
||||
if (loginToken.isEmpty()) {
|
||||
|
||||
SnackBar.error(
|
||||
ctx,
|
||||
findViewById(android.R.id.content),
|
||||
getString(R.string.loginTokenError));
|
||||
enableProcessButton();
|
||||
return;
|
||||
}
|
||||
|
||||
versionCheck(loginToken);
|
||||
serverPageLimitSettings(String.valueOf(instanceUrl), loginToken);
|
||||
|
||||
@@ -333,6 +356,9 @@ public class LoginActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
giteaVersion = new Version(version.getVersion());
|
||||
if (selectedProvider.equals("infer")) {
|
||||
selectedProvider = AppUtil.inferProvider(version.getVersion());
|
||||
}
|
||||
|
||||
if (giteaVersion.less(getString(R.string.versionLow))) {
|
||||
|
||||
@@ -434,11 +460,17 @@ public class LoginActivity extends BaseActivity {
|
||||
loginToken,
|
||||
giteaVersion.toString(),
|
||||
maxResponseItems,
|
||||
defaultPagingNumber);
|
||||
defaultPagingNumber,
|
||||
selectedProvider);
|
||||
account = userAccountsApi.getAccountById((int) accountId);
|
||||
} else {
|
||||
userAccountsApi.updateTokenByAccountName(
|
||||
accountName, loginToken);
|
||||
userAccountsApi.updateProvider(
|
||||
selectedProvider,
|
||||
userAccountsApi
|
||||
.getAccountByName(accountName)
|
||||
.getAccountId());
|
||||
userAccountsApi.login(
|
||||
userAccountsApi
|
||||
.getAccountByName(accountName)
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.Html;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
@@ -12,6 +11,7 @@ import android.widget.TextView;
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.NavOptions;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
@@ -95,11 +95,23 @@ public class MainActivity extends BaseActivity
|
||||
return;
|
||||
}
|
||||
|
||||
if (tinyDB.getInt("currentActiveAccountId", -1) <= 0) {
|
||||
int currentAccountId = tinyDB.getInt("currentActiveAccountId", -1);
|
||||
if (currentAccountId <= 0) {
|
||||
AppUtil.logout(this);
|
||||
return;
|
||||
}
|
||||
|
||||
UserAccountsApi userAccountsApi = BaseApi.getInstance(this, UserAccountsApi.class);
|
||||
if (userAccountsApi != null) {
|
||||
UserAccount currentAccount = userAccountsApi.getAccountById(currentAccountId);
|
||||
if (currentAccount != null
|
||||
&& (currentAccount.getProvider() == null
|
||||
|| currentAccount.getProvider().isEmpty())) {
|
||||
String inferredProvider = AppUtil.inferProvider(currentAccount.getServerVersion());
|
||||
userAccountsApi.updateProvider(inferredProvider, currentAccountId);
|
||||
}
|
||||
}
|
||||
|
||||
setSupportActionBar(binding.toolbar);
|
||||
binding.toolbar.setVisibility(View.GONE);
|
||||
binding.toolbar.invalidate();
|
||||
@@ -322,7 +334,9 @@ public class MainActivity extends BaseActivity
|
||||
ImageView userAvatar = binding.userAvatar;
|
||||
|
||||
if (name != null && !name.isEmpty()) {
|
||||
userFullname.setText(Html.fromHtml(name));
|
||||
userFullname.setText(
|
||||
HtmlCompat.fromHtml(
|
||||
name, HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
} else {
|
||||
userFullname.setText(username);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.mian.gitnex.database.models.UserAccount;
|
||||
import org.mian.gitnex.helpers.UrlHelper;
|
||||
|
||||
/**
|
||||
* @author M M Arif
|
||||
* @author mmarif
|
||||
*/
|
||||
public class UserAccountsNavAdapter
|
||||
extends RecyclerView.Adapter<UserAccountsNavAdapter.UserAccountsViewHolder> {
|
||||
@@ -81,12 +81,12 @@ public class UserAccountsNavAdapter
|
||||
}
|
||||
|
||||
newAccount.setOnClickListener(
|
||||
item -> {
|
||||
Intent intent = new Intent(context, LoginActivity.class);
|
||||
intent.putExtra("mode", "new_account");
|
||||
context.startActivity(intent);
|
||||
dialog.dismiss();
|
||||
});
|
||||
item -> {
|
||||
Intent intent = new Intent(context, LoginActivity.class);
|
||||
intent.putExtra("mode", "new_account");
|
||||
context.startActivity(intent);
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
UserAccountsAdapter arrayAdapter = new UserAccountsAdapter(context, dialog);
|
||||
listView.setLayoutManager(new LinearLayoutManager(context));
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.mian.gitnex.database.dao.UserAccountsDao;
|
||||
import org.mian.gitnex.database.models.UserAccount;
|
||||
|
||||
/**
|
||||
* @author M M Arif
|
||||
* @author mmarif
|
||||
*/
|
||||
public class UserAccountsApi extends BaseApi {
|
||||
|
||||
@@ -25,7 +25,8 @@ public class UserAccountsApi extends BaseApi {
|
||||
String token,
|
||||
String serverVersion,
|
||||
int maxResponseItems,
|
||||
int defaultPagingNumber) {
|
||||
int defaultPagingNumber,
|
||||
String provider) {
|
||||
|
||||
UserAccount userAccount = new UserAccount();
|
||||
userAccount.setAccountName(accountName);
|
||||
@@ -36,6 +37,7 @@ public class UserAccountsApi extends BaseApi {
|
||||
userAccount.setLoggedIn(true);
|
||||
userAccount.setMaxResponseItems(maxResponseItems);
|
||||
userAccount.setDefaultPagingNumber(defaultPagingNumber);
|
||||
userAccount.setProvider(provider);
|
||||
|
||||
return userAccountsDao.createAccount(userAccount);
|
||||
}
|
||||
@@ -117,4 +119,8 @@ public class UserAccountsApi extends BaseApi {
|
||||
public void login(int accountId) {
|
||||
executorService.execute(() -> userAccountsDao.login(accountId));
|
||||
}
|
||||
|
||||
public void updateProvider(final String provider, final int accountId) {
|
||||
executorService.execute(() -> userAccountsDao.updateProvider(provider, accountId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
import org.mian.gitnex.database.models.UserAccount;
|
||||
|
||||
/**
|
||||
* @author M M Arif
|
||||
* @author mmarif
|
||||
*/
|
||||
@Dao
|
||||
public interface UserAccountsDao {
|
||||
@@ -81,4 +81,7 @@ public interface UserAccountsDao {
|
||||
|
||||
@Query("DELETE FROM UserAccounts WHERE accountId = :accountId")
|
||||
void deleteAccount(int accountId);
|
||||
|
||||
@Query("UPDATE UserAccounts SET provider = :provider WHERE accountId = :accountId")
|
||||
void updateProvider(String provider, int accountId);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.database.models.UserAccount;
|
||||
|
||||
/**
|
||||
* @author M M Arif
|
||||
* @author mmarif
|
||||
*/
|
||||
@Database(
|
||||
entities = {Repository.class, UserAccount.class, Notes.class, AppSettings.class},
|
||||
version = 10,
|
||||
version = 11,
|
||||
exportSchema = false)
|
||||
public abstract class GitnexDatabase extends RoomDatabase {
|
||||
|
||||
@@ -30,7 +30,6 @@ public abstract class GitnexDatabase extends RoomDatabase {
|
||||
new Migration(1, 2) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||
// database.execSQL("DROP TABLE Drafts");
|
||||
database.execSQL("ALTER TABLE 'Drafts' ADD COLUMN 'commentId' TEXT");
|
||||
}
|
||||
};
|
||||
@@ -110,6 +109,16 @@ public abstract class GitnexDatabase extends RoomDatabase {
|
||||
database.execSQL("DROP table Drafts");
|
||||
}
|
||||
};
|
||||
|
||||
private static final Migration MIGRATION_10_11 =
|
||||
new Migration(10, 11) {
|
||||
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||
database.execSQL("ALTER TABLE 'userAccounts' ADD COLUMN 'provider' TEXT");
|
||||
}
|
||||
};
|
||||
|
||||
private static volatile GitnexDatabase gitnexDatabase;
|
||||
|
||||
public static GitnexDatabase getDatabaseInstance(Context context) {
|
||||
@@ -131,7 +140,8 @@ public abstract class GitnexDatabase extends RoomDatabase {
|
||||
MIGRATION_6_7,
|
||||
MIGRATION_7_8,
|
||||
MIGRATION_8_9,
|
||||
MIGRATION_9_10)
|
||||
MIGRATION_9_10,
|
||||
MIGRATION_10_11)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import androidx.room.PrimaryKey;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author M M Arif
|
||||
* @author mmarif
|
||||
*/
|
||||
@Entity(tableName = "userAccounts")
|
||||
public class UserAccount implements Serializable {
|
||||
@@ -24,6 +24,7 @@ public class UserAccount implements Serializable {
|
||||
private int defaultPagingNumber;
|
||||
private int maxAttachmentsSize;
|
||||
private int maxNumberOfAttachments;
|
||||
private String provider;
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
@@ -112,4 +113,12 @@ public class UserAccount implements Serializable {
|
||||
public void setMaxNumberOfAttachments(int maxNumberOfAttachments) {
|
||||
this.maxNumberOfAttachments = maxNumberOfAttachments;
|
||||
}
|
||||
|
||||
public String getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public void setProvider(String provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,4 +721,13 @@ public class AppUtil {
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
public static String inferProvider(String version) {
|
||||
if (Version.valid(version)) {
|
||||
Version v = new Version(version);
|
||||
int majorVersion = v.getValues().isEmpty() ? 0 : v.getValues().get(0);
|
||||
return majorVersion == 1 ? "gitea" : "forgejo";
|
||||
}
|
||||
return "gitea";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,4 +236,8 @@ public class Version {
|
||||
|
||||
return raw;
|
||||
}
|
||||
|
||||
public List<Integer> getValues() {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,4 +83,8 @@ public class AccountContext implements Serializable {
|
||||
assert account.getAccountName() != null;
|
||||
return new File(context.getCacheDir() + "responses", account.getAccountName());
|
||||
}
|
||||
|
||||
public String getProvider() {
|
||||
return getAccount().getProvider();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,29 @@
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/dimen28dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/providerSpinnerLayout"
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen8dp"
|
||||
android:layout_marginBottom="@dimen/dimen8dp"
|
||||
android:hint="@string/select_provider"
|
||||
android:textColorHint="?attr/hintColor"
|
||||
app:endIconTint="?attr/iconsColor"
|
||||
app:hintTextColor="?attr/hintColor">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/providerSpinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
android:labelFor="@+id/providerSpinner"
|
||||
android:textColor="?attr/inputTextColor"
|
||||
android:textSize="@dimen/dimen16sp" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/httpsSpinnerLayout"
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
|
||||
@@ -23,6 +23,13 @@
|
||||
<item>zh-TW</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="provider_options">
|
||||
<item>Gitea</item>
|
||||
<item>Forgejo</item>
|
||||
<item>Codeberg (Forgejo-based)</item>
|
||||
<item>I am not sure</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="fonts">
|
||||
<item>Roboto</item>
|
||||
<item>Manrope</item>
|
||||
|
||||
@@ -1002,4 +1002,6 @@
|
||||
<string name="switch_account">Switch account</string>
|
||||
<string name="clear_cache_button_text">Clear Cache (%1$s)</string>
|
||||
<string name="repository_not_exist">Repository does not exist</string>
|
||||
<string name="select_provider">Select instance provider</string>
|
||||
<string name="provider_empty_error">Please select an instance provider</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user