Multiple accounts support (#624)

Title update

Color clean up

switch to another account and update the token at login

Add new account

Add fab button for new account and activity

update libs

Remove account from Manage accounts list

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/624
Reviewed-by: 6543 <6543@noreply.codeberg.org>
This commit is contained in:
M M Arif 2020-08-04 22:50:04 +02:00 committed by 6543
parent ea36a3f6d6
commit 30921ea330
40 changed files with 623 additions and 61 deletions

View File

@ -36,14 +36,14 @@ configurations {
}
dependencies {
def lifecycle_version = "2.3.0-alpha05"
def lifecycle_version = "2.3.0-alpha06"
def markwon_version = "4.4.0"
def work_version = "2.4.0"
def acra = "5.5.0"
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:1.3.0-alpha01"
implementation "com.google.android.material:material:1.3.0-alpha01"
implementation "com.google.android.material:material:1.3.0-alpha02"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
@ -81,7 +81,7 @@ dependencies {
implementation "com.hendraanggrian.appcompat:socialview-commons:0.2"
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
implementation "commons-io:commons-io:20030203.000550"
implementation "org.apache.commons:commons-lang3:3.10"
implementation 'org.apache.commons:commons-lang3:3.11'
implementation "com.github.chrisbanes:PhotoView:2.3.0"
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
implementation "ch.acra:acra-mail:$acra"

View File

@ -85,6 +85,7 @@
<activity android:name=".activities.AddNewTeamMemberActivity" />
<activity android:name=".activities.SettingsDraftsActivity" />
<activity android:name=".activities.RepoForksActivity" />
<activity android:name=".activities.AddNewAccountActivity" />
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
<meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>

View File

@ -0,0 +1,267 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.databinding.ActivityAddNewAccountBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.PathsHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.UrlHelper;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.UserInfo;
import java.net.URI;
import io.mikael.urlbuilder.UrlBuilder;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class AddNewAccountActivity extends BaseActivity {
final Context ctx = this;
private Context appCtx;
private TinyDB tinyDB;
private View.OnClickListener onClickListener;
private ActivityAddNewAccountBinding viewBinding;
private enum Protocol {HTTPS, HTTP}
@Override
protected int getLayoutResourceId(){
return R.layout.activity_add_new_account;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
tinyDB = new TinyDB(appCtx);
viewBinding = ActivityAddNewAccountBinding.inflate(getLayoutInflater());
View view = viewBinding.getRoot();
setContentView(view);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
initCloseListener();
viewBinding.close.setOnClickListener(onClickListener);
ArrayAdapter<AddNewAccountActivity.Protocol> adapterProtocols = new ArrayAdapter<>(AddNewAccountActivity.this, R.layout.spinner_item, AddNewAccountActivity.Protocol.values());
adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item);
viewBinding.protocolSpinner.setAdapter(adapterProtocols);
viewBinding.addNewAccount.setOnClickListener(login -> {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
}
else {
processLogin();
}
});
}
private void processLogin() {
try {
String instanceUrlET = viewBinding.instanceUrl.getText().toString();
String loginToken = viewBinding.loginToken.getText().toString();
Protocol protocol = (Protocol) viewBinding.protocolSpinner.getSelectedItem();
if(instanceUrlET.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldURL));
return;
}
if(loginToken.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.loginTokenError));
return;
}
URI rawInstanceUrl = UrlBuilder.fromString(UrlHelper.fixScheme(instanceUrlET, "http")).toUri();
URI instanceUrlWithProtocol = UrlBuilder.fromUri(rawInstanceUrl).withPath(PathsHelper.join(rawInstanceUrl.getPath()))
.withScheme(protocol.name().toLowerCase()).toUri();
URI instanceUrl = UrlBuilder.fromUri(instanceUrlWithProtocol).withPath(PathsHelper.join(instanceUrlWithProtocol.getPath(), "/api/v1/"))
.toUri();
versionCheck(instanceUrl.toString(), loginToken);
}
catch(Exception e) {
Log.e("onFailure-login", e.toString());
Toasty.error(ctx, getResources().getString(R.string.malformedUrl));
}
}
private void versionCheck(final String instanceUrl, final String loginToken) {
Call<GiteaVersion> callVersion;
callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken(loginToken);
callVersion.enqueue(new Callback<GiteaVersion>() {
@Override
public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) {
if(responseVersion.code() == 200) {
GiteaVersion version = responseVersion.body();
Version giteaVersion;
assert version != null;
try {
giteaVersion = new Version(version.getVersion());
}
catch(Exception e) {
Toasty.error(ctx, getResources().getString(R.string.versionUnknown));
return;
}
if(giteaVersion.less(getString(R.string.versionLow))) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader))
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setIcon(R.drawable.ic_warning)
.setCancelable(true);
alertDialogBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
dialog.dismiss();
//enableProcessButton();
});
alertDialogBuilder.setPositiveButton(getString(R.string.textContinue), (dialog, which) -> {
dialog.dismiss();
login(instanceUrl, loginToken);
});
alertDialogBuilder.create().show();
}
else if(giteaVersion.lessOrEqual(getString(R.string.versionHigh))) {
login(instanceUrl, loginToken);
}
else {
Toasty.info(ctx, getResources().getString(R.string.versionUnsupportedNew));
login(instanceUrl, loginToken);
}
}
else if(responseVersion.code() == 403) {
login(instanceUrl, loginToken);
}
}
private void login(String instanceUrl, String loginToken) {
setupNewAccountWithToken(instanceUrl, loginToken);
}
@Override
public void onFailure(@NonNull Call<GiteaVersion> callVersion, @NonNull Throwable t) {
Log.e("onFailure-versionCheck", t.toString());
Toasty.error(ctx, getResources().getString(R.string.errorOnLogin));
}
});
}
private void setupNewAccountWithToken(String instanceUrl, final String loginToken) {
Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo("token " + loginToken);
call.enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(@NonNull Call<UserInfo> call, @NonNull retrofit2.Response<UserInfo> response) {
UserInfo userDetails = response.body();
switch(response.code()) {
case 200:
assert userDetails != null;
// insert new account to db if does not exist
String accountName = userDetails.getUsername() + "@" + instanceUrl;
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
int checkAccount = userAccountsApi.getCount(accountName);
if(checkAccount == 0) {
userAccountsApi.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, "");
Toasty.success(ctx, getResources().getString(R.string.accountAddedMessage));
finish();
}
else {
Toasty.warning(ctx, getResources().getString(R.string.accountAlreadyExistsError));
}
break;
case 401:
Toasty.error(ctx,getResources().getString(R.string.unauthorizedApiError));
break;
default:
Toasty.error(ctx,getResources().getString(R.string.genericApiStatusError) + response.code());
}
}
@Override
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
Toasty.error(ctx,getResources().getString(R.string.genericError));
}
});
}
private void initCloseListener() {
onClickListener = view -> finish();
}
}

