Dashboard view (#1279)

Closes #1231

Closes #1280

Closes #1295

Closes #1298

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1279
Co-authored-by: M M Arif <mmarif@swatian.com>
Co-committed-by: M M Arif <mmarif@swatian.com>
This commit is contained in:
M M Arif 2023-09-19 05:23:43 +00:00 committed by M M Arif
parent ea954503bf
commit d2ff9b8a8a
33 changed files with 1696 additions and 102 deletions

View file

@ -1,4 +1,4 @@
pipeline:
steps:
build:
image: alvrme/alpine-android:android-32-jdk17
commands:

View file

@ -1,4 +1,4 @@
pipeline:
steps:
author-header:
image: qwerty287/woodpecker-regex-check
group: check

View file

@ -6,7 +6,7 @@ depends_on:
run_on: [ success, failure ]
skip_clone: true
pipeline:
steps:
discord:
image: appleboy/drone-discord
settings:

View file

@ -1,4 +1,4 @@
pipeline:
steps:
prepare:
image: alpine
commands:

View file

@ -4,29 +4,27 @@
# GitNex - Android client for Forgejo and Gitea
GitNex is a free/paid, open-source Android client for Git repository management tool Forgejo and Gitea.
GitNex is a free/paid, open-source Android client for the Git repository management tools Forgejo and Gitea.
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. **No trackers are used** and source code is available here for
anyone to audit.
GitNex is licensed under the GPLv3 License. Please refer to the LICENSE file for the full text of the license. **No trackers are used**, and the source code is available here for anyone to audit.
## Downloads
[<img alt='Get it on F-Droid' src='https://codeberg.org/gitnex/GitNex/raw/branch/main/assets/fdroid.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/)
[<img alt='Get it on Google Play' src='https://codeberg.org/gitnex/GitNex/raw/branch/main/assets/google-play.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex.pro)
[<img alt='Download builds and releases' src='https://codeberg.org/gitnex/GitNex/raw/branch/main/assets/apk-badge.png' height="82"/>](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE)
[<img alt='Download builds and releases' src='https://codeberg.org/gitnex/GitNex/raw/branch/main/assets/apk-badge.png' height="82"/>](https://cloud.swatian.com/s/WS4k3seXnmfQppo)
## Note about Forgejo and Gitea version
Please make sure that you are on latest stable release or later for better app experience.
Please make sure that you are on the latest stable release or later for a better app experience.
Check the versions [compatibility page](https://codeberg.org/gitnex/GitNex/wiki/Compatibility) which lists all the supported versions with
compatibility ratio.
Check the version [compatibility page](https://codeberg.org/gitnex/GitNex/wiki/Compatibility), which lists all the supported versions along with their compatibility ratios.
## Build from source
Option 1 - Download the source code, open it in Android Studio and build it there.
Option 1 - Download the source code, open it in Android Studio, and build it there.
Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew assembleFree`.
Option 2 - Open the terminal (Linux) and navigate to the project directory. Then, run `./gradlew assembleFree`.
## Features
@ -48,10 +46,9 @@ Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew assemb
## Translation
Help us translate GitNex to your native language.
Help us translate GitNex into your native language.
We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your language is not listed, please
request [here](https://codeberg.org/gitnex/GitNex/issues) to add it to the project.
We use [Crowdin](https://crowdin.com/project/gitnex) for translations. If your language is not listed, please request to add it to the project [here](https://codeberg.org/gitnex/GitNex/issues).
**Link: https://crowdin.com/project/GitNex**
@ -75,7 +72,7 @@ request [here](https://codeberg.org/gitnex/GitNex/issues) to add it to the proje
## Thanks
Thanks to all the open source libraries, contributors and donators.
Thanks to all the open source libraries, contributors, and donors.
#### Open source libraries

View file

@ -54,16 +54,16 @@ configurations {
}
dependencies {
def lifecycle_version = '2.6.1'
def lifecycle_version = '2.6.2'
def markwon_version = '4.6.2'
def work_version = '2.8.1'
def acra = '5.9.7'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0-alpha01'
implementation 'androidx.compose.material3:material3:1.2.0-alpha03'
implementation 'androidx.compose.material3:material3-window-size-class:1.2.0-alpha03'
implementation 'com.google.android.material:material:1.11.0-alpha02'
implementation 'androidx.compose.material3:material3:1.2.0-alpha07'
implementation 'androidx.compose.material3:material3-window-size-class:1.2.0-alpha07'
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta02'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "androidx.legacy:legacy-support-v4:1.0.0"
@ -111,7 +111,7 @@ dependencies {
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.5.0'
implementation 'androidx.browser:browser:1.6.0'
implementation 'com.google.android.flexbox:flexbox:3.0.0'
implementation('org.codeberg.gitnex:tea4j-autodeploy:65f700d036') {
exclude module: 'org.apache.oltu.oauth2.common'

View file

@ -101,7 +101,7 @@ public class DeepLinksActivity extends BaseActivity {
accountFound = true;
AppUtil.switchToAccount(ctx, userAccount, true);
AppUtil.switchToAccount(ctx, userAccount, false);
break;
}
}

View file

@ -700,6 +700,26 @@ public class IssueDetailActivity extends BaseActivity
viewBinding.issuePrState,
ColorStateList.valueOf(
ctx.getResources().getColor(R.color.iconIssuePrClosedColor, null)));
} else if (issue.getIssue().getTitle().contains("[WIP]")
|| issue.getIssue().getTitle().contains("[wip]")) { // draft
viewBinding.issuePrState.setImageResource(R.drawable.ic_draft);
ImageViewCompat.setImageTintList(
viewBinding.issuePrState,
ColorStateList.valueOf(
ctx.getResources().getColor(R.color.colorWhite, null)));
viewBinding.issuePrState.setBackgroundResource(R.drawable.shape_draft_release);
viewBinding.issuePrState.setPadding(
(int) ctx.getResources().getDimension(R.dimen.dimen4dp),
(int) ctx.getResources().getDimension(R.dimen.dimen2dp),
(int) ctx.getResources().getDimension(R.dimen.dimen4dp),
(int) ctx.getResources().getDimension(R.dimen.dimen2dp));
viewBinding.toolbarTitle.setPadding(
(int) ctx.getResources().getDimension(R.dimen.dimen12dp),
(int) ctx.getResources().getDimension(R.dimen.dimen0dp),
(int) ctx.getResources().getDimension(R.dimen.dimen0dp),
(int) ctx.getResources().getDimension(R.dimen.dimen0dp));
} else { // open
viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request);
@ -1034,7 +1054,7 @@ public class IssueDetailActivity extends BaseActivity
RetrofitClient.getApiInterface(this)
.repoGetPullRequest(repoOwner, repoName, (long) issueIndex)
.enqueue(
new Callback<PullRequest>() {
new Callback<>() {
@Override
public void onResponse(

View file

@ -639,7 +639,9 @@ public class LoginActivity extends BaseActivity {
final String credential = Credentials.basic(loginUid, loginPass, StandardCharsets.UTF_8);
CreateAccessTokenOption createUserToken = new CreateAccessTokenOption().name(tokenName);
if (giteaVersion.higherOrEqual("1.19.0")) {
if (giteaVersion.higherOrEqual("1.20.0")) {
createUserToken.addScopesItem("all");
} else if (giteaVersion.less("1.20.0") && (giteaVersion.higherOrEqual("1.19.0"))) {
createUserToken.addScopesItem("all");
createUserToken.addScopesItem("sudo");
}

View file

@ -39,6 +39,7 @@ import org.mian.gitnex.databinding.ActivityMainBinding;
import org.mian.gitnex.fragments.AdministrationFragment;
import org.mian.gitnex.fragments.BottomSheetDraftsFragment;
import org.mian.gitnex.fragments.BottomSheetMyIssuesFilterFragment;
import org.mian.gitnex.fragments.DashboardFragment;
import org.mian.gitnex.fragments.DraftsFragment;
import org.mian.gitnex.fragments.ExploreFragment;
import org.mian.gitnex.fragments.MostVisitedReposFragment;
@ -150,6 +151,8 @@ public class MainActivity extends BaseActivity
toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration));
} else if (fragmentById instanceof MyIssuesFragment) {
toolbarTitle.setText(getResources().getString(R.string.navMyIssues));
} else if (fragmentById instanceof DashboardFragment) {
toolbarTitle.setText(getResources().getString(R.string.dashboard));
}
getNotificationsCount();
@ -161,6 +164,11 @@ public class MainActivity extends BaseActivity
Menu menu = navigationView.getMenu();
navNotifications = menu.findItem(R.id.nav_notifications);
MenuItem navDashboard = menu.findItem(R.id.nav_dashboard);
navDashboard.getActionView().findViewById(R.id.betaBadge).setVisibility(View.VISIBLE);
TextView dashboardBetaView = navDashboard.getActionView().findViewById(R.id.betaBadge);
dashboardBetaView.setText(R.string.beta);
navigationView
.getViewTreeObserver()
@ -296,6 +304,10 @@ public class MainActivity extends BaseActivity
if (getAccount().requiresVersion("1.14.0")) {
navigationView.getMenu().findItem(R.id.nav_my_issues).setVisible(true);
}
if (getAccount().requiresVersion("1.20.0")) {
navigationView.getMenu().findItem(R.id.nav_dashboard).setVisible(true);
}
}
@Override
@ -489,7 +501,14 @@ public class MainActivity extends BaseActivity
.commit();
navigationView.setCheckedItem(R.id.nav_notes);
break;
case 11:
toolbarTitle.setText(getResources().getString(R.string.dashboard));
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, new DashboardFragment())
.commit();
navigationView.setCheckedItem(R.id.nav_dashboard);
break;
default:
toolbarTitle.setText(getResources().getString(R.string.navMyRepos));
getSupportFragmentManager()
@ -710,6 +729,13 @@ public class MainActivity extends BaseActivity
.beginTransaction()
.replace(R.id.fragment_container, new NotesFragment())
.commit();
} else if (id == R.id.nav_dashboard) {
toolbarTitle.setText(getResources().getString(R.string.dashboard));
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, new DashboardFragment())
.commit();
}
drawer.closeDrawer(GravityCompat.START);

View file

@ -1,11 +1,12 @@
package org.mian.gitnex.activities;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.view.inputmethod.EditorInfo;
import androidx.appcompat.widget.SearchView;
import androidx.lifecycle.ViewModelProvider;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.UserGridAdapter;
@ -18,37 +19,29 @@ import org.mian.gitnex.viewmodels.RepoStargazersViewModel;
*/
public class RepoStargazersActivity extends BaseActivity {
private TextView noDataStargazers;
private View.OnClickListener onClickListener;
private UserGridAdapter adapter;
private GridView mGridView;
private ProgressBar mProgressBar;
private RepositoryContext repository;
private ActivityRepoStargazersBinding activityRepoStargazersBinding;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityRepoStargazersBinding activityRepoStargazersBinding =
ActivityRepoStargazersBinding.inflate(getLayoutInflater());
activityRepoStargazersBinding = ActivityRepoStargazersBinding.inflate(getLayoutInflater());
setContentView(activityRepoStargazersBinding.getRoot());
ImageView closeActivity = activityRepoStargazersBinding.close;
TextView toolbarTitle = activityRepoStargazersBinding.toolbarTitle;
noDataStargazers = activityRepoStargazersBinding.noDataStargazers;
mGridView = activityRepoStargazersBinding.gridView;
mProgressBar = activityRepoStargazersBinding.progressBar;
setSupportActionBar(activityRepoStargazersBinding.toolbar);
repository = RepositoryContext.fromIntent(getIntent());
final String repoOwner = repository.getOwner();
final String repoName = repository.getName();
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
activityRepoStargazersBinding.close.setOnClickListener(onClickListener);
toolbarTitle.setText(R.string.repoStargazersInMenu);
activityRepoStargazersBinding.toolbarTitle.setText(R.string.repoStargazersInMenu);
fetchDataAsync(repoOwner, repoName);
}
@ -67,16 +60,18 @@ public class RepoStargazersActivity extends BaseActivity {
if (adapter.getCount() > 0) {
mGridView.setAdapter(adapter);
noDataStargazers.setVisibility(View.GONE);
activityRepoStargazersBinding.gridView.setAdapter(adapter);
activityRepoStargazersBinding.noDataStargazers.setVisibility(
View.GONE);
} else {
adapter.notifyDataSetChanged();
mGridView.setAdapter(adapter);
noDataStargazers.setVisibility(View.VISIBLE);
activityRepoStargazersBinding.gridView.setAdapter(adapter);
activityRepoStargazersBinding.noDataStargazers.setVisibility(
View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
activityRepoStargazersBinding.progressBar.setVisibility(View.GONE);
});
}
@ -90,4 +85,36 @@ public class RepoStargazersActivity extends BaseActivity {
super.onResume();
repository.checkAccountSwitch(this);
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
if (activityRepoStargazersBinding.gridView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
return true;
}
}

View file

@ -1,11 +1,12 @@
package org.mian.gitnex.activities;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.view.inputmethod.EditorInfo;
import androidx.appcompat.widget.SearchView;
import androidx.lifecycle.ViewModelProvider;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.UserGridAdapter;
@ -18,12 +19,9 @@ import org.mian.gitnex.viewmodels.RepoWatchersViewModel;
*/
public class RepoWatchersActivity extends BaseActivity {
private TextView noDataWatchers;
private View.OnClickListener onClickListener;
private UserGridAdapter adapter;
private GridView mGridView;
private ProgressBar mProgressBar;
private ActivityRepoWatchersBinding activityRepoWatchersBinding;
private RepositoryContext repository;
@Override
@ -31,24 +29,19 @@ public class RepoWatchersActivity extends BaseActivity {
super.onCreate(savedInstanceState);
ActivityRepoWatchersBinding activityRepoWatchersBinding =
ActivityRepoWatchersBinding.inflate(getLayoutInflater());
activityRepoWatchersBinding = ActivityRepoWatchersBinding.inflate(getLayoutInflater());
setContentView(activityRepoWatchersBinding.getRoot());
ImageView closeActivity = activityRepoWatchersBinding.close;
TextView toolbarTitle = activityRepoWatchersBinding.toolbarTitle;
noDataWatchers = activityRepoWatchersBinding.noDataWatchers;
mGridView = activityRepoWatchersBinding.gridView;
mProgressBar = activityRepoWatchersBinding.progressBar;
setSupportActionBar(activityRepoWatchersBinding.toolbar);
repository = RepositoryContext.fromIntent(getIntent());
final String repoOwner = repository.getOwner();
final String repoName = repository.getName();
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
activityRepoWatchersBinding.close.setOnClickListener(onClickListener);
toolbarTitle.setText(R.string.repoWatchersInMenu);
activityRepoWatchersBinding.toolbarTitle.setText(R.string.repoWatchersInMenu);
fetchDataAsync(repoOwner, repoName);
}
@ -67,16 +60,17 @@ public class RepoWatchersActivity extends BaseActivity {
if (adapter.getCount() > 0) {
mGridView.setAdapter(adapter);
noDataWatchers.setVisibility(View.GONE);
activityRepoWatchersBinding.gridView.setAdapter(adapter);
activityRepoWatchersBinding.noDataWatchers.setVisibility(View.GONE);
} else {
adapter.notifyDataSetChanged();
mGridView.setAdapter(adapter);
noDataWatchers.setVisibility(View.VISIBLE);
activityRepoWatchersBinding.gridView.setAdapter(adapter);
activityRepoWatchersBinding.noDataWatchers.setVisibility(
View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
activityRepoWatchersBinding.progressBar.setVisibility(View.GONE);
});
}
@ -90,4 +84,35 @@ public class RepoWatchersActivity extends BaseActivity {
super.onResume();
repository.checkAccountSwitch(this);
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(
new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
if (activityRepoWatchersBinding.gridView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
return true;
}
}

View file

@ -93,6 +93,9 @@ public class SettingsGeneralActivity extends BaseActivity {
} else if (homeScreenSelectedChoice == 10) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.navNotes));
} else if (homeScreenSelectedChoice == 11) {
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.dashboard));
}
viewBinding.homeScreenFrame.setOnClickListener(

View file

@ -0,0 +1,892 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.text.HtmlCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.vdurmont.emoji.EmojiParser;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.gitnex.tea4j.v2.models.Activity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
/**
* @author M M Arif
*/
public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
TinyDB tinyDb;
private List<Activity> activityList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
private Intent intent;
public boolean isUserOrg = false;
public DashboardAdapter(List<Activity> dataList, Context ctx) {
this.context = ctx;
this.activityList = dataList;
this.tinyDb = TinyDB.getInstance(ctx);
}
@NonNull @Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
return new DashboardAdapter.DashboardHolder(
inflater.inflate(R.layout.list_dashboard_activity, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (position >= getItemCount() - 1
&& isMoreDataAvailable
&& !isLoading
&& loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
((DashboardAdapter.DashboardHolder) holder).bindData(activityList.get(position));
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getItemCount() {
return activityList.size();
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
if (!isMoreDataAvailable) {
loadMoreListener.onLoadFinished();
}
}
@SuppressLint("NotifyDataSetChanged")
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
loadMoreListener.onLoadFinished();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Activity> list) {
activityList = list;
notifyDataChanged();
}
public interface OnLoadMoreListener {
void onLoadMore();
void onLoadFinished();
}
class DashboardHolder extends RecyclerView.ViewHolder {
private final ImageView userAvatar;
private final TextView typeDetails;
private final TextView createdTime;
private final ImageView typeIcon;
private final TextView dashText;
private final LinearLayout dashTextFrame;
private Activity activityObject;
DashboardHolder(View itemView) {
super(itemView);
userAvatar = itemView.findViewById(R.id.user_avatar);
typeDetails = itemView.findViewById(R.id.type_details);
typeIcon = itemView.findViewById(R.id.type_icon);
createdTime = itemView.findViewById(R.id.created_time);
dashText = itemView.findViewById(R.id.text);
dashTextFrame = itemView.findViewById(R.id.dash_text_frame);
new Handler()
.postDelayed(
() -> {
if (!AppUtil.checkGhostUsers(
activityObject.getActUser().getLogin())) {
userAvatar.setOnLongClickListener(
loginId -> {
AppUtil.copyToClipboard(
context,
activityObject.getActUser().getLogin(),
context.getString(
R.string.copyLoginIdToClipBoard,
activityObject
.getActUser()
.getLogin()));
return true;
});
userAvatar.setOnClickListener(
v -> {
intent = new Intent(context, ProfileActivity.class);
intent.putExtra(
"username",
activityObject.getActUser().getLogin());
context.startActivity(intent);
});
}
if (activityObject.getOpType().equalsIgnoreCase("create_repo")
|| activityObject
.getOpType()
.equalsIgnoreCase("rename_repo")
|| activityObject.getOpType().equalsIgnoreCase("star_repo")
|| activityObject
.getOpType()
.equalsIgnoreCase("transfer_repo")) {
itemView.setOnClickListener(
v -> {
Context context = v.getContext();
RepositoryContext repo =
new RepositoryContext(
activityObject.getRepo(), context);
repo.saveToDB(context);
Intent intent =
repo.getIntent(
context, RepoDetailActivity.class);
if (isUserOrg) {
intent.putExtra("openedFromUserOrg", true);
}
context.startActivity(intent);
});
}
if (activityObject.getOpType().equalsIgnoreCase("create_issue")
|| activityObject
.getOpType()
.equalsIgnoreCase("comment_issue")
|| activityObject
.getOpType()
.equalsIgnoreCase("close_issue")
|| activityObject
.getOpType()
.equalsIgnoreCase("reopen_issue")) {
String[] parts =
activityObject.getRepo().getFullName().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
RepositoryContext repo =
new RepositoryContext(repoOwner, repoName, context);
String[] contentParts =
activityObject.getContent().split("\\|");
String id = contentParts[0];
Intent intentIssueDetail =
new IssueContext(repo, Integer.parseInt(id), "open")
.getIntent(context, IssueDetailActivity.class);
intentIssueDetail.putExtra("openedFromLink", "true");
itemView.setOnClickListener(
v -> {
repo.saveToDB(context);
context.startActivity(intentIssueDetail);
});
}
if (activityObject
.getOpType()
.equalsIgnoreCase("create_pull_request")
|| activityObject
.getOpType()
.equalsIgnoreCase("close_pull_request")
|| activityObject
.getOpType()
.equalsIgnoreCase("reopen_pull_request")
|| activityObject
.getOpType()
.equalsIgnoreCase("approve_pull_request")
|| activityObject
.getOpType()
.equalsIgnoreCase("reject_pull_request")
|| activityObject
.getOpType()
.equalsIgnoreCase("comment_pull")
|| activityObject
.getOpType()
.equalsIgnoreCase("auto_merge_pull_request")
|| activityObject
.getOpType()
.equalsIgnoreCase("merge_pull_request")) {
String[] parts =
activityObject.getRepo().getFullName().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
RepositoryContext repo =
new RepositoryContext(repoOwner, repoName, context);
String[] contentParts =
activityObject.getContent().split("\\|");
String id = contentParts[0];
Intent intentIssueDetail =
new IssueContext(repo, Integer.parseInt(id), "open")
.getIntent(context, IssueDetailActivity.class);
intentIssueDetail.putExtra("openedFromLink", "true");
itemView.setOnClickListener(
v -> {
repo.saveToDB(context);
context.startActivity(intentIssueDetail);
});
}
if (activityObject.getOpType().equalsIgnoreCase("commit_repo")) {
if (activityObject.getContent().isEmpty()) {
itemView.setOnClickListener(
v -> {
RepositoryContext repo =
new RepositoryContext(
activityObject.getRepo(),
context);
Intent repoIntent =
new Intent(
context,
RepoDetailActivity.class);
repoIntent.putExtra("goToSection", "yes");
repoIntent.putExtra(
"goToSectionType", "commitsList");
repoIntent.putExtra(
"branchName",
activityObject
.getRefName()
.substring(
activityObject
.getRefName()
.lastIndexOf(
"/")
+ 1)
.trim());
repo.saveToDB(context);
repoIntent.putExtra(
RepositoryContext.INTENT_EXTRA, repo);
context.startActivity(repoIntent);
});
}
}
if (activityObject.getOpType().equalsIgnoreCase("publish_release")
|| activityObject
.getOpType()
.equalsIgnoreCase("push_tag")) {
itemView.setOnClickListener(
v -> {
RepositoryContext repo =
new RepositoryContext(
activityObject.getRepo(), context);
Intent repoIntent =
new Intent(
context, RepoDetailActivity.class);
repoIntent.putExtra("goToSection", "yes");
repoIntent.putExtra("goToSectionType", "releases");
repoIntent.putExtra(
"releaseTagName",
activityObject
.getRefName()
.substring(
activityObject
.getRefName()
.lastIndexOf(
"/")
+ 1)
.trim());
repo.saveToDB(context);
repoIntent.putExtra(
RepositoryContext.INTENT_EXTRA, repo);
context.startActivity(repoIntent);
});
}
},
200);
}
void bindData(Activity activity) {
this.activityObject = activity;
Locale locale = context.getResources().getConfiguration().locale;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context)
.get()
.load(activity.getActUser().getAvatarUrl())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(userAvatar);
String username =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getActUser().getLogin()
+ "</font>";
String headerString = "";
String typeString = "";
if (activity.getOpType().contains("repo")) {
if (activity.getOpType().equalsIgnoreCase("create_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "created repository";
typeIcon.setImageResource(R.drawable.ic_repo);
} else if (activity.getOpType().equalsIgnoreCase("rename_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "renamed repository from " + activity.getContent() + " to";
typeIcon.setImageResource(R.drawable.ic_repo);
} else if (activity.getOpType().equalsIgnoreCase("star_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "starred";
typeIcon.setImageResource(R.drawable.ic_star);
} else if (activity.getOpType().equalsIgnoreCase("transfer_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
typeString = "transferred repository " + activity.getContent() + " to";
typeIcon.setImageResource(R.drawable.ic_arrow_up);
} else if (activity.getOpType().equalsIgnoreCase("commit_repo")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
if (activity.getContent().isEmpty()) {
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(
activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "created branch " + branch + " in";
} else {
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(
activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "pushed to " + branch + " at";
JSONObject commitsObj = null;
try {
commitsObj = new JSONObject(activity.getContent());
} catch (JSONException ignored) {
}
JSONArray commitsShaArray = null;
try {
commitsShaArray =
Objects.requireNonNull(commitsObj).getJSONArray("Commits");
} catch (JSONException ignored) {
}
dashTextFrame.setVisibility(View.VISIBLE);
dashTextFrame.setOrientation(LinearLayout.VERTICAL);
dashTextFrame.removeAllViews();
for (int i = 0; i < Objects.requireNonNull(commitsShaArray).length(); i++) {
try {
String timelineCommits =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(),
R.color.lightBlue,
null)
+ "'>"
+ StringUtils.substring(
String.valueOf(commitsShaArray.get(i)),
9,
19)
+ "</font>";
TextView dynamicCommitTv = new TextView(context);
dynamicCommitTv.setId(View.generateViewId());
dynamicCommitTv.setText(
HtmlCompat.fromHtml(
timelineCommits, HtmlCompat.FROM_HTML_MODE_LEGACY));
JSONObject sha1Obj = null;
try {
sha1Obj = (JSONObject) commitsShaArray.get(i);
} catch (JSONException ignored) {
}
JSONObject finalSha1Obj = sha1Obj;
dynamicCommitTv.setOnClickListener(
v14 -> {
RepositoryContext repo =
new RepositoryContext(
activity.getRepo(), context);
Intent repoIntent =
new Intent(context, RepoDetailActivity.class);
repoIntent.putExtra("goToSection", "yes");
repoIntent.putExtra("goToSectionType", "commit");
try {
assert finalSha1Obj != null;
repoIntent.putExtra(
"sha", (String) finalSha1Obj.get("Sha1"));
} catch (JSONException ignored) {
}
repo.saveToDB(context);
repoIntent.putExtra(
RepositoryContext.INTENT_EXTRA, repo);
context.startActivity(repoIntent);
});
dashTextFrame.setOrientation(LinearLayout.VERTICAL);
dashTextFrame.addView(dynamicCommitTv);
} catch (JSONException ignored) {
}
}
}
typeIcon.setImageResource(R.drawable.ic_commit);
}
} else if (activity.getOpType().contains("issue")) {
String id;
String content;
String[] contentParts = activity.getContent().split("\\|");
if (contentParts.length > 1) {
id = contentParts[0];
content = contentParts[1];
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
} else {
id = contentParts[0];
}
if (activity.getOpType().equalsIgnoreCase("create_issue")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "opened issue";
typeIcon.setImageResource(R.drawable.ic_issue);
} else if (activity.getOpType().equalsIgnoreCase("comment_issue")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "commented on issue";
typeIcon.setImageResource(R.drawable.ic_comment);
} else if (activity.getOpType().equalsIgnoreCase("close_issue")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "closed issue";
typeIcon.setImageResource(R.drawable.ic_issue_closed);
} else if (activity.getOpType().equalsIgnoreCase("reopen_issue")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "reopened issue";
typeIcon.setImageResource(R.drawable.ic_reopen);
}
} else if (activity.getOpType().contains("pull")) {
String id;
String content;
String[] contentParts = activity.getContent().split("\\|");
if (contentParts.length > 1) {
id = contentParts[0];
content = contentParts[1];
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
} else {
id = contentParts[0];
}
if (activity.getOpType().equalsIgnoreCase("create_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "created pull request";
typeIcon.setImageResource(R.drawable.ic_pull_request);
} else if (activity.getOpType().equalsIgnoreCase("close_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "closed pull request";
typeIcon.setImageResource(R.drawable.ic_issue_closed);
} else if (activity.getOpType().equalsIgnoreCase("reopen_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "reopened pull request";
typeIcon.setImageResource(R.drawable.ic_reopen);
} else if (activity.getOpType().equalsIgnoreCase("merge_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "merged pull request";
typeIcon.setImageResource(R.drawable.ic_pull_request);
} else if (activity.getOpType().equalsIgnoreCase("approve_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "approved";
typeIcon.setImageResource(R.drawable.ic_done);
} else if (activity.getOpType().equalsIgnoreCase("reject_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "suggested changes for";
typeIcon.setImageResource(R.drawable.ic_diff);
} else if (activity.getOpType().equalsIgnoreCase("comment_pull")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "commented on pull request";
typeIcon.setImageResource(R.drawable.ic_comment);
} else if (activity.getOpType().equalsIgnoreCase("auto_merge_pull_request")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ context.getResources().getString(R.string.hash)
+ id
+ "</font>";
typeString = "automatically merged pull request";
typeIcon.setImageResource(R.drawable.ic_issue_closed);
}
} else if (activity.getOpType().contains("branch")) {
String content;
String[] contentParts = activity.getContent().split("\\|");
if (contentParts.length > 1) {
content = contentParts[1];
dashTextFrame.setVisibility(View.VISIBLE);
dashText.setText(EmojiParser.parseToUnicode(content));
}
if (activity.getOpType().equalsIgnoreCase("delete_branch")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "deleted branch " + branch + " at";
typeIcon.setImageResource(R.drawable.ic_commit);
}
} else if (activity.getOpType().contains("tag")) {
if (activity.getOpType().equalsIgnoreCase("push_tag")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRefName()
.substring(activity.getRefName().lastIndexOf("/") + 1)
.trim()
+ "</font>";
typeString = "pushed tag " + branch + " to";
typeIcon.setImageResource(R.drawable.ic_commit);
} else if (activity.getOpType().equalsIgnoreCase("delete_tag")) {
headerString =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'>"
+ activity.getRepo().getFullName()
+ "</font>";
String branch =
"<font color='"
+ ResourcesCompat.getColor(
context.getResources(), R.color.lightGray, null)
+ "'