Using blurred avatar as background. (#532)

Fixing NullPointerException when image isn't loaded yet.

Display country instead of raw language code.

Minor improvements and contrasting color.

First changes.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
This commit is contained in:
opyale 2020-06-06 22:04:07 +02:00 committed by M M Arif
parent e267aa5100
commit acc55e3433
12 changed files with 371 additions and 225 deletions

View File

@ -86,5 +86,6 @@ dependencies {
implementation "ch.acra:acra-mail:$acra" implementation "ch.acra:acra-mail:$acra"
implementation "ch.acra:acra-limiter:$acra" implementation "ch.acra:acra-limiter:$acra"
implementation "ch.acra:acra-notification:$acra" implementation "ch.acra:acra-notification:$acra"
implementation 'com.eightbitlab:blurview:1.6.3'
} }

View File

@ -12,6 +12,7 @@ import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -22,7 +23,6 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import com.google.android.material.navigation.NavigationView; import com.google.android.material.navigation.NavigationView;
import com.squareup.picasso.NetworkPolicy;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
@ -38,6 +38,7 @@ import org.mian.gitnex.fragments.StarredRepositoriesFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.ChangeLog; import org.mian.gitnex.helpers.ChangeLog;
import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.GiteaVersion;
@ -45,6 +46,8 @@ import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.Objects; import java.util.Objects;
import eightbitlab.com.blurview.BlurView;
import eightbitlab.com.blurview.RenderScriptBlur;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -55,9 +58,12 @@ import retrofit2.Callback;
public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener { public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer; private DrawerLayout drawer;
private BlurView blurView;
private TextView userFullName; private TextView userFullName;
private TextView userEmail; private TextView userEmail;
private ImageView userAvatar; private ImageView userAvatar;
private ImageView userAvatarBackground;
private ViewGroup navHeaderFrame;
private TextView toolbarTitle; private TextView toolbarTitle;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
@ -131,6 +137,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
FragmentManager fm = getSupportFragmentManager(); FragmentManager fm = getSupportFragmentManager();
Fragment fragmentById = fm.findFragmentById(R.id.fragment_container); Fragment fragmentById = fm.findFragmentById(R.id.fragment_container);
if(fragmentById instanceof SettingsFragment) { if(fragmentById instanceof SettingsFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings));
} }
@ -163,15 +170,10 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.darkGreen)); toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.darkGreen));
drawer.addDrawerListener(toggle); drawer.addDrawerListener(toggle);
drawer.addDrawerListener(new DrawerLayout.DrawerListener() { drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
}
@Override @Override
public void onDrawerOpened(@NonNull View drawerView) { public void onDrawerOpened(@NonNull View drawerView) {
@ -184,78 +186,118 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
String userFullNameNav = tinyDb.getString("userFullname"); String userFullNameNav = tinyDb.getString("userFullname");
String userAvatarNav = tinyDb.getString("userAvatar"); String userAvatarNav = tinyDb.getString("userAvatar");
blurView = hView.findViewById(R.id.blurView);
userEmail = hView.findViewById(R.id.userEmail); userEmail = hView.findViewById(R.id.userEmail);
userFullName = hView.findViewById(R.id.userFullname);
userAvatar = hView.findViewById(R.id.userAvatar);
userAvatarBackground = hView.findViewById(R.id.userAvatarBackground);
navHeaderFrame = hView.findViewById(R.id.navHeaderFrame);
userEmail.setTypeface(myTypeface);
userFullName.setTypeface(myTypeface);
navigationView.getMenu().findItem(R.id.nav_administration).setVisible(tinyDb.getBoolean("userIsAdmin"));
if(!userEmailNav.equals("")) { if(!userEmailNav.equals("")) {
userEmail.setText(userEmailNav); userEmail.setText(userEmailNav);
userEmail.setTypeface(myTypeface);
} }
userFullName = hView.findViewById(R.id.userFullname);
if(!userFullNameNav.equals("")) { if(!userFullNameNav.equals("")) {
userFullName.setText(userFullNameNav); userFullName.setText(userFullNameNav);
userFullName.setTypeface(myTypeface);
} }
userAvatar = hView.findViewById(R.id.userAvatar);
if(!userAvatarNav.equals("")) { if(!userAvatarNav.equals("")) {
PicassoService.getInstance(ctx).get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
PicassoService.getInstance(ctx).get()
.load(userAvatarNav)
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0))
.resize(160, 160)
.centerCrop().into(userAvatar);
PicassoService.getInstance(ctx).get()
.load(userAvatarNav)
.into(userAvatarBackground, new com.squareup.picasso.Callback() {
@Override
public void onSuccess() {
int textColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground);
userFullName.setTextColor(textColor);
userEmail.setTextColor(textColor);
blurView.setupWith(navHeaderFrame)
.setBlurAlgorithm(new RenderScriptBlur(ctx))
.setBlurRadius(5)
.setHasFixedTransformationMatrix(false);
}
@Override
public void onError(Exception e) {}
});
} }
userAvatar.setOnClickListener(new View.OnClickListener() { userAvatar.setOnClickListener(v -> {
public void onClick(View v) { getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
drawer.closeDrawers();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
drawer.closeDrawers();
}
}); });
} }
@Override @Override
public void onDrawerClosed(@NonNull View drawerView) { public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {}
// Called when a drawer has settled in a completely closed state.
}
@Override @Override
public void onDrawerStateChanged(int newState) { public void onDrawerClosed(@NonNull View drawerView) {}
// Called when the drawer motion state changes. The new state will be one of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING.
} @Override
public void onDrawerStateChanged(int newState) {}
}); });
toggle.syncState(); toggle.syncState();
if(savedInstanceState == null) { if(savedInstanceState == null) {
if(tinyDb.getInt("homeScreenId") == 0) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); switch(tinyDb.getInt("homeScreenId")) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home); case 1:
} toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
else if(tinyDb.getInt("homeScreenId") == 1) { getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); navigationView.setCheckedItem(R.id.nav_starred_repos);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit(); break;
navigationView.setCheckedItem(R.id.nav_starred_repos);
} case 2:
else if(tinyDb.getInt("homeScreenId") == 2) { toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); navigationView.setCheckedItem(R.id.nav_organizations);
navigationView.setCheckedItem(R.id.nav_organizations); break;
}
else if(tinyDb.getInt("homeScreenId") == 3) { case 3:
toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_repositories); navigationView.setCheckedItem(R.id.nav_repositories);
} break;
else if(tinyDb.getInt("homeScreenId") == 4) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); case 4:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
navigationView.setCheckedItem(R.id.nav_profile); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
} navigationView.setCheckedItem(R.id.nav_profile);
else { break;
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); default:
navigationView.setCheckedItem(R.id.nav_home); toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home);
break;
} }
} }
if(!connToInternet) { if(!connToInternet) {
@ -269,7 +311,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
else { else {
displayUserInfo(instanceUrl, instanceToken, loginUid); loadUserInfo(instanceUrl, instanceToken, loginUid);
giteaVersion(instanceUrl); giteaVersion(instanceUrl);
tinyDb.putBoolean("noConnection", false); tinyDb.putBoolean("noConnection", false);
@ -314,46 +356,56 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch(menuItem.getItemId()) { switch(menuItem.getItemId()) {
case R.id.nav_home: case R.id.nav_home:
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
break; break;
case R.id.nav_organizations: case R.id.nav_organizations:
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
break; break;
case R.id.nav_profile: case R.id.nav_profile:
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
break; break;
case R.id.nav_repositories: case R.id.nav_repositories:
toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
break; break;
case R.id.nav_settings: case R.id.nav_settings:
toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit();
break; break;
case R.id.nav_logout: case R.id.nav_logout:
logout(this, ctx); logout(this, ctx);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
break; break;
case R.id.nav_about: case R.id.nav_about:
toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout)); toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit();
break; break;
case R.id.nav_rate_app: case R.id.nav_rate_app:
rateThisApp(); rateThisApp();
break; break;
case R.id.nav_starred_repos: case R.id.nav_starred_repos:
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
break; break;
case R.id.nav_explore: case R.id.nav_explore:
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreRepositoriesFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreRepositoriesFragment()).commit();
break; break;
case R.id.nav_administration: case R.id.nav_administration:
toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AdministrationFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AdministrationFragment()).commit();
@ -422,15 +474,12 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
private void displayUserInfo(String instanceUrl, String token, String loginUid) { private void loadUserInfo(String instanceUrl, String token, String loginUid) {
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(appCtx);
Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo(Authorization.returnAuthentication(ctx, loginUid, token)); Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo(Authorization.returnAuthentication(ctx, loginUid, token));
NavigationView navigationView = findViewById(R.id.nav_view);
final View hView = navigationView.getHeaderView(0);
call.enqueue(new Callback<UserInfo>() { call.enqueue(new Callback<UserInfo>() {
@Override @Override
@ -443,12 +492,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
if(response.code() == 200) { if(response.code() == 200) {
assert userDetails != null; assert userDetails != null;
if(userDetails.getIs_admin() != null) { if(userDetails.getIs_admin() != null) {
tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin()); tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin());
navigationView.getMenu().findItem(R.id.nav_administration).setVisible(userDetails.getIs_admin());
} }
tinyDb.putString("userLogin", userDetails.getLogin()); tinyDb.putString("userLogin", userDetails.getLogin());
tinyDb.putInt("userId", userDetails.getId()); tinyDb.putInt("userId", userDetails.getId());
if(!userDetails.getFullname().equals("")) { if(!userDetails.getFullname().equals("")) {
tinyDb.putString("userFullname", userDetails.getFullname()); tinyDb.putString("userFullname", userDetails.getFullname());
} }
@ -458,51 +509,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
tinyDb.putString("userEmail", userDetails.getEmail()); tinyDb.putString("userEmail", userDetails.getEmail());
tinyDb.putString("userAvatar", userDetails.getAvatar()); tinyDb.putString("userAvatar", userDetails.getAvatar());
if(userDetails.getLang() != null) { if(userDetails.getLang() != null) {
tinyDb.putString("userLang", userDetails.getLang()); tinyDb.putString("userLang", userDetails.getLang());
} }
else { else {
tinyDb.putString("userLang", "..."); tinyDb.putString("userLang", "...");
} }
userAvatar = hView.findViewById(R.id.userAvatar);
if(!Objects.requireNonNull(userDetails).getAvatar().equals("")) {
PicassoService.getInstance(ctx).get().load(userDetails.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
}
else {
userAvatar.setImageResource(R.mipmap.app_logo_round);
}
userFullName = hView.findViewById(R.id.userFullname);
if(!userDetails.getFullname().equals("")) {
userFullName.setText(userDetails.getFullname());
}
else if(!userDetails.getLogin().equals("")) {
userFullName.setText(userDetails.getLogin());
}
else {
userFullName.setText("...");
}
userEmail = hView.findViewById(R.id.userEmail);
if(!userDetails.getEmail().equals("")) {
userEmail.setText(userDetails.getEmail());
}
else {
userEmail.setText("...");
}
userAvatar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
drawer.closeDrawers();
}
});
} }
} }
else if(response.code() == 401) { else if(response.code() == 401) {

View File

@ -14,16 +14,18 @@ import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
/** /**
* Author anonTree1417 * Author opyale
*/ */
public class PicassoService { public class PicassoService {
private static PicassoService picassoService; private static PicassoService picassoService;
private static File cachePath;
private Picasso picasso; private Picasso picasso;
private PicassoService(Context context) { private PicassoService(Context context) {
cachePath = new File(context.getCacheDir() + "/picasso_cache/");
Picasso.Builder builder = new Picasso.Builder(context); Picasso.Builder builder = new Picasso.Builder(context);
try { try {
@ -45,10 +47,6 @@ public class PicassoService {
}); });
File cachePath = new File(context.getCacheDir() + "/picasso_cache/");
//noinspection ResultOfMethodCallIgnored
cachePath.mkdirs();
picasso = builder.memoryCache(new PicassoCache(cachePath, context)).build(); picasso = builder.memoryCache(new PicassoCache(cachePath, context)).build();
} }
@ -61,7 +59,9 @@ public class PicassoService {
public Picasso get() { public Picasso get() {
cachePath.mkdirs();
return picasso; return picasso;
} }
public static synchronized PicassoService getInstance(Context context) { public static synchronized PicassoService getInstance(Context context) {

View File

@ -3,12 +3,6 @@ package org.mian.gitnex.fragments;
import android.content.Context; import android.content.Context;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -17,13 +11,24 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.squareup.picasso.Callback;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import eightbitlab.com.blurview.BlurView;
import eightbitlab.com.blurview.RenderScriptBlur;
/** /**
* Author M M Arif * Author M M Arif
@ -31,26 +36,67 @@ import java.util.Objects;
public class ProfileFragment extends Fragment { public class ProfileFragment extends Fragment {
private Context ctx = getContext(); private Context ctx;
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ctx = getContext();
View v = inflater.inflate(R.layout.fragment_profile, container, false); View v = inflater.inflate(R.layout.fragment_profile, container, false);
setHasOptionsMenu(true); setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext()); TinyDB tinyDb = new TinyDB(getContext());
BlurView blurView = v.findViewById(R.id.blurView);
TextView userFullName = v.findViewById(R.id.userFullName); TextView userFullName = v.findViewById(R.id.userFullName);
ImageView userAvatarBackground = v.findViewById(R.id.userAvatarBackground);
ImageView userAvatar = v.findViewById(R.id.userAvatar); ImageView userAvatar = v.findViewById(R.id.userAvatar);
TextView userLogin = v.findViewById(R.id.userLogin); TextView userLogin = v.findViewById(R.id.userLogin);
TextView userEmail = v.findViewById(R.id.userEmail); TextView userLanguage = v.findViewById(R.id.userLanguage);
ViewGroup aboutFrame = v.findViewById(R.id.aboutFrame);
String[] userLanguageCodes = tinyDb.getString("userLang").split("-");
Locale locale = new Locale(userLanguageCodes[0], userLanguageCodes[1]);
userFullName.setText(tinyDb.getString("userFullname"));
userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin")));
userLanguage.setText(locale.getDisplayCountry());
PicassoService.getInstance(ctx).get()
.load(tinyDb.getString("userAvatar"))
.transform(new RoundedTransformation(8, 0))
.placeholder(R.drawable.loader_animated)
.resize(120, 120)
.centerCrop().into(userAvatar);
PicassoService.getInstance(ctx).get()
.load(tinyDb.getString("userAvatar"))
.into(userAvatarBackground, new Callback() {
@Override
public void onSuccess() {
int textColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground);
userFullName.setTextColor(textColor);
userLogin.setTextColor(textColor);
userLanguage.setTextColor(textColor);
blurView.setupWith(aboutFrame)
.setBlurAlgorithm(new RenderScriptBlur(ctx))
.setBlurRadius(3)
.setHasFixedTransformationMatrix(true);
}
@Override
public void onError(Exception e) {}
});
userFullName.setText(tinyDb.getString("userFullname"));
PicassoService.getInstance(ctx).get().load(tinyDb.getString("userAvatar")).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(userAvatar);
userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin")));
userEmail.setText(tinyDb.getString("userEmail"));
ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager()); ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
@ -79,11 +125,16 @@ public class ProfileFragment extends Fragment {
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0); ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount(); int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) { for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j); ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildCount = vgTab.getChildCount(); int tabChildCount = vgTab.getChildCount();
for (int i = 0; i < tabChildCount; i++) { for (int i = 0; i < tabChildCount; i++) {
View tabViewChild = vgTab.getChildAt(i); View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) { if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(myTypeface); ((TextView) tabViewChild).setTypeface(myTypeface);
} }
@ -108,15 +159,22 @@ public class ProfileFragment extends Fragment {
public Fragment getItem(int position) { public Fragment getItem(int position) {
Fragment fragment = null; Fragment fragment = null;
switch (position) { switch (position) {
case 0: // followers case 0: // followers
return ProfileFollowersFragment.newInstance("repoOwner", "repoName"); return ProfileFollowersFragment.newInstance("repoOwner", "repoName");
case 1: // following case 1: // following
return ProfileFollowingFragment.newInstance("repoOwner", "repoName"); return ProfileFollowingFragment.newInstance("repoOwner", "repoName");
case 2: // emails case 2: // emails
return ProfileEmailsFragment.newInstance("repoOwner", "repoName"); return ProfileEmailsFragment.newInstance("repoOwner", "repoName");
} }
return fragment; return fragment;
} }
@Override @Override
@ -128,9 +186,11 @@ public class ProfileFragment extends Fragment {
@Override @Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear(); menu.clear();
Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.profile_dotted_menu, menu); Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.profile_dotted_menu, menu);
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
} }
@Override @Override
@ -139,17 +199,20 @@ public class ProfileFragment extends Fragment {
int id = item.getItemId(); int id = item.getItemId();
switch (id) { switch (id) {
case android.R.id.home: case android.R.id.home:
((MainActivity)ctx).finish(); ((MainActivity)ctx).finish();
return true; return true;
case R.id.profileMenu: case R.id.profileMenu:
BottomSheetProfileFragment bottomSheet = new BottomSheetProfileFragment(); BottomSheetProfileFragment bottomSheet = new BottomSheetProfileFragment();
bottomSheet.show(getChildFragmentManager(), "profileBottomSheet"); bottomSheet.show(getChildFragmentManager(), "profileBottomSheet");
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
}
}
} }
} }

View File

@ -1,6 +1,9 @@
package org.mian.gitnex.helpers; package org.mian.gitnex.helpers;
import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.widget.ImageView;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
/** /**
@ -16,7 +19,7 @@ public class ColorInverter {
int d; int d;
if (a < 0.5) { if (a < 0.5) {
d = 0; // black d = 30; // almost black
} else { } else {
d = 255; // white d = 255; // white
} }
@ -24,4 +27,20 @@ public class ColorInverter {
return Color.rgb(d, d, d); return Color.rgb(d, d, d);
} }
@ColorInt
public int getImageViewContrastColor(ImageView imageView) {
if(imageView != null) {
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
return getContrastColor(bitmap.getPixel(bitmap.getWidth() / 2, bitmap.getHeight() / 2));
}
else {
return Color.rgb(255, 255, 255);
}
}
} }

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical" android:orientation="vertical"
android:gravity="center" android:gravity="center"
@ -239,4 +239,4 @@
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@ -10,58 +10,89 @@
<RelativeLayout <RelativeLayout
android:id="@+id/aboutFrame" android:id="@+id/aboutFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="172dp" android:layout_height="200dp"
android:orientation="vertical" android:gravity="top"
android:background="@drawable/nav_background" android:orientation="vertical">
android:gravity="top">
<LinearLayout <ImageView
android:id="@+id/layoutFrameAccount" android:id="@+id/userAvatarBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="186dp" android:layout_height="match_parent"
android:padding="16dp" android:contentDescription="@string/generalImgContentText"
android:orientation="vertical"> android:scaleType="centerCrop" />
<ImageView <eightbitlab.com.blurview.BlurView
android:id="@+id/userAvatar" android:id="@+id/blurView"
android:layout_width="54dp" android:layout_width="match_parent"
android:layout_height="54dp" android:layout_height="match_parent"
android:layout_marginBottom="8dp" app:blurOverlayColor="@color/blurColor">
android:layout_gravity="center"
android:contentDescription="@string/generalImgContentText"
android:src="@mipmap/app_logo_round" />
<TextView <LinearLayout
android:id="@+id/userFullName" android:id="@+id/layoutFrameAccount"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:textIsSelectable="true" android:gravity="center"
android:layout_marginBottom="8dp" android:orientation="vertical"
android:textSize="16sp" android:padding="16dp">
android:textColor="@color/white"
android:layout_gravity="center" />
<TextView <ImageView
android:id="@+id/userLogin" android:id="@+id/userAvatar"
android:layout_width="wrap_content" android:layout_width="54dp"
android:layout_height="wrap_content" android:layout_height="54dp"
android:textIsSelectable="true" android:layout_marginBottom="8dp"
android:layout_marginBottom="8dp" android:contentDescription="@string/generalImgContentText"
android:textSize="16sp" android:src="@mipmap/app_logo_round" />
android:textColor="@color/white"
android:layout_gravity="center" />
<TextView <TextView
android:id="@+id/userEmail" android:id="@+id/userFullName"
android:textIsSelectable="true" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:textColor="@color/white"
android:layout_marginBottom="0dp" android:textIsSelectable="true"
android:textSize="16sp" android:textSize="18sp" />
android:textColor="@color/white"
android:layout_gravity="center" />
</LinearLayout> <TextView
android:id="@+id/userLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:textColor="@color/white"
android:textIsSelectable="true"
android:textSize="14sp" />
<View
android:layout_width="50dp"
android:layout_height="1dp"
android:layout_marginBottom="10dp"
android:background="@color/colorWhite" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="18dp"
android:layout_marginRight="2dp"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_language"
app:tint="@color/colorWhite" />
<TextView
android:id="@+id/userLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textIsSelectable="true"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</eightbitlab.com.blurview.BlurView>
</RelativeLayout> </RelativeLayout>
@ -108,4 +139,4 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout> </LinearLayout>

View File

@ -25,7 +25,6 @@
android:id="@+id/userFullName" android:id="@+id/userFullName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="@string/userName" android:text="@string/userName"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="16sp" /> android:textSize="16sp" />
@ -34,10 +33,9 @@
android:id="@+id/userName" android:id="@+id/userName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="@string/userName" android:text="@string/userName"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="16sp" /> android:textSize="14sp" />
</LinearLayout> </LinearLayout>

View File

@ -25,7 +25,6 @@
android:id="@+id/userFullName" android:id="@+id/userFullName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="@string/userName" android:text="@string/userName"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="16sp" /> android:textSize="16sp" />
@ -34,10 +33,9 @@
android:id="@+id/userName" android:id="@+id/userName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="@string/userName" android:text="@string/userName"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="16sp" /> android:textSize="14sp" />
</LinearLayout> </LinearLayout>

View File

@ -1,62 +1,83 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navHeaderFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="200dp" android:layout_height="200dp">
android:background="@drawable/nav_background"
android:gravity="bottom"
android:paddingTop="16dp">
<ImageView <ImageView
android:id="@+id/userAvatar" android:id="@+id/userAvatarBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_android"
android:maxHeight="24dp"
android:maxWidth="24dp"
android:paddingStart="20dp"
android:paddingEnd="5dp"
android:contentDescription="@string/app_name"/>
<TextView
android:id="@+id/userFullname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:text="@string/app_name"
android:textSize="18sp"
android:textIsSelectable="true"
android:textColor="@color/white"
android:paddingStart="20dp"
android:paddingEnd="5dp" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginTop="5dp"> android:contentDescription="@string/generalImgContentText"
android:scaleType="centerCrop" />
<TextView <eightbitlab.com.blurview.BlurView
android:id="@+id/userEmail" android:id="@+id/blurView"
android:layout_width="0dp"
android:layout_weight="0.85"
android:layout_height="wrap_content"
android:text="@string/appEmail"
android:textSize="14sp"
android:textIsSelectable="true"
android:textColor="@color/white"
android:gravity="start"
android:layout_gravity="center_vertical"
android:paddingStart="20dp"
android:paddingEnd="5dp" />
</LinearLayout>
<View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="match_parent"
android:layout_marginTop="16dp" app:blurOverlayColor="@color/blurColor">
android:background="?attr/dividerColor" />
</LinearLayout> <LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:paddingTop="16dp">
<ImageView
android:id="@+id/userAvatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_android"
android:maxHeight="24dp"
android:maxWidth="24dp"
android:paddingStart="20dp"
android:paddingEnd="5dp"
android:contentDescription="@string/app_name"/>
<TextView
android:id="@+id/userFullname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:text="@string/app_name"
android:textSize="18sp"
android:textIsSelectable="true"
android:textColor="@color/white"
android:paddingStart="20dp"
android:paddingEnd="5dp" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp">
<TextView
android:id="@+id/userEmail"
android:layout_width="0dp"
android:layout_weight="0.85"
android:layout_height="wrap_content"
android:text="@string/appEmail"
android:textSize="14sp"
android:textIsSelectable="true"
android:textColor="@color/white"
android:gravity="start"
android:layout_gravity="center_vertical"
android:paddingStart="20dp"
android:paddingEnd="5dp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="16dp"
android:background="?attr/dividerColor" />
</LinearLayout>
</eightbitlab.com.blurview.BlurView>
</RelativeLayout>

View File

@ -11,6 +11,7 @@
<color name="black">#000009</color> <color name="black">#000009</color>
<color name="white">#ffffff</color> <color name="white">#ffffff</color>
<color name="tooltipBackground">#1e88ce</color> <color name="tooltipBackground">#1e88ce</color>
<color name="blurColor">#41818181</color>
<color name="btnBackground">#009486</color> <color name="btnBackground">#009486</color>
<color name="btnTextColor">#ffffff</color> <color name="btnTextColor">#ffffff</color>
<color name="inputBackground">#1d1d1d</color> <color name="inputBackground">#1d1d1d</color>

View File

@ -406,7 +406,7 @@
<string name="emailErrorInUse">Email address is already in use</string> <string name="emailErrorInUse">Email address is already in use</string>
<string name="emailTypeText">Primary</string> <string name="emailTypeText">Primary</string>
<string name="profileTabEmails">Emails</string> <string name="profileTabEmails">Emails</string>
<string name="usernameWithAt" translatable="false">\u0040\u0020%1$s</string> <string name="usernameWithAt" translatable="false">\u0040%1$s</string>
<!-- profile section --> <!-- profile section -->
<!-- single issue section --> <!-- single issue section -->