View File

@ -95,7 +95,7 @@ public class CreateFileActivity extends BaseActivity {
closeActivity.setOnClickListener(onClickListener);
newFileBranchesSpinner = findViewById(R.id.newFileBranchesSpinner);
newFileBranchesSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
newFileBranchesSpinner.getBackground().setColorFilter(getResources().getColor(R.color.colorWhite), PorterDuff.Mode.SRC_ATOP);
getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
newFileBranchesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()

View File

@ -127,7 +127,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
newIssueDueDate.setOnClickListener(this);
newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner);
newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.colorWhite), PorterDuff.Mode.SRC_ATOP);
getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit);
getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid);

View File

@ -88,7 +88,7 @@ public class CreateReleaseActivity extends BaseActivity {
closeActivity.setOnClickListener(onClickListener);
releaseBranch = findViewById(R.id.releaseBranch);
releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.colorWhite), PorterDuff.Mode.SRC_ATOP);
getBranches(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override

View File

@ -87,7 +87,7 @@ public class CreateRepoActivity extends BaseActivity {
closeActivity.setOnClickListener(onClickListener);
spinner = findViewById(R.id.ownerSpinner);
spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
spinner.getBackground().setColorFilter(getResources().getColor(R.color.colorWhite), PorterDuff.Mode.SRC_ATOP);
getOrganizations(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), userLogin);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override

View File

@ -109,7 +109,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
loadCollaboratorsList();
editIssueMilestoneSpinner = findViewById(R.id.editIssueMilestoneSpinner);
editIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
editIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.colorWhite), PorterDuff.Mode.SRC_ATOP);
editIssueDescription.setMentionAdapter(defaultMentionAdapter);

View File

