From e2aff890d7671330a7bdeea03956f701f8bdbe4c Mon Sep 17 00:00:00 2001 From: M M Arif Date: Tue, 7 Jul 2020 16:20:43 +0200 Subject: [PATCH] Accounts overview screen (#577) optimize url string Overview of accounts in the app Co-authored-by: M M Arif Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/577 Reviewed-by: opyale --- .../mian/gitnex/activities/MainActivity.java | 12 ++ .../gitnex/adapters/UserAccountsAdapter.java | 110 ++++++++++++++++++ .../fragments/UserAccountsFragment.java | 95 +++++++++++++++ app/src/main/res/drawable/circle.xml | 3 +- app/src/main/res/drawable/circle_red.xml | 3 +- app/src/main/res/drawable/circle_white.xml | 12 ++ .../main/res/drawable/ic_account_circle.xml | 5 + .../res/layout/fragment_user_accounts.xml | 24 ++++ .../main/res/layout/list_user_accounts.xml | 60 ++++++++++ app/src/main/res/layout/nav_header.xml | 72 ++++++++---- app/src/main/res/values/strings.xml | 3 + 11 files changed, 374 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java create mode 100644 app/src/main/java/org/mian/gitnex/fragments/UserAccountsFragment.java create mode 100644 app/src/main/res/drawable/circle_white.xml create mode 100644 app/src/main/res/drawable/ic_account_circle.xml create mode 100644 app/src/main/res/layout/fragment_user_accounts.xml create mode 100644 app/src/main/res/layout/list_user_accounts.xml diff --git a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java index 5f78c196..aed4a5d8 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java @@ -40,6 +40,7 @@ import org.mian.gitnex.fragments.ProfileFragment; import org.mian.gitnex.fragments.RepositoriesFragment; import org.mian.gitnex.fragments.SettingsFragment; import org.mian.gitnex.fragments.StarredRepositoriesFragment; +import org.mian.gitnex.fragments.UserAccountsFragment; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.ChangeLog; @@ -182,6 +183,9 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig else if(fragmentById instanceof AdministrationFragment) { toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); } + else if(fragmentById instanceof UserAccountsFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleUserAccounts)); + } drawer = findViewById(R.id.drawer_layout); NavigationView navigationView = findViewById(R.id.nav_view); @@ -281,6 +285,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig }); + ImageView userAccounts = hView.findViewById(R.id.userAccounts); + userAccounts.setOnClickListener(v -> { + + toolbarTitle.setText(getResources().getString(R.string.pageTitleUserAccounts)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new UserAccountsFragment()).commit(); + drawer.closeDrawers(); + }); + toggle.syncState(); if(launchFragment != null) { diff --git a/app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java new file mode 100644 index 00000000..ee2d4024 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java @@ -0,0 +1,110 @@ +package org.mian.gitnex.adapters; + +import android.annotation.SuppressLint; +import android.content.Context; +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.recyclerview.widget.RecyclerView; +import org.mian.gitnex.R; +import org.mian.gitnex.database.models.UserAccount; +import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.util.TinyDB; +import java.util.List; +import io.mikael.urlbuilder.UrlBuilder; + +/** + * Author M M Arif + */ + +public class UserAccountsAdapter extends RecyclerView.Adapter { + + private List userAccountsList; + private Context mCtx; + private TinyDB tinyDB; + + static class UserAccountsViewHolder extends RecyclerView.ViewHolder { + + private TextView accountUrl; + private TextView userId; + private ImageView activeAccount; + private ImageView deleteAccount; + + private UserAccountsViewHolder(View itemView) { + + super(itemView); + + accountUrl = itemView.findViewById(R.id.accountUrl); + userId = itemView.findViewById(R.id.userId); + activeAccount = itemView.findViewById(R.id.activeAccount); + deleteAccount = itemView.findViewById(R.id.deleteAccount); + + deleteAccount.setOnClickListener(itemDelete -> { + // use later to delete an account + + }); + + itemView.setOnClickListener(itemEdit -> { + // use later to switch account + + }); + + } + + } + + public UserAccountsAdapter(Context mCtx, List userAccountsListMain) { + + this.mCtx = mCtx; + this.userAccountsList = userAccountsListMain; + } + + private void deleteAccount(int position) { + + userAccountsList.remove(position); + notifyItemRemoved(position); + notifyItemRangeChanged(position, userAccountsList.size()); + Toasty.info(mCtx, mCtx.getResources().getString(R.string.accountDeletedMessage)); + + } + + @NonNull + @Override + public UserAccountsAdapter.UserAccountsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + + View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_user_accounts, parent, false); + return new UserAccountsViewHolder(v); + } + + @SuppressLint("DefaultLocale") + @Override + public void onBindViewHolder(@NonNull UserAccountsAdapter.UserAccountsViewHolder holder, int position) { + + UserAccount currentItem = userAccountsList.get(position); + tinyDB = new TinyDB(mCtx); + + String url = UrlBuilder.fromString(currentItem.getInstanceUrl()) + .withPath("/") + .toString(); + + holder.userId.setText(String.format("@%s", currentItem.getUserName())); + holder.accountUrl.setText(url); + + if(tinyDB.getInt("currentActiveAccountId") == currentItem.getAccountId()) { + holder.activeAccount.setVisibility(View.VISIBLE); + } + else { + holder.deleteAccount.setVisibility(View.GONE); + } + + } + + @Override + public int getItemCount() { + return userAccountsList.size(); + } + +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/UserAccountsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/UserAccountsFragment.java new file mode 100644 index 00000000..03b7f832 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/UserAccountsFragment.java @@ -0,0 +1,95 @@ +package org.mian.gitnex.fragments; + +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import org.mian.gitnex.R; +import org.mian.gitnex.adapters.UserAccountsAdapter; +import org.mian.gitnex.database.api.UserAccountsApi; +import org.mian.gitnex.database.models.UserAccount; +import java.util.ArrayList; +import java.util.List; + +/** + * Author M M Arif + */ + +public class UserAccountsFragment extends Fragment { + + private Context ctx; + private UserAccountsAdapter adapter; + private RecyclerView mRecyclerView; + private UserAccountsApi userAccountsApi; + private List userAccountsList; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View v = inflater.inflate(R.layout.fragment_user_accounts, container, false); + ctx = getContext(); + setHasOptionsMenu(true); + + userAccountsList = new ArrayList<>(); + userAccountsApi = new UserAccountsApi(ctx); + + mRecyclerView = v.findViewById(R.id.recyclerView); + final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + + mRecyclerView.setHasFixedSize(true); + mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx)); + + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), + DividerItemDecoration.VERTICAL); + mRecyclerView.addItemDecoration(dividerItemDecoration); + + adapter = new UserAccountsAdapter(getContext(), userAccountsList); + + swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> { + + userAccountsList.clear(); + swipeRefresh.setRefreshing(false); + fetchDataAsync(); + + }, 250)); + + fetchDataAsync(); + + return v; + + } + + private void fetchDataAsync() { + + userAccountsApi.getAllAccounts().observe(getViewLifecycleOwner(), userAccounts -> { + + assert userAccounts != null; + if(userAccounts.size() > 0) { + + userAccountsList.clear(); + userAccountsList.addAll(userAccounts); + adapter.notifyDataSetChanged(); + mRecyclerView.setAdapter(adapter); + + } + + }); + + } + + @Override + public void onResume() { + super.onResume(); + userAccountsList.clear(); + fetchDataAsync(); + } + +} diff --git a/app/src/main/res/drawable/circle.xml b/app/src/main/res/drawable/circle.xml index 27c363c7..63a896ff 100644 --- a/app/src/main/res/drawable/circle.xml +++ b/app/src/main/res/drawable/circle.xml @@ -1,5 +1,6 @@ + - \ No newline at end of file + diff --git a/app/src/main/res/drawable/circle_red.xml b/app/src/main/res/drawable/circle_red.xml index 7aef7d52..e6909b1c 100644 --- a/app/src/main/res/drawable/circle_red.xml +++ b/app/src/main/res/drawable/circle_red.xml @@ -1,5 +1,6 @@ + - \ No newline at end of file + diff --git a/app/src/main/res/drawable/circle_white.xml b/app/src/main/res/drawable/circle_white.xml new file mode 100644 index 00000000..d528ee44 --- /dev/null +++ b/app/src/main/res/drawable/circle_white.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_account_circle.xml b/app/src/main/res/drawable/ic_account_circle.xml new file mode 100644 index 00000000..6461e8cc --- /dev/null +++ b/app/src/main/res/drawable/ic_account_circle.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_user_accounts.xml b/app/src/main/res/layout/fragment_user_accounts.xml new file mode 100644 index 00000000..12eda096 --- /dev/null +++ b/app/src/main/res/layout/fragment_user_accounts.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/list_user_accounts.xml b/app/src/main/res/layout/list_user_accounts.xml new file mode 100644 index 00000000..fb458d03 --- /dev/null +++ b/app/src/main/res/layout/list_user_accounts.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/nav_header.xml b/app/src/main/res/layout/nav_header.xml index 722faffb..72b02626 100644 --- a/app/src/main/res/layout/nav_header.xml +++ b/app/src/main/res/layout/nav_header.xml @@ -35,35 +35,61 @@ android:paddingEnd="5dp" android:contentDescription="@string/generalImgContentText"/> - - + android:orientation="horizontal" + android:layout_marginTop="5dp" + android:baselineAligned="false"> - + android:layout_weight=".82" + android:orientation="vertical" + android:layout_marginTop="5dp"> + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 23c94b1a..3bf34b14 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -58,6 +58,7 @@ New File Explore Gitea Administration + Manage Accounts (beta) Version\u0020:\u0020 @@ -684,4 +685,6 @@ Crash reports Archived + + Account deleted successfully