mirror of
https://codeberg.org/gitnex/GitNex
synced 2024-12-23 00:48:57 +01:00
Most visited repositories (#1178)
This is an app only feature and could be useful to some users including me. Co-authored-by: M M Arif <mmarif@swatian.com> Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1178
This commit is contained in:
parent
23df83110d
commit
387089fb26
@ -108,7 +108,7 @@ dependencies {
|
||||
implementation "androidx.work:work-runtime:$work_version"
|
||||
implementation "io.mikael:urlbuilder:2.0.9"
|
||||
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.2.0"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
|
||||
implementation 'androidx.biometric:biometric:1.1.0'
|
||||
implementation 'com.github.chrisvest:stormpot:2.4.2'
|
||||
implementation 'androidx.browser:browser:1.4.0'
|
||||
|
@ -39,6 +39,7 @@ import org.mian.gitnex.fragments.BottomSheetDraftsFragment;
|
||||
import org.mian.gitnex.fragments.BottomSheetMyIssuesFilterFragment;
|
||||
import org.mian.gitnex.fragments.DraftsFragment;
|
||||
import org.mian.gitnex.fragments.ExploreFragment;
|
||||
import org.mian.gitnex.fragments.MostVisitedReposFragment;
|
||||
import org.mian.gitnex.fragments.MyIssuesFragment;
|
||||
import org.mian.gitnex.fragments.MyProfileFragment;
|
||||
import org.mian.gitnex.fragments.MyRepositoriesFragment;
|
||||
@ -145,6 +146,9 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
||||
else if(fragmentById instanceof MyProfileFragment) {
|
||||
toolbarTitle.setText(getResources().getString(R.string.navProfile));
|
||||
}
|
||||
else if(fragmentById instanceof MostVisitedReposFragment) {
|
||||
toolbarTitle.setText(getResources().getString(R.string.navMostVisited));
|
||||
}
|
||||
else if(fragmentById instanceof DraftsFragment) {
|
||||
toolbarTitle.setText(getResources().getString(R.string.titleDrafts));
|
||||
}
|
||||
@ -592,6 +596,11 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
||||
toolbarTitle.setText(getResources().getString(R.string.navMyIssues));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyIssuesFragment()).commit();
|
||||
}
|
||||
else if(id == R.id.nav_most_visited) {
|
||||
|
||||
toolbarTitle.setText(getResources().getString(R.string.navMostVisited));
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MostVisitedReposFragment()).commit();
|
||||
}
|
||||
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
@ -62,7 +62,6 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
|
||||
DraftsApi draftsApi = BaseApi.getInstance(context, DraftsApi.class);
|
||||
assert draftsApi != null;
|
||||
draftsApi.deleteSingleDraft(getDraftId);
|
||||
|
||||
});
|
||||
|
||||
itemView.setOnClickListener(itemEdit -> {
|
||||
@ -98,9 +97,7 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
|
||||
});
|
||||
bottomSheetReplyFragment.show(fragmentManager, "replyBottomSheet");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DraftsAdapter(Context ctx, FragmentManager fragmentManager, List<DraftWithRepository> draftsListMain) {
|
||||
@ -152,9 +149,14 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
|
||||
return draftsList.size();
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
public void notifyDataChanged() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void updateList(List<DraftWithRepository> list) {
|
||||
|
||||
draftsList = list;
|
||||
notifyDataSetChanged();
|
||||
notifyDataChanged();
|
||||
}
|
||||
}
|
||||
|
@ -117,14 +117,21 @@ public class ExploreIssuesAdapter extends RecyclerView.Adapter<RecyclerView.View
|
||||
|
||||
RepositoryContext repo = new RepositoryContext(repoOwner, repoName, context);
|
||||
|
||||
repo.saveToDB(context);
|
||||
|
||||
Intent intentIssueDetail = new IssueContext(issue, repo).getIntent(context, IssueDetailActivity.class);
|
||||
intentIssueDetail.putExtra("openedFromLink", "true");
|
||||
|
||||
itemView.setOnClickListener(v -> context.startActivity(intentIssueDetail));
|
||||
frameLabels.setOnClickListener(v -> context.startActivity(intentIssueDetail));
|
||||
frameLabelsDots.setOnClickListener(v -> context.startActivity(intentIssueDetail));
|
||||
itemView.setOnClickListener(v -> {
|
||||
repo.saveToDB(context);
|
||||
context.startActivity(intentIssueDetail);
|
||||
});
|
||||
frameLabels.setOnClickListener(v -> {
|
||||
repo.saveToDB(context);
|
||||
context.startActivity(intentIssueDetail);
|
||||
});
|
||||
frameLabelsDots.setOnClickListener(v -> {
|
||||
repo.saveToDB(context);
|
||||
context.startActivity(intentIssueDetail);
|
||||
});
|
||||
}, 200);
|
||||
|
||||
issueAssigneeAvatar.setOnClickListener(v -> {
|
||||
|
@ -116,7 +116,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<RecyclerVie
|
||||
|
||||
orgName.setText(userRepositories.getFullName().split("/")[0]);
|
||||
repoName.setText(userRepositories.getFullName().split("/")[1]);
|
||||
repoStars.setText(String.valueOf(userRepositories.getStarsCount()));
|
||||
repoStars.setText(AppUtil.numberFormatter(userRepositories.getStarsCount()));
|
||||
|
||||
ColorGenerator generator = ColorGenerator.Companion.getMATERIAL();
|
||||
int color = generator.getColor(userRepositories.getName());
|
||||
|
@ -0,0 +1,103 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
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 com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.RepoDetailActivity;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.contexts.RepositoryContext;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author M M Arif
|
||||
*/
|
||||
|
||||
public class MostVisitedReposAdapter extends RecyclerView.Adapter<MostVisitedReposAdapter.MostVisitedViewHolder> {
|
||||
|
||||
private List<Repository> mostVisitedReposList;
|
||||
|
||||
static class MostVisitedViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private Repository repository;
|
||||
|
||||
private final ImageView image;
|
||||
private final TextView repoName;
|
||||
private final TextView orgName;
|
||||
private final TextView mostVisited;
|
||||
|
||||
private MostVisitedViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
image = itemView.findViewById(R.id.image);
|
||||
repoName = itemView.findViewById(R.id.repo_name);
|
||||
orgName = itemView.findViewById(R.id.org_name);
|
||||
mostVisited = itemView.findViewById(R.id.most_visited);
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
|
||||
Context context = v.getContext();
|
||||
RepositoryContext repositoryContext = new RepositoryContext(repository.getRepositoryOwner(), repository.getRepositoryName(), context);
|
||||
Intent intent = repositoryContext.getIntent(context, RepoDetailActivity.class);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public MostVisitedReposAdapter(List<Repository> reposListMain) {
|
||||
this.mostVisitedReposList = reposListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MostVisitedViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_most_visited_repos, parent, false);
|
||||
return new MostVisitedViewHolder(v);
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MostVisitedViewHolder holder, int position) {
|
||||
|
||||
Repository currentItem = mostVisitedReposList.get(position);
|
||||
holder.repository = currentItem;
|
||||
|
||||
ColorGenerator generator = ColorGenerator.Companion.getMATERIAL();
|
||||
int color = generator.getColor(currentItem.getRepositoryOwner());
|
||||
String firstCharacter = String.valueOf(currentItem.getRepositoryOwner().charAt(0));
|
||||
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 14);
|
||||
|
||||
holder.image.setImageDrawable(drawable);
|
||||
holder.orgName.setText(currentItem.getRepositoryOwner());
|
||||
holder.repoName.setText(currentItem.getRepositoryName());
|
||||
holder.mostVisited.setText(AppUtil.numberFormatter(currentItem.getMostVisited()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mostVisitedReposList.size();
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
public void notifyDataChanged() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void updateList(List<Repository> list) {
|
||||
|
||||
mostVisitedReposList = list;
|
||||
notifyDataChanged();
|
||||
}
|
||||
}
|
@ -109,7 +109,7 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
this.userRepositories = forksModel;
|
||||
orgName.setText(forksModel.getFullName().split("/")[0]);
|
||||
repoName.setText(forksModel.getFullName().split("/")[1]);
|
||||
repoStars.setText(String.valueOf(forksModel.getStarsCount()));
|
||||
repoStars.setText(AppUtil.numberFormatter(forksModel.getStarsCount()));
|
||||
|
||||
ColorGenerator generator = ColorGenerator.Companion.getMATERIAL();
|
||||
int color = generator.getColor(forksModel.getName());
|
||||
@ -175,7 +175,6 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
|
||||
Context context = v.getContext();
|
||||
|
||||
String[] parts = userRepositories.getFullName().split("/");
|
||||
RepositoryContext repo = new RepositoryContext(userRepositories, context);
|
||||
repo.saveToDB(context);
|
||||
Intent intent = repo.getIntent(context, RepoDetailActivity.class);
|
||||
@ -184,7 +183,6 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setMoreDataAvailable(boolean moreDataAvailable) {
|
||||
|
@ -127,7 +127,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
String timeFormat = tinyDb.getString("dateFormat", "pretty");
|
||||
orgName.setText(repositories.getFullName().split("/")[0]);
|
||||
repoName.setText(repositories.getFullName().split("/")[1]);
|
||||
repoStars.setText(String.valueOf(repositories.getStarsCount()));
|
||||
repoStars.setText(AppUtil.numberFormatter(repositories.getStarsCount()));
|
||||
|
||||
ColorGenerator generator = ColorGenerator.Companion.getMATERIAL();
|
||||
int color = generator.getColor(repositories.getName());
|
||||
|
@ -19,12 +19,13 @@ public class RepositoriesApi extends BaseApi {
|
||||
repositoriesDao = gitnexDatabase.repositoriesDao();
|
||||
}
|
||||
|
||||
public long insertRepository(int repoAccountId, String repositoryOwner, String repositoryName) {
|
||||
public long insertRepository(int repoAccountId, String repositoryOwner, String repositoryName, int mostVisited) {
|
||||
|
||||
Repository repository = new Repository();
|
||||
repository.setRepoAccountId(repoAccountId);
|
||||
repository.setRepositoryOwner(repositoryOwner);
|
||||
repository.setRepositoryName(repositoryName);
|
||||
repository.setMostVisited(mostVisited);
|
||||
|
||||
return insertRepositoryAsyncTask(repository);
|
||||
}
|
||||
@ -69,4 +70,11 @@ public class RepositoriesApi extends BaseApi {
|
||||
executorService.execute(() -> repositoriesDao.deleteRepository(repositoryId));
|
||||
}
|
||||
|
||||
public void updateRepositoryMostVisited(int mostVisited, int repositoryId) {
|
||||
executorService.execute(() -> repositoriesDao.updateRepositoryMostVisited(mostVisited, repositoryId));
|
||||
}
|
||||
|
||||
public LiveData<List<Repository>> fetchAllMostVisited(int repoAccountId) {
|
||||
return repositoriesDao.fetchAllMostVisited(repoAccountId);
|
||||
}
|
||||
}
|
||||
|
@ -44,4 +44,9 @@ public interface RepositoriesDao {
|
||||
@Query("DELETE FROM Repositories WHERE repoAccountId = :repoAccountId")
|
||||
void deleteRepositoriesByAccount(int repoAccountId);
|
||||
|
||||
@Query("UPDATE Repositories SET mostVisited = :mostVisited WHERE repositoryId = :repositoryId")
|
||||
void updateRepositoryMostVisited(int mostVisited, int repositoryId);
|
||||
|
||||
@Query("SELECT * FROM Repositories WHERE mostVisited > 0 AND repoAccountId = :repoAccountId ORDER BY mostVisited DESC LIMIT 50")
|
||||
LiveData<List<Repository>> fetchAllMostVisited(int repoAccountId);
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ import org.mian.gitnex.database.models.UserAccount;
|
||||
*/
|
||||
|
||||
@Database(entities = {Draft.class, Repository.class, UserAccount.class},
|
||||
version = 5, exportSchema = false)
|
||||
version = 6, exportSchema = false)
|
||||
public abstract class GitnexDatabase extends RoomDatabase {
|
||||
|
||||
private static final String DB_NAME = "gitnex";
|
||||
private static GitnexDatabase gitnexDatabase;
|
||||
private static volatile GitnexDatabase gitnexDatabase;
|
||||
|
||||
public abstract DraftsDao draftsDao();
|
||||
public abstract RepositoriesDao repositoriesDao();
|
||||
@ -61,6 +61,14 @@ public abstract class GitnexDatabase extends RoomDatabase {
|
||||
}
|
||||
};
|
||||
|
||||
private static final Migration MIGRATION_5_6 = new Migration(5, 6) {
|
||||
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||
database.execSQL("ALTER TABLE 'Repositories' ADD COLUMN 'mostVisited' INTEGER NOT NULL DEFAULT 0");
|
||||
}
|
||||
};
|
||||
|
||||
public static GitnexDatabase getDatabaseInstance(Context context) {
|
||||
|
||||
if (gitnexDatabase == null) {
|
||||
@ -68,9 +76,9 @@ public abstract class GitnexDatabase extends RoomDatabase {
|
||||
if(gitnexDatabase == null) {
|
||||
|
||||
gitnexDatabase = Room.databaseBuilder(context, GitnexDatabase.class, DB_NAME)
|
||||
// .fallbackToDestructiveMigration()
|
||||
//.fallbackToDestructiveMigration()
|
||||
.allowMainThreadQueries()
|
||||
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5)
|
||||
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6)
|
||||
.build();
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ public class Repository implements Serializable {
|
||||
private int repoAccountId;
|
||||
private String repositoryOwner;
|
||||
private String repositoryName;
|
||||
private int mostVisited;
|
||||
|
||||
public int getRepositoryId() {
|
||||
return repositoryId;
|
||||
@ -56,4 +57,12 @@ public class Repository implements Serializable {
|
||||
public void setRepositoryName(String repositoryName) {
|
||||
this.repositoryName = repositoryName;
|
||||
}
|
||||
|
||||
public int getMostVisited() {
|
||||
return mostVisited;
|
||||
}
|
||||
|
||||
public void setMostVisited(int mostVisited) {
|
||||
this.mostVisited = mostVisited;
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,6 @@ public class DraftsFragment extends Fragment {
|
||||
fetchDataAsync(currentActiveAccountId);
|
||||
|
||||
return fragmentDraftsBinding.getRoot();
|
||||
|
||||
}
|
||||
|
||||
private void fetchDataAsync(int accountId) {
|
||||
@ -99,18 +98,14 @@ public class DraftsFragment extends Fragment {
|
||||
draftsList_.clear();
|
||||
noData.setVisibility(View.GONE);
|
||||
draftsList_.addAll(drafts);
|
||||
adapter.notifyDataSetChanged();
|
||||
adapter.notifyDataChanged();
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,9 +121,8 @@ public class DraftsFragment extends Fragment {
|
||||
|
||||
BaseApi.getInstance(ctx, DraftsApi.class).deleteAllDrafts(accountId);
|
||||
draftsList_.clear();
|
||||
adapter.notifyDataSetChanged();
|
||||
adapter.notifyDataChanged();
|
||||
Toasty.success(ctx, getResources().getString(R.string.draftsDeleteSuccess));
|
||||
|
||||
}
|
||||
else {
|
||||
Toasty.warning(ctx, getResources().getString(R.string.draftsListEmpty));
|
||||
@ -160,10 +154,8 @@ public class DraftsFragment extends Fragment {
|
||||
|
||||
filter(newText);
|
||||
return false;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void filter(String text) {
|
||||
@ -184,5 +176,4 @@ public class DraftsFragment extends Fragment {
|
||||
|
||||
adapter.updateList(arr);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,103 @@
|
||||
package org.mian.gitnex.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
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.activities.MainActivity;
|
||||
import org.mian.gitnex.adapters.MostVisitedReposAdapter;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.databinding.FragmentDraftsBinding;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author M M Arif
|
||||
*/
|
||||
|
||||
public class MostVisitedReposFragment extends Fragment {
|
||||
|
||||
private Context ctx;
|
||||
private MostVisitedReposAdapter adapter;
|
||||
private RecyclerView mRecyclerView;
|
||||
private RepositoriesApi repositoriesApi;
|
||||
private TextView noData;
|
||||
private List<Repository> mostVisitedReposList;
|
||||
private int currentActiveAccountId;
|
||||
private SwipeRefreshLayout swipeRefresh;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
FragmentDraftsBinding fragmentDraftsBinding = FragmentDraftsBinding.inflate(inflater, container, false);
|
||||
|
||||
ctx = getContext();
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navMostVisited));
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(ctx);
|
||||
|
||||
mostVisitedReposList = new ArrayList<>();
|
||||
repositoriesApi = BaseApi.getInstance(ctx, RepositoriesApi.class);
|
||||
|
||||
noData = fragmentDraftsBinding.noData;
|
||||
mRecyclerView = fragmentDraftsBinding.recyclerView;
|
||||
swipeRefresh = fragmentDraftsBinding.pullToRefresh;
|
||||
|
||||
mRecyclerView.setHasFixedSize(true);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
adapter = new MostVisitedReposAdapter(mostVisitedReposList);
|
||||
currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
|
||||
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
mostVisitedReposList.clear();
|
||||
fetchDataAsync(currentActiveAccountId);
|
||||
}, 250));
|
||||
|
||||
fetchDataAsync(currentActiveAccountId);
|
||||
|
||||
return fragmentDraftsBinding.getRoot();
|
||||
}
|
||||
|
||||
private void fetchDataAsync(int accountId) {
|
||||
|
||||
repositoriesApi.fetchAllMostVisited(accountId).observe(getViewLifecycleOwner(), mostVisitedRepos -> {
|
||||
|
||||
swipeRefresh.setRefreshing(false);
|
||||
assert mostVisitedRepos != null;
|
||||
if(mostVisitedRepos.size() > 0) {
|
||||
|
||||
mostVisitedReposList.clear();
|
||||
noData.setVisibility(View.GONE);
|
||||
mostVisitedReposList.addAll(mostVisitedRepos);
|
||||
adapter.notifyDataChanged();
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
}
|
||||
else {
|
||||
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@ import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@ -456,6 +457,27 @@ public class AppUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty number format
|
||||
* Example, 1200 = 1.2k
|
||||
*/
|
||||
public static String numberFormatter(Number number) {
|
||||
|
||||
char[] suffix = {' ', 'k', 'M', 'B', 'T'};
|
||||
long numValue = number.longValue();
|
||||
int value = (int) Math.floor(Math.log10(numValue));
|
||||
int base = value / 3;
|
||||
if(value >= 3 && base < suffix.length) {
|
||||
return new DecimalFormat("#0.0").format(numValue / Math.pow(10, base * 3)) + suffix[base];
|
||||
}
|
||||
if(base >= suffix.length) {
|
||||
return new DecimalFormat("#0").format(numValue / Math.pow(10, base * 2)) + suffix[4];
|
||||
}
|
||||
else {
|
||||
return new DecimalFormat("#,##0").format(numValue);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check for ghost/restricted users/profiles
|
||||
*/
|
||||
public static Boolean checkGhostUsers(String str) {
|
||||
|
@ -33,7 +33,6 @@ public class RepositoryContext implements Serializable {
|
||||
OPEN,
|
||||
CLOSED;
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -243,16 +242,17 @@ public class RepositoryContext implements Serializable {
|
||||
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
|
||||
|
||||
assert repositoryData != null;
|
||||
Integer count = repositoryData.checkRepository(currentActiveAccountId, getOwner(), getName());
|
||||
Repository getMostVisitedValue = repositoryData.getRepository(currentActiveAccountId, getOwner(), getName());
|
||||
|
||||
if(count == 0) {
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, getOwner(), getName());
|
||||
if(getMostVisitedValue == null) {
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, getOwner(), getName(), 1);
|
||||
setRepositoryId((int) id);
|
||||
return (int) id;
|
||||
}
|
||||
else {
|
||||
Repository data = repositoryData.getRepository(currentActiveAccountId, getOwner(), getName());
|
||||
setRepositoryId(data.getRepositoryId());
|
||||
repositoryData.updateRepositoryMostVisited(getMostVisitedValue.getMostVisited() + 1, data.getRepositoryId());
|
||||
return data.getRepositoryId();
|
||||
}
|
||||
}
|
||||
|
20
app/src/main/res/drawable/ic_trending.xml
Normal file
20
app/src/main/res/drawable/ic_trending.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M3,17l6,-6l4,4l8,-8"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="?attr/iconsColor"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M14,7l7,0l0,7"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="?attr/iconsColor"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
@ -70,7 +70,7 @@
|
||||
android:layout_marginBottom="@dimen/dimen8dp"
|
||||
android:hint="@string/protocol"
|
||||
app:endIconTint="?attr/iconsColor"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu">
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/httpsSpinner"
|
||||
|
@ -25,7 +25,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/draftsListEmpty"
|
||||
android:text="@string/noDataFound"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:gravity="center"
|
||||
android:textSize="20sp"
|
||||
|
83
app/src/main/res/layout/list_most_visited_repos.xml
Normal file
83
app/src/main/res/layout/list_most_visited_repos.xml
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:focusable="true"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/dimen16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/org_info_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="@dimen/dimen24dp"
|
||||
android:layout_height="@dimen/dimen24dp"
|
||||
android:layout_marginStart="@dimen/dimen0dp"
|
||||
android:layout_marginEnd="@dimen/dimen10dp"
|
||||
android:contentDescription="@string/repoContentAvatar"
|
||||
android:src="@drawable/ic_android" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/org_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="@dimen/dimen14sp"
|
||||
tools:text="@string/orgName" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/repo_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/repoName"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="@dimen/dimen16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<View
|
||||
android:id="@+id/spacer_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="@dimen/dimen8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/repo_info_stars_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical|start"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dimen18dp"
|
||||
android:layout_height="@dimen/dimen18dp"
|
||||
android:layout_marginStart="@dimen/dimen0dp"
|
||||
android:layout_marginEnd="@dimen/dimen6dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
app:srcCompat="@drawable/ic_trending"
|
||||
app:tint="?attr/iconsColor" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/most_visited"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="@dimen/dimen14sp"
|
||||
tools:text="@string/repoStars" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -38,6 +38,10 @@
|
||||
android:icon="@drawable/ic_search"
|
||||
android:title="@string/pageTitleExplore" />
|
||||
|
||||
<item android:id="@+id/nav_most_visited"
|
||||
android:icon="@drawable/ic_trending"
|
||||
android:title="@string/navMostVisited" />
|
||||
|
||||
<item android:id="@+id/nav_comments_draft"
|
||||
android:icon="@drawable/ic_drafts"
|
||||
android:title="@string/titleDrafts" />
|
||||
|
@ -9,6 +9,7 @@
|
||||
<dimen name="dimen10dp">10dp</dimen>
|
||||
<dimen name="dimen12dp">12dp</dimen>
|
||||
<dimen name="dimen16dp">16dp</dimen>
|
||||
<dimen name="dimen18dp">18dp</dimen>
|
||||
<dimen name="dimen20dp">20dp</dimen>
|
||||
<dimen name="dimen24dp">24dp</dimen>
|
||||
<dimen name="dimen26dp">26dp</dimen>
|
||||
|
@ -31,6 +31,7 @@
|
||||
<string name="navLogout">Logout</string>
|
||||
<string name="navAdministration">Administration</string>
|
||||
<string name="navMyIssues">My Issues</string>
|
||||
<string name="navMostVisited">Most Visited Repos</string>
|
||||
<!-- menu items -->
|
||||
|
||||
<!-- page titles -->
|
||||
|
Loading…
Reference in New Issue
Block a user