@ -112,7 +112,7 @@ public class LoginActivity extends BaseActivity {
});
info_button.setOnClickListener(
view -> new Tooltip.Builder(view).setText(R.string.urlInfoTooltip).setTextColor(getResources().getColor(R.color.white))
view -> new Tooltip.Builder(view).setText(R.string.urlInfoTooltip).setTextColor(getResources().getColor(R.color.colorWhite))
.setBackgroundColor(getResources().getColor(R.color.tooltipBackground)).setCancelable(true).setDismissOnClick(true).setPadding(30)
.setCornerRadius(R.dimen.tooltipCornor).setGravity(Gravity.BOTTOM).show());
@ -137,7 +137,6 @@ public class LoginActivity extends BaseActivity {
if(isAvailable) {
enableProcessButton();
SnackBar.success(ctx, layoutView, getResources().getString(R.string.netConnectionIsBack));
}
else {
@ -392,6 +391,9 @@ public class LoginActivity extends BaseActivity {
if(checkAccount == 0) {
userAccountsApi.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, "");
}
else {
userAccountsApi.updateTokenByAccountName(accountName, loginToken);
}
enableProcessButton();
startActivity(new Intent(LoginActivity.this, MainActivity.class));
@ -574,6 +576,9 @@ public class LoginActivity extends BaseActivity {
userAccountsApi
.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), newToken.getSha1(), "");
}
else {
userAccountsApi.updateTokenByAccountName(accountName, newToken.getSha1());
}
startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();

View File

@ -248,7 +248,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
switch(codeBlockList[i]) {
case "White - Black":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorWhite));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
case "Grey - Black":
@ -256,12 +256,12 @@ public class SettingsAppearanceActivity extends BaseActivity {
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
case "White - Grey":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorWhite));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorAccent));
break;
case "Dark - White":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorPrimary));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorWhite));
break;
default:
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen));

View File

@ -86,7 +86,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
holder.userRole.setVisibility(View.VISIBLE);
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.textColor(mCtx.getResources().getColor(R.color.white))
.textColor(mCtx.getResources().getColor(R.color.colorWhite))
.fontSize(44)
.width(180)
.height(60)

View File

@ -58,7 +58,7 @@ public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdap
if(currentItem.getPrimary()) {
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.textColor(mCtx.getResources().getColor(R.color.white))
.textColor(mCtx.getResources().getColor(R.color.colorWhite))
.fontSize(36)
.width(220)
.height(60)

View File

@ -1,16 +1,20 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
@ -28,13 +32,15 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
private Context mCtx;
private TinyDB tinyDB;
static class UserAccountsViewHolder extends RecyclerView.ViewHolder {
class UserAccountsViewHolder extends RecyclerView.ViewHolder {
private TextView accountUrl;
private TextView userId;
private ImageView activeAccount;
private ImageView deleteAccount;
private ImageView repoAvatar;
private TextView accountId;
private TextView accountName;
private UserAccountsViewHolder(View itemView) {
@ -45,14 +51,48 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
activeAccount = itemView.findViewById(R.id.activeAccount);
deleteAccount = itemView.findViewById(R.id.deleteAccount);
repoAvatar = itemView.findViewById(R.id.repoAvatar);
accountId = itemView.findViewById(R.id.accountId);
accountName = itemView.findViewById(R.id.accountName);
deleteAccount.setOnClickListener(itemDelete -> {
// use later to delete an account
new AlertDialog.Builder(mCtx)
.setIcon(mCtx.getDrawable(R.drawable.ic_delete))
.setTitle(mCtx.getResources().getString(R.string.removeAccountPopupTitle))
.setMessage(mCtx.getResources().getString(R.string.removeAccountPopupMessage))
.setPositiveButton(mCtx.getResources().getString(R.string.removeButton), (dialog, which) -> {
updateLayoutByPosition(getAdapterPosition());
UserAccountsApi userAccountsApi = new UserAccountsApi(mCtx);
userAccountsApi.deleteAccount(Integer.parseInt(accountId.getText().toString()));
}).setNeutralButton(mCtx.getResources().getString(R.string.cancelButton), null)
.show();
});
itemView.setOnClickListener(itemEdit -> {
// use later to switch account
String accountNameSwitch = accountName.getText().toString();
UserAccountsApi userAccountsApi = new UserAccountsApi(mCtx);
UserAccount userAccount = userAccountsApi.getAccountData(accountNameSwitch);
Log.e("userAccount", userAccount.getInstanceUrl());
if(tinyDB.getInt("currentActiveAccountId") != userAccount.getAccountId()) {
String url = UrlBuilder.fromString(userAccount.getInstanceUrl())
.withPath("/")
.toString();
tinyDB.putString("loginUid", userAccount.getUserName());
tinyDB.putString("userLogin", userAccount.getUserName());
tinyDB.putString(userAccount.getUserName() + "-token", userAccount.getToken());
tinyDB.putString("instanceUrl", userAccount.getInstanceUrl());
tinyDB.putInt("currentActiveAccountId", userAccount.getAccountId());
Toasty.success(mCtx, mCtx.getResources().getString(R.string.switchAccountSuccess, userAccount.getUserName(), url));
((Activity) mCtx).recreate();
}
});
@ -66,7 +106,7 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
this.userAccountsList = userAccountsListMain;
}
private void deleteAccount(int position) {
private void updateLayoutByPosition(int position) {
userAccountsList.remove(position);
notifyItemRemoved(position);
@ -94,6 +134,8 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
.withPath("/")
.toString();
holder.accountId.setText(String.valueOf(currentItem.getAccountId()));
holder.accountName.setText(currentItem.getAccountName());
holder.userId.setText(String.format("@%s", currentItem.getUserName()));
holder.accountUrl.setText(url);
@ -103,7 +145,7 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
holder.activeAccount.setVisibility(View.VISIBLE);
}
else {
holder.deleteAccount.setVisibility(View.GONE);
holder.deleteAccount.setVisibility(View.VISIBLE);
}
}

View File

@ -48,11 +48,16 @@ public class UserAccountsApi {
new Thread(() -> userAccountsDao.updateServerVersion(serverVersion, accountId)).start();
}
public static void updateToken(final int accountId, final String token) {
public void updateToken(final int accountId, final String token) {
new Thread(() -> userAccountsDao.updateAccountToken(accountId, token)).start();
}
public void updateTokenByAccountName(final String accountName, final String token) {
new Thread(() -> userAccountsDao.updateAccountTokenByAccountName(accountName, token)).start();
}
public UserAccount getAccountData(String accountName) {
try {
@ -90,7 +95,7 @@ public class UserAccountsApi {
return userAccountsDao.fetchAllAccounts();
}
public static void deleteAccount(final int accountId) {
public void deleteAccount(final int accountId) {
new Thread(() -> userAccountsDao.deleteAccount(accountId)).start();
}

View File

@ -38,6 +38,9 @@ public interface UserAccountsDao {
@Query("UPDATE UserAccounts SET token = :token WHERE accountId = :accountId")
void updateAccountToken(int accountId, String token);
@Query("UPDATE UserAccounts SET token = :token WHERE accountName = :accountName")
void updateAccountTokenByAccountName(String accountName, String token);
@Query("UPDATE UserAccounts SET instanceUrl = :instanceUrl, token = :token WHERE accountId = :accountId")
void updateHostInfo(String instanceUrl, String token, int accountId);

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
@ -11,7 +12,9 @@ import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.AddNewAccountActivity;
import org.mian.gitnex.adapters.UserAccountsAdapter;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
@ -29,6 +32,7 @@ public class UserAccountsFragment extends Fragment {
private RecyclerView mRecyclerView;
private UserAccountsApi userAccountsApi;
private List<UserAccount> userAccountsList;
private ExtendedFloatingActionButton addNewAccount;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -61,6 +65,13 @@ public class UserAccountsFragment extends Fragment {
}, 250));
addNewAccount = v.findViewById(R.id.addNewAccount);
addNewAccount.setOnClickListener(view -> {
Intent intent = new Intent(view.getContext(), AddNewAccountActivity.class);
startActivity(intent);
});
fetchDataAsync();
return v;

View File

@ -27,7 +27,7 @@ public class ClickListener implements View.OnClickListener {
{
LayoutInflater inflater1 = LayoutInflater.from(mCtx);
View layout = inflater1.inflate(R.layout.custom_toast,
View layout = inflater1.inflate(R.layout.custom_toast_success,
(ViewGroup) v.findViewById(R.id.custom_toast_container));
TextView text = layout.findViewById(R.id.toastText);

View File

@ -30,7 +30,7 @@ public class SnackBar {
View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text);
textView.setTextColor(context.getResources().getColor(R.color.white));
textView.setTextColor(context.getResources().getColor(R.color.colorWhite));
snackBar.show();
@ -60,4 +60,4 @@ public class SnackBar {
}
}
}

View File

@ -16,7 +16,7 @@ public class Toasty {
public static void info(Context context, String message) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(context.getResources().getLayout(R.layout.custom_toast), null);
View view = inflater.inflate(context.getResources().getLayout(R.layout.custom_toast_info), null);
TextView text = view.findViewById(R.id.toastText);
text.setText(message);
@ -43,4 +43,34 @@ public class Toasty {
}
public static void warning(Context context, String message) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(context.getResources().getLayout(R.layout.custom_toast_warning), null);
TextView text = view.findViewById(R.id.toastText);
text.setText(message);
Toast toast = new Toast(context);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(view);
toast.show();
}
public static void success(Context context, String message) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(context.getResources().getLayout(R.layout.custom_toast_success), null);
TextView text = view.findViewById(R.id.toastText);
text.setText(message);
Toast toast = new Toast(context);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(view);
toast.show();
}
}

View File

@ -7,6 +7,6 @@
android:width="36dp"
android:height="36dp" />
<solid
android:color="@color/white" />
android:color="@color/colorWhite" />
</shape>

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/layoutNewAccount"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/primaryBackgroundColor"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBackgroundColor"
tools:ignore="UnusedAttribute">
<ImageView
android:id="@+id/close"
android:layout_width="@dimen/close_button_size"
android:layout_height="@dimen/close_button_size"
android:layout_marginRight="15dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:contentDescription="@string/close"
android:src="@drawable/ic_arrow_back" />
<TextView
android:id="@+id/toolbarTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/addNewAccount"
android:textColor="?attr/primaryTextColor"
android:ellipsize="none"
android:scrollbars="horizontal"
android:singleLine="true"
android:layout_marginEnd="20dp"
android:textSize="18sp" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp"
android:layout_marginTop="50dp"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="@drawable/shape_dropdown">
<Spinner
android:id="@+id/protocolSpinner"
android:layout_width="120dp"
android:layout_height="44dp"
android:padding="10dp"
android:spinnerMode="dropdown" />
</RelativeLayout>
<EditText
android:id="@+id/instanceUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/shape_inputs"
android:drawableStart="@drawable/ic_link"
android:drawablePadding="10dp"
android:hint="@string/instanceUrl"
android:inputType="textUri"
android:padding="10dp"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="14sp"
android:autofillHints="@string/instanceUrl" />
<EditText
android:id="@+id/loginToken"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/shape_inputs"
android:drawableStart="@drawable/ic_lock"
android:drawablePadding="10dp"
android:hint="@string/copyToken"
android:inputType="text"
android:padding="10dp"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="14sp"
android:visibility="visible"
android:autofillHints="@string/copyToken" />
<Button
android:id="@+id/addNewAccount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="15dp"
android:background="@drawable/shape_buttons"
android:text="@string/addNewAccountText"
android:textColor="@color/btnTextColor"
android:textSize="16sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -228,7 +228,7 @@
<ImageView
android:id="@+id/addNewComment"
android:src="@drawable/ic_reply"
android:tint="@color/white"
android:tint="@color/colorWhite"
android:layout_width="54dp"
android:layout_height="54dp"
android:layout_margin="15dp"

View File

@ -107,4 +107,4 @@
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -25,6 +25,6 @@
android:layout_toEndOf="@+id/counterBadgeIssueText"
android:background="@drawable/shape_badge_background"
android:text="@string/infoTabRepoZero"
android:textColor="@color/white" />
android:textColor="@color/colorWhite" />
</RelativeLayout>

View File

@ -24,7 +24,7 @@
android:background="@drawable/shape_badge_background"
android:gravity="center"
android:text="@string/infoTabRepoZero"
android:textColor="@color/white"
android:textColor="@color/colorWhite"
android:textSize="12sp" />
</RelativeLayout>

View File

@ -24,7 +24,7 @@
android:background="@drawable/shape_badge_background"
android:gravity="center"
android:text="@string/infoTabRepoZero"
android:textColor="@color/white"
android:textColor="@color/colorWhite"
android:textSize="12sp" />
</RelativeLayout>

View File

@ -6,12 +6,12 @@
android:layout_height="fill_parent"
android:padding="15dp"
android:background="@drawable/shape_round_corners"
android:backgroundTint="@color/toastBackground">
android:backgroundTint="@color/colorRed">
<TextView android:id="@+id/toastText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/darkRed"
android:textColor="@color/colorWhite"
android:layout_gravity="center"
android:gravity="center" />

View File

@ -11,7 +11,7 @@
<TextView android:id="@+id/toastText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textColor="@color/colorWhite"
android:layout_gravity="center"
android:gravity="center" />

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_toast_container"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="15dp"
android:background="@drawable/shape_round_corners"
android:backgroundTint="@color/successColor">
<TextView android:id="@+id/toastText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:layout_gravity="center"
android:gravity="center" />
</LinearLayout>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_toast_container"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="15dp"
android:background="@drawable/shape_round_corners"
android:backgroundTint="@color/warningColor">
<TextView android:id="@+id/toastText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimary"
android:layout_gravity="center"
android:gravity="center" />
</LinearLayout>

View File

@ -47,7 +47,7 @@
android:id="@+id/userFullName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textColor="@color/colorWhite"
android:textIsSelectable="true"
android:textSize="18sp" />
@ -56,7 +56,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:textColor="@color/white"
android:textColor="@color/colorWhite"
android:textIsSelectable="true"
android:textSize="14sp" />
@ -86,7 +86,7 @@
android:id="@+id/userLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textColor="@color/colorWhite"
android:textIsSelectable="true"
android:textSize="14sp" />

View File

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/userAccountsFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
@ -16,9 +17,22 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:padding="4dp"
android:scrollbars="vertical" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</RelativeLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/addNewAccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:text="@string/addNewAccount"
android:contentDescription="@string/addNewAccount"
android:textColor="@color/colorWhite"
android:backgroundTint="@color/darkGreen"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
app:iconTint="@color/colorWhite"
app:icon="@drawable/ic_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -10,6 +10,18 @@
android:layout_margin="15dp"
android:background="?attr/primaryBackgroundColor">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/accountId"
android:visibility="gone" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/accountName"
android:visibility="gone" />
<RelativeLayout
android:id="@+id/layoutFrame"
android:layout_width="match_parent"

View File

@ -56,7 +56,7 @@
android:paddingTop="10dp"
android:textSize="18sp"
android:textIsSelectable="true"
android:textColor="@color/white"
android:textColor="@color/colorWhite"
android:paddingStart="20dp"
android:paddingEnd="5dp" />
@ -66,7 +66,7 @@
android:layout_height="wrap_content"
android:textSize="14sp"
android:textIsSelectable="true"
android:textColor="@color/white"
android:textColor="@color/colorWhite"
android:gravity="start"
android:layout_gravity="center_vertical"
android:paddingStart="20dp"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppThemeLight" parent="Theme.AppCompat.Light.NoActionBar">
<style name="AppThemeLight" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:statusBarColor">@color/lightThemeBackground</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:typeface">monospace</item>

View File

@ -11,4 +11,4 @@
<attr name="selectedTextColor" format="reference" />
<attr name="alertDialogTheme" format="reference" />
<attr name="dividerColor" format="reference" />
</resources>
</resources>

View File

@ -7,7 +7,6 @@
<color name="hintColor">#7f7e7b</color>
<color name="colorWhite">#ffffff</color>
<color name="black">#000009</color>
<color name="white">#ffffff</color>
<color name="tooltipBackground">#1e88ce</color>
<color name="blurColor">#41818181</color>
<color name="btnBackground">#009486</color>
@ -28,6 +27,8 @@
<color name="diffSelectedColor">#434343</color>
<color name="dividerColorDark">#1d1d1d</color>
<color name="lightYellow">#efd34a</color>
<color name="warningColor">#dbb109</color>
<color name="successColor">#1e9c37</color>
<color name="lightThemeDiffRemovedColor">#FCEDED</color>
<color name="lightThemeDiffAddedColor">#EAF8ED</color>

View File

@ -54,7 +54,7 @@
<string name="pageTitleNewFile">New File</string>
<string name="pageTitleExplore">Explore</string>
<string name="pageTitleAdministration">Gitea Administration</string>
<string name="pageTitleUserAccounts">Manage Accounts (beta)</string>
<string name="pageTitleUserAccounts">Manage Accounts</string>
<!-- page titles -->
<string name="repoName">Demo repo</string>
@ -535,7 +535,7 @@
<string name="loginViaPassword">Username / Password</string>
<string name="loginMethodText">Choose your preferred login method to access your account. Token is more secure!</string>
<string name="unauthorizedApiError">Instance has returned an error - Unauthorized. Check your credentials and try again</string>
<string name="loginTokenError">Please enter the correct token</string>
<string name="loginTokenError">Token is required</string>
<string name="prDeletedFrok">Deleted Fork</string>
<string name="noDataPullRequests">No pull requests found</string>
@ -626,6 +626,13 @@
<string name="archivedRepository">Archived</string>
<string name="accountDeletedMessage">Account deleted successfully</string>
<string name="removeAccountPopupTitle">Remove Account</string>
<string name="removeAccountPopupMessage">Are you sure you want to remove this account from the app?\nThis will remove all the data related to this account on the app only.</string>
<string name="addNewAccount">New Account</string>
<string name="addNewAccountText">Add New Account</string>
<string name="accountAlreadyExistsError">Account already exists in the app</string>
<string name="accountAddedMessage">Account added successfully</string>
<string name="switchAccountSuccess">Switched to account : %1$s@%2$s</string>
<!-- Notifications -->
<string name="pageTitleNotifications">Notifications</string>

View File

@ -1,7 +1,7 @@
<resources>
<style name="DrawerIcon" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="color">@color/white</item>
<item name="color">@color/colorWhite</item>
<item name="android:textSize">16sp</item>
</style>
@ -19,8 +19,8 @@
</style>
<style name="radioButtonsInDarkTheme" parent="Theme.AppCompat.Dialog.Alert">
<item name="colorControlNormal">@color/white</item>
<item name="colorControlActivated">@color/white</item>
<item name="colorControlNormal">@color/colorWhite</item>
<item name="colorControlActivated">@color/colorWhite</item>
</style>
</resources>

View File

@ -2,7 +2,7 @@
<resources>
<!-- Dark theme - default -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:statusBarColor">@color/colorPrimary</item>
<item name="android:typeface">monospace</item>
<item name="colorAccent">@color/colorAccent</item>
@ -31,7 +31,7 @@
<!-- Dark theme - default -->
<!-- Light theme -->
<style name="AppThemeLight" parent="Theme.AppCompat.Light.NoActionBar">
<style name="AppThemeLight" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:statusBarColor">@color/lightThemeBackground</item>
<item name="android:typeface">monospace</item>
<item name="colorAccent">@color/colorAccent</item>
@ -89,15 +89,15 @@
<style name="AppThemeConfirmDialog" parent="Theme.AppCompat.Dialog.Alert">
<item name="android:background">@color/colorPrimary</item>
<item name="android:textColorPrimary">@color/white</item>
<item name="android:textColor">@color/white</item>
<item name="colorControlNormal">@color/white</item>
<item name="android:textColorPrimary">@color/colorWhite</item>
<item name="android:textColor">@color/colorWhite</item>
<item name="colorControlNormal">@color/colorWhite</item>
<item name="colorControlActivated">@color/darkGreen</item>
<item name="android:windowBackground">@drawable/shape_round_corners</item>
</style>
<style name="AppThemeLightConfirmDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:background">@color/white</item>
<item name="android:background">@color/colorWhite</item>
<item name="android:textColorPrimary">@color/lightThemeTextColor</item>
<item name="android:textColor">@color/lightThemeTextColor</item>
<item name="colorControlNormal">@color/lightThemeTextColor</item>
@ -107,13 +107,13 @@
<style name="AppThemePopupMenuStyle" parent="Widget.AppCompat.PopupMenu">
<item name="android:popupBackground">@color/colorPrimary</item>
<item name="android:textColor">@color/white</item>
<item name="android:textColor">@color/colorWhite</item>
<item name="android:layout_marginStart">3dp</item>
<item name="android:layout_marginEnd">3dp</item>
</style>
<style name="AppThemeLightPopupMenuStyle" parent="Widget.AppCompat.Light.PopupMenu">
<item name="android:popupBackground">@color/white</item>
<item name="android:popupBackground">@color/colorWhite</item>
<item name="android:itemBackground">@color/lightThemeBackground</item>
<item name="android:textColor">@color/lightThemeTextColor</item>
<item name="android:layout_marginStart">3dp</item>