Compare commits

...

59 Commits

Author SHA1 Message Date
71d7f543a6 Merge branch 'main' into 7-assign-team-to-repo 2021-08-30 00:22:07 +02:00
244dc12fc3 Kick start 4.1.0 (#966)
As title

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/966
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-08-24 21:29:34 +02:00
8ea7e470c5 Prepare release 4.0.0 (#963)
Closes #956

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/963
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-08-16 09:04:43 +02:00
77edf450c6 Translation updates (#962)
As title

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/962
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-08-16 08:37:23 +02:00
e0ff35d530 [BUG] Releases should come before release tag (#958)
As title

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/958
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-08-15 19:36:12 +02:00
f88a2df749 Enable user link handler and fix click on users in admin section (#957)
addresses #955
This pr does the following:
1. enables the users link handler
2. it allows clicks on the full `itemView` in the admin users section (related to https://codeberg.org/gitnex/GitNex/pulls/931#issuecomment-211296)

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/957
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-08-11 14:47:31 +02:00
bb392fb639 Fix biometric bug in recent apps (#940)
Closes #930

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: 6543 <6543@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/940
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-08-03 09:41:40 +02:00
6a6ecd251a Merge branch 'main' into 7-assign-team-to-repo 2021-08-02 20:08:41 +02:00
1693acaa70 User profile view (#931)
Closes #881

Please suggest on current data shown as some may be related to personal(email etc), but at this moment we have not much to show either. So sticking to it is my view on this.

I will extend the taps on profile images once we agree what to show.

@gitnex/Code-Managers

- [x] Detail
- [x] Repositories
- [x] Starred Repos
- [x] Followers
- [x] Following
- [x] Tap on all profile images
- [x] Organizations

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: opyale <opyale@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/931
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-08-02 20:04:33 +02:00
1e8c8efd6b Fix md rendering after editing file (#954)
### Describe what your pull request does and which issue you’re targeting
fixes #951
and you can review/merge it

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/954
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-08-02 19:22:49 +02:00
5544ae4248 Add option to change times that are used to switch to light/dark theme (#932)
### Describe what your pull request does and which issue you’re targeting
Closes #928

This allows to select the time to switch between themes. The mentioned color/contrast problem with the time selection isn't fixed. I also simplified the settings code (0fe854fd49). And with [this](a590f5bc4c) GitNex hides the two options to change the time if your theme isn't `Auto (Light/Dark)` or `Auto (Retro/Dark)`. I could apply this also to the notifications settings, that means that the advanced settings for notifications (polling delay, light...) are hidden if the notifications aren't enabled.

this is ready to review/merge
<br><br>

<!-- Make sure you are targeting the "main" branch, pull requests on release branches are only allowed for bug fixes. -->

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/932
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-08-02 18:59:30 +02:00
36f20bb1aa Add more link handlers (#948)
I can't implement every handler correctly, if there are no views that display them (e.g. a single milestone or release)

- [X] Organization #915
- [X] Milestones
- [X] Milestone
- [X] New milestone
- [X] Files
- [ ] Lines *currently opens file viewer*
- [X] Folders/directory's
- [X] Branches list
- [X] Branches
- [X] Releases
- [X] Release
- [X] new Release
- [X] Labels
- [X] Explore (orgs/repos)
- [X] Commits list
- [X] New issue
- [ ] Issue comments *currently opens the issue details*
- [X] New PR
- [ ] PR comments *currently opens the PR details*
- [X] PR diff
- [X] Your user profile
- [ ] User profiles *blocked by #931*
- [X] Gitea administration
- [X] Notifications
- [X] repository settings (only for repo admins)
- [X] Login screen

Commits: not possible, Gitea's API doesn't provide enough information to view the correct branch in the list and/or to display the diff.

Closes #918
Closes #915

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/948
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-07-23 17:41:19 +02:00
0e696eb46f Allow navigating from issue to repo (#937)
Allow navigating from issue opend by link to go back to repo

Closes #747

Co-authored-by: qwerty287 <ndev@web.de>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/937
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-07-09 17:36:59 +02:00
2b3b0fbe0f Fix Gitea version check (#945)
Closes #941

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/945
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-06-20 17:26:13 +02:00
f96827488b Hide mark as read button when no notifications are available (#938)
Closes #847

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/938
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-06-17 22:00:33 +02:00
8d0df59bfe Fixing CI (#936)
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/936
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: opyale <opyale@noreply.codeberg.org>
Co-committed-by: opyale <opyale@noreply.codeberg.org>
2021-06-13 19:38:28 +02:00
d567a012d8 Add option to delete branch after pr got merged (#929)
### Describe what your pull request does and which issue you’re targeting
<!-- Create a new issue, if it doesn't exist yet -->
Closes #860
<br><br>

<!-- Make sure you are targeting the "main" branch, pull requests on release branches are only allowed for bug fixes. -->

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/929
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-06-10 18:03:52 +02:00
0fc845e058 Small improvements to About dialog (#927)
As title

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/927
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-06-06 21:15:32 +02:00
b97fa45b18 Move settings arrays to resources (#924)
### Describe what your pull request does and which issue you’re targeting
<!-- Create a new issue, if it doesn't exist yet -->
Closes #920
<br><br>

<!-- Make sure you are targeting the "main" branch, pull requests on release branches are only allowed for bug fixes. -->

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/924
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-06-05 16:07:05 +02:00
d458d60122 Add ScrollViews to DeepLink view (#923)
### Describe what your pull request does and which issue you’re targeting
<!-- Create a new issue, if it doesn't exist yet -->
Closes #921
<br><br>

<!-- Make sure you are targeting the "main" branch, pull requests on release branches are only allowed for bug fixes. -->

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/923
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-05-30 20:57:02 +02:00
881aad5f2d New About App dialog, improvements and fixes (#922)
Possible fix for #917

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/922
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-05-30 19:28:14 +02:00
547e7c705d Use language provided by system (#914)
Pr tries to implement support for usage of system language.

Currently work in progress.

- [x] add option to use system language
- [x] use this by default
- [x] fix other usages of db value "locale"
- [X] fix usages of `Locale.getDefault()` (except [here](https://codeberg.org/gitnex/GitNex/src/branch/main/app/src/main/java/org/mian/gitnex/helpers/ssl/MemorizingTrustManager.java#L429))
- [ ] get language list programmaticaly
- [X] localize language names (related to #101)
- [X] move languages list to ~~Hashmap~~ TreeMap (it seems that HashMaps sort everything in a random order)

I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).
<br>
Fixes #899

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/914
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-05-29 18:21:48 +02:00
cc70fe9a68 Make markdown links clickable (#916)
Pr makes links in markdown clickable.

Closes #797
<br><br>

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/916
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-05-28 21:23:07 +02:00
3b3b0ada2f Public organizations (#906)
Closes #903

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: opyale <opyale@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/906
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-05-25 22:39:06 +02:00
a9f1010add Improve reply comment title (#912)
Closes #910

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/912
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-05-25 21:26:21 +02:00
c8872ade9f Fix typo (#911)
Fixes "Crodwin" typo

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/911
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-05-25 14:35:30 +02:00
960eaa1cf9 Fix missing docker image. (#909)
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/909
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: opyale <opyale@noreply.codeberg.org>
Co-committed-by: opyale <opyale@noreply.codeberg.org>
2021-05-24 14:42:08 +02:00
224ead33bf Fix going back from about fragment (#908)
### Describe what your pull request does and which issue you’re targeting
This PR fixes the problem that you can't go back from the "About" section in the settings and it changes the action bar behaviour of the about fragment to keep the design consistent (see below).

The activity action bar is hidden [here](82ffeefdc4/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java (L35)), as the about fragment uses it's own (in my implementation) to keep the design consistent (currently, all sections of the settings are own activitys and their action bar has a close button, except the about section). If you don't like this, I can remove it, but currently, it doesn't look nice integrated.

Closes #905

- [X] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [X] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [X] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/908
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
2021-05-23 22:29:11 +02:00
1dd615fcae Moving to 'main' branch (#902)
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/902
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-authored-by: opyale <opyale@noreply.codeberg.org>
Co-committed-by: opyale <opyale@noreply.codeberg.org>
2021-05-01 20:30:44 +02:00
36808b1dbb Merge branch 'main' into 7-assign-team-to-repo 2021-05-01 19:45:45 +02:00
8741074906 UI improvements and update translation file (#900)
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/900
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@noreply.codeberg.org>
Co-committed-by: M M Arif <mmarif@noreply.codeberg.org>
2021-05-01 00:01:22 +02:00
23b8301fbf Fix repo desc in recyclerview (#896)
fixes and clean up

Use Authorization.get()

minor  fixes

Fix repo desc in recyclerview

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: opyale <opyale@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/896
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-Authored-By: M M Arif <mmarif@noreply.codeberg.org>
Co-Committed-By: M M Arif <mmarif@noreply.codeberg.org>
2021-04-15 17:05:56 +02:00
cd902ff1ca Merge branch 'master' into 7-assign-team-to-repo 2021-04-13 20:57:48 +02:00
d72f097012 Implement multi-session notification polling and additional improvements/refactors/cleanups/fixes (#875)
Merge branch 'master' of https://codeberg.org/gitnex/GitNex into notifications-performance-improvements

 Conflicts:
	app/src/main/java/org/mian/gitnex/adapters/DraftsAdapter.java
	app/src/main/java/org/mian/gitnex/adapters/NotificationsAdapter.java
	app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java
	app/src/main/java/org/mian/gitnex/adapters/UserAccountsNavAdapter.java
	app/src/main/res/layout/bottom_sheet_repository_in_list.xml
	app/src/main/res/layout/list_files.xml

Merge branch 'master' into notifications-performance-improvements

Merge branch 'master' into notifications-performance-improvements

Merge branch 'master' of https://codeberg.org/gitnex/GitNex into notifications-performance-improvements

 Conflicts:
	app/src/main/res/values-it/strings.xml

Add ripple effect to buttons.

Run syntax highlighting on separate thread. (#859)

Initial commit.

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/875
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-Authored-By: opyale <opyale@noreply.codeberg.org>
Co-Committed-By: opyale <opyale@noreply.codeberg.org>
2021-04-13 20:56:50 +02:00
9d3cd49d23 New UI for multiple screens (#894)
clean up

Another round of ui improvements and some refactors

Minor improvements.

Hide user accounts frame while list is loading

Remove unnecessary attribute

Minor improvements.

Define avatar size in lists globally.

Improvemnts to some ui elements

Improve layout of organizations and repositories.

Update the UI across most of the screens

Refactor org UI

clean up repo layout

Add archived msg instead of label

Redesign repos UI

Move archived to repo detail screen

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: opyale <opyale@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/894
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-Authored-By: M M Arif <mmarif@noreply.codeberg.org>
Co-Committed-By: M M Arif <mmarif@noreply.codeberg.org>
2021-04-13 16:19:42 +02:00
e8f938bdb0 Merge branch 'master' into 7-assign-team-to-repo 2021-04-10 21:43:33 +02:00
27a4bab73c Remove "Android PdfViewer" library (#893)
Remove "Android PdfViewer" library

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/893
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-Authored-By: opyale <opyale@noreply.codeberg.org>
Co-Committed-By: opyale <opyale@noreply.codeberg.org>
2021-04-10 21:16:07 +02:00
8312983ed3 Merge branch 'master' into 7-assign-team-to-repo 2021-04-10 20:37:56 +02:00
69a5f00771 Add private icon in repo detail toolbar, switch to if by gradle lint (#892)
Hide repoTypeToolbar by default.

Merge branch 'master' into add-repo-status-icon

Add private icon in repo detail toolbar, switch to if by gradle lint

Co-authored-by: opyale <opyale@noreply.codeberg.org>
Co-authored-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/892
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-Authored-By: M M Arif <mmarif@noreply.codeberg.org>
Co-Committed-By: M M Arif <mmarif@noreply.codeberg.org>
2021-04-10 20:29:21 +02:00
8104889bf6 Improve markdown rendering performance (#890)
Use object pooling with up to 45 threads for improved parallelization in markdown rendering.

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/890
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-Authored-By: opyale <opyale@noreply.codeberg.org>
Co-Committed-By: opyale <opyale@noreply.codeberg.org>
2021-04-10 19:54:05 +02:00
bd3e6ff20a [Frontport] Tr updates (#871)
Tr updates

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/871
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Co-Authored-By: M M Arif <mmarif@noreply.codeberg.org>
Co-Committed-By: M M Arif <mmarif@noreply.codeberg.org>
2021-04-01 12:02:35 +02:00
a384128c8f Launch Toasts on UI thread. (#868)
Launch Toasts on UI thread.

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/868
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-Authored-By: opyale <opyale@noreply.codeberg.org>
Co-Committed-By: opyale <opyale@noreply.codeberg.org>
2021-03-31 19:36:11 +02:00
a47be21017 Merge branch 'master' into 7-assign-team-to-repo 2021-03-31 19:24:12 +02:00
4b140f3195 Fixing crash on ProfileFragment (#865)
Fixing crash on ProfileFragment

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/865
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
Co-Authored-By: opyale <opyale@noreply.codeberg.org>
Co-Committed-By: opyale <opyale@noreply.codeberg.org>
2021-03-31 18:36:47 +02:00
4ccc66b04e Fix lock icon for repos (#864)
Fix lock icon for repos

Fix layout

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/864
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-Authored-By: M M Arif <mmarif@noreply.codeberg.org>
Co-Committed-By: M M Arif <mmarif@noreply.codeberg.org>
2021-03-31 18:28:18 +02:00
7c6247782b [Frontport] Fix Acra and workmanager, update gradle (#856)
Move acra to application

[Frontport] Fix Acra and workmanager errors, update gradle

Fix ACRA and workmanager errors

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/856
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Co-Authored-By: M M Arif <mmarif@noreply.codeberg.org>
Co-Committed-By: M M Arif <mmarif@noreply.codeberg.org>
2021-03-30 16:31:39 +02:00
3e5fca4f52 Fall back to plain text if syntax highlighting fails. (#854)
[HotFix] Fall back to plain text if syntax highlighting fails.

upstream issue: https://github.com/noties/Prism4j/issues/8

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/854
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Co-Authored-By: opyale <opyale@noreply.codeberg.org>
Co-Committed-By: opyale <opyale@noreply.codeberg.org>
2021-03-30 00:31:26 +02:00
69b7984d85 Merge branch 'master' into 7-assign-team-to-repo 2021-03-19 14:48:26 +01:00
26b623a35b Merge branch 'master' into 7-assign-team-to-repo 2021-03-10 10:30:50 +01:00
df3e1b9940 Merge branch 'master' into 7-assign-team-to-repo 2021-02-04 10:40:33 +01:00
1d15f9b1d2 Merge branch 'master' into 7-assign-team-to-repo 2021-02-02 01:20:24 +01:00
1e838031e1 Merge branch 'master' into 7-assign-team-to-repo 2021-01-26 23:52:29 +01:00
c6ebca8a08 Merge branch 'master' into 7-assign-team-to-repo 2021-01-26 18:57:15 +01:00
5b92be3a28 Merge branch 'master' into 7-assign-team-to-repo 2021-01-14 18:43:23 +01:00
fbd92eb06b Merge branch 'master' into 7-assign-team-to-repo 2020-10-12 23:13:53 +05:00
f727ec51b8 Merge branch 'master' into 7-assign-team-to-repo 2020-10-12 18:04:27 +05:00
829320ca0c Merge branch 'master' into 7-assign-team-to-repo 2020-10-05 21:34:16 +05:00
4d1d7a7204 Merge branch 'master' into 7-assign-team-to-repo
# Conflicts:
#	app/src/main/res/values/strings.xml
2020-10-05 21:22:21 +05:00
a009e5dac9 add to menu 2020-09-16 20:59:17 +05:00
263 changed files with 8654 additions and 5447 deletions

View File

@ -15,8 +15,8 @@ steps:
image: zosiab/eclint:latest
depends_on: [ clone ]
commands:
- git pull origin master
- eclint check $(git diff --name-only origin/master)
- git pull origin main
- eclint check $(git diff --name-only origin/main)
# This may be used in the future, because it makes of intellij's native code inspection/formatting capabilities.
# Additional information: https://www.jetbrains.com/help/idea/command-line-formatter.html
@ -54,7 +54,7 @@ trigger:
event:
- push
branch:
- master
- main
---
kind: pipeline
@ -101,4 +101,4 @@ trigger:
event:
- push
branch:
- master
- main

View File

@ -31,7 +31,7 @@
<!-- Screenshots and stacktrace's can go here. -->
<br><br>
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/master/CONTRIBUTING.md).
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
<br>
#### Thank you for your time.

View File

@ -2,8 +2,8 @@
<!-- Create a new issue, if it doesn't exist yet -->
<br><br>
<!-- Make sure you are targeting the master branch, pull requests on release branches are only allowed for bug fixes. -->
<!-- Make sure you are targeting the "main" branch, pull requests on release branches are only allowed for bug fixes. -->
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/master/CONTRIBUTING.md).
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
- [ ] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
- [ ] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/master/LICENSE).
- [ ] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).

View File

@ -4,10 +4,10 @@ stages:
- publish
on_setup:
image: tutum/curl
image: curlimages/curl:7.77.0
stage: .pre
only:
- master
- main
- tags
variables:
INSTANCE: "https://codeberg.org"
@ -20,7 +20,7 @@ build:
image: nextcloudci/android:android-54
stage: build
only:
- master
- main
- tags
script:
- ./gradlew assembleFreeRelease
@ -33,7 +33,7 @@ sign:
image: nextcloudci/android:android-54
stage: sign
only:
- master
- main
- tags
variables:
OUTPUT: "signed.apk"
@ -47,10 +47,10 @@ sign:
expire_in: 15 minutes
latest:
image: tutum/curl
image: curlimages/curl:7.77.0
stage: publish
only:
- master
- main
- tags
variables:
WEBDAV_USERNAME: "GitNexBot"
@ -60,7 +60,7 @@ latest:
- curl -T "$PLUGIN_FILE" -u "$WEBDAV_USERNAME":"$WEBDAV_PASSWORD" "$PLUGIN_DESTINATION"
release:
image: tutum/curl
image: curlimages/curl:7.77.0
stage: publish
only:
- tags
@ -72,10 +72,10 @@ release:
- curl -T "$PLUGIN_FILE" -u "$WEBDAV_USERNAME":"$WEBDAV_PASSWORD" 'https://cloud.swatian.com/remote.php/dav/files/GitNexBot/gitnex/releases/'"$CI_COMMIT_REF_NAME"'.apk'
on_success:
image: tutum/curl
image: curlimages/curl:7.77.0
stage: .post
only:
- master
- main
- tags
variables:
INSTANCE: "https://codeberg.org"
@ -86,10 +86,10 @@ on_success:
when: on_success
on_failure:
image: tutum/curl
image: curlimages/curl:7.77.0
stage: .post
only:
- master
- main
- tags
variables:
INSTANCE: "https://codeberg.org"

View File

@ -29,7 +29,7 @@ It is documented in the Wiki: [Code-Standards](https://codeberg.org/gitnex/GitNe
2. Clone the forked repository from your namespace to your local machine.
3. Create a new branch and work on your feature, enhancement or patch.
4. Push your commits to your forked version.
5. You can now create a PR using the web interface against **master** branch.
5. You can now create a PR using the web interface against **main** branch.
For more information, click [here](http://makeapullrequest.com/).

View File

@ -1,4 +1,4 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Pipeline status](https://img.shields.io/gitlab/pipeline/opyale/gitnex/master)](https://gitlab.com/opyale/gitnex/-/pipelines) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://codeberg.org/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://codeberg.org/gitnex/GitNex/releases) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf)
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Pipeline status](https://img.shields.io/gitlab/pipeline/opyale/gitnex/main)](https://gitlab.com/opyale/gitnex/-/pipelines) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://codeberg.org/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://codeberg.org/gitnex/GitNex/releases) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf)
[<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif)
@ -11,7 +11,7 @@ GitNex is licensed under GPLv3 License. See the LICENSE file for the full licens
## Downloads
[<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/)
[<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.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/master/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/DN7E5xxtaw4fRbE)
## Note about Gitea version
Please make sure that you are on latest stable release or later for better app experience.
@ -37,7 +37,7 @@ Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew assemb
- [MANY MORE](https://codeberg.org/gitnex/GitNex/wiki/Features)
## Contributing
[CONTRIBUTING](https://codeberg.org/gitnex/GitNex/src/branch/master/CONTRIBUTING.md)
[CONTRIBUTING](https://codeberg.org/gitnex/GitNex/src/branch/main/CONTRIBUTING.md)
## Translation
Help us translate GitNex to your native language.
@ -48,9 +48,9 @@ We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your la
## Screenshots:
<img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/001.png" alt="001.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/002.png" alt="002.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/003.png" alt="003.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/004.png" alt="004.png" width="200"/>
<img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/001.png" alt="001.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/002.png" alt="002.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/003.png" alt="003.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/004.png" alt="004.png" width="200"/>
---|---|---|---
<img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/005.png" alt="005.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/006.png" alt="006.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/007.png" alt="007.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/008.png" alt="008.png" width="200"/>
<img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/005.png" alt="005.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/006.png" alt="006.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/007.png" alt="007.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/008.png" alt="008.png" width="200"/>
## Links
[Website](https://gitnex.com)
@ -84,10 +84,10 @@ Thanks to all the open source libraries, contributors and donators.
- [HamidrezaAmz/BreadcrumbsView](https://github.com/HamidrezaAmz/BreadcrumbsView)
- [Baseflow/PhotoView](https://github.com/Baseflow/PhotoView)
- [apache/commons](https://github.com/apache/commons-io)
- [barteksc/AndroidPdfViewer](https://github.com/barteksc/AndroidPdfViewer)
- [ge0rg/MemorizingTrustManager](https://github.com/ge0rg/MemorizingTrustManager)
- [mikaelhg/urlbuilder](https://github.com/mikaelhg/urlbuilder)
- [ACRA/acra](https://github.com/ACRA/acra)
- [chrisvest/stormpot](https://github.com/chrisvest/stormpot)
#### Icon sets
- [feathericons/feather](https://github.com/feathericons/feather)

View File

@ -6,8 +6,8 @@ android {
applicationId "org.mian.gitnex"
minSdkVersion 21
targetSdkVersion 30
versionCode 350
versionName "3.5.0"
versionCode 405
versionName "4.1.0-dev"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -24,7 +24,7 @@ android {
}
}
buildFeatures {
viewBinding = true
viewBinding true
}
buildTypes {
release {
@ -54,20 +54,21 @@ configurations {
}
dependencies {
def lifecycle_version = '2.3.0'
def lifecycle_version = '2.3.1'
def markwon_version = '4.6.2'
def work_version = "2.5.0"
def work_version = "2.7.0-alpha05"
def acra = "5.7.0"
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.3.0-beta01'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.appcompat:appcompat:1.4.0-alpha03'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2'
implementation "com.google.code.gson:gson:2.8.6"
implementation "com.squareup.picasso:picasso:2.71828"
@ -100,17 +101,17 @@ dependencies {
implementation "commons-io:commons-io:20030203.000550"
implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation "com.github.chrisbanes:PhotoView:2.3.0"
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
implementation "ch.acra:acra-mail:$acra"
implementation "ch.acra:acra-limiter:$acra"
implementation "ch.acra:acra-notification:$acra"
implementation 'androidx.room:room-runtime:2.2.6'
annotationProcessor 'androidx.room:room-compiler:2.2.6'
implementation 'androidx.room:room-runtime:2.3.0'
annotationProcessor 'androidx.room:room-compiler:2.3.0'
implementation "androidx.work:work-runtime:$work_version"
implementation "io.mikael:urlbuilder:2.0.9"
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
implementation "org.codeberg.gitnex:tea4j:1.0.5"
implementation "org.codeberg.gitnex:tea4j:1.0.16"
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'
}

View File

@ -51,7 +51,7 @@
android:name=".activities.CreateNewUserActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.ProfileEmailActivity"
android:name=".activities.MyProfileEmailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.AddCollaboratorToRepositoryActivity"
@ -88,7 +88,8 @@
<activity
android:name=".activities.MainActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation">
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -123,7 +124,7 @@
android:name=".activities.SettingsAppearanceActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.SettingsFileViewerActivity"
android:name=".activities.ProfileActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.SettingsSecurityActivity"
@ -173,7 +174,8 @@
android:name=".activities.DeepLinksActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:noHistory="true"
android:launchMode="singleTask">
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

View File

@ -0,0 +1,62 @@
package org.mian.gitnex.actions;
import android.content.Context;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author qwerty287
*/
public class PullRequestActions {
public static void deleteHeadBranch(Context context, String repoOwner, String repoName, String headBranch, boolean showToasts) {
Call<JsonElement> call = RetrofitClient
.getApiInterface(context)
.deleteBranch(Authorization.get(context), repoOwner, repoName, headBranch);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 204) {
if(showToasts) Toasty.success(context, context.getString(R.string.deleteBranchSuccess));
}
else if(response.code() == 401) {
AlertDialogs
.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle), context.getResources().getString(R.string.alertDialogTokenRevokedMessage), context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
if(showToasts) Toasty.error(context, context.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
if(showToasts) Toasty.warning(context, context.getString(R.string.deleteBranchErrorNotFound));
}
else {
if(showToasts) Toasty.error(context, context.getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
if(showToasts) Toasty.error(context, context.getString(R.string.deleteBranchError));
}
});
}
}

View File

@ -12,6 +12,7 @@ import org.gitnex.tea4j.models.GiteaVersion;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.databinding.ActivityAddNewAccountBinding;
import org.mian.gitnex.helpers.AppUtil;
@ -48,6 +49,7 @@ public class AddNewAccountActivity extends BaseActivity {
initCloseListener();
viewBinding.close.setOnClickListener(onClickListener);
viewBinding.instanceUrl.setText(getIntent().getStringExtra("instanceUrl"));
ArrayAdapter<Protocol> adapterProtocols = new ArrayAdapter<>(ctx, R.layout.list_spinner_items, Protocol.values());
@ -114,9 +116,7 @@ public class AddNewAccountActivity extends BaseActivity {
private void versionCheck(final String instanceUrl, final String loginToken) {
Call<GiteaVersion> callVersion;
callVersion = RetrofitClient.getApiInterface(ctx).getGiteaVersionWithToken("token " + loginToken);
callVersion = RetrofitClient.getApiInterface(ctx, instanceUrl).getGiteaVersionWithToken("token " + loginToken);
callVersion.enqueue(new Callback<GiteaVersion>() {
@Override
@ -205,14 +205,15 @@ public class AddNewAccountActivity extends BaseActivity {
assert userDetails != null;
// insert new account to db if does not exist
String accountName = userDetails.getUsername() + "@" + instanceUrl;
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
int checkAccount = userAccountsApi.getCount(accountName);
UserAccountsApi userAccountsApi = BaseApi.getInstance(ctx, UserAccountsApi.class);
boolean userAccountExists = userAccountsApi.userAccountExists(accountName);
if(checkAccount == 0) {
if(!userAccountExists) {
userAccountsApi.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, "");
userAccountsApi.createNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, "");
Toasty.success(ctx, getResources().getString(R.string.accountAddedMessage));
finish();
}
else {

View File

@ -2,11 +2,17 @@ package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.biometric.BiometricPrompt;
import androidx.core.content.ContextCompat;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.notifications.Notifications;
import java.util.Locale;
import java.util.concurrent.Executor;
/**
* Author M M Arif
@ -36,7 +42,7 @@ public abstract class BaseActivity extends AppCompatActivity {
break;
case 2:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
if(TimeHelper.timeBetweenHours(tinyDB.getInt("darkThemeTimeHour"), tinyDB.getInt("lightThemeTimeHour"), tinyDB.getInt("darkThemeTimeMinute"), tinyDB.getInt("lightThemeTimeMinute"))) {
tinyDB.putString("currentTheme", "dark");
setTheme(R.style.AppTheme);
@ -53,7 +59,7 @@ public abstract class BaseActivity extends AppCompatActivity {
setTheme(R.style.AppThemeRetro);
break;
case 4:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
if(TimeHelper.timeBetweenHours(tinyDB.getInt("darkThemeTimeHour"), tinyDB.getInt("lightThemeTimeHour"), tinyDB.getInt("darkThemeTimeMinute"), tinyDB.getInt("lightThemeTimeMinute"))) {
tinyDB.putString("currentTheme", "dark");
setTheme(R.style.AppTheme);
@ -76,9 +82,55 @@ public abstract class BaseActivity extends AppCompatActivity {
}
AppUtil.setAppLocale(getResources(), tinyDB.getString("locale"));
String locale = tinyDB.getString("locale");
if (locale.isEmpty()) {
AppUtil.setAppLocale(getResources(), Locale.getDefault().getLanguage());
}
else {
AppUtil.setAppLocale(getResources(), locale);
}
Notifications.startWorker(appCtx);
}
public void onResume() {
super.onResume();
if(tinyDB.getBoolean("biometricStatus") && !tinyDB.getBoolean("biometricLifeCycle")) {
Executor executor = ContextCompat.getMainExecutor(this);
BiometricPrompt biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
// Authentication error, close the app
if(errorCode == BiometricPrompt.ERROR_USER_CANCELED ||
errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
finish();
}
}
// Authentication succeeded, continue to app
@Override public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) { super.onAuthenticationSucceeded(result); tinyDB.putBoolean("biometricLifeCycle", true); }
// Authentication failed, close the app
@Override public void onAuthenticationFailed() { super.onAuthenticationFailed(); }
});
BiometricPrompt.PromptInfo biometricPromptBuilder = new BiometricPrompt.PromptInfo.Builder()
.setTitle(getString(R.string.biometricAuthTitle))
.setSubtitle(getString(R.string.biometricAuthSubTitle))
.setNegativeButtonText(getString(R.string.cancelButton)).build();
biometricPrompt.authenticate(biometricPromptBuilder);
}
}
}

View File

@ -215,7 +215,7 @@ public class CreateRepoActivity extends BaseActivity {
Call<List<OrgOwner>> call = RetrofitClient
.getApiInterface(ctx)
.getOrgOwners(instanceToken);
.getOrgOwners(instanceToken, 1, 50);
call.enqueue(new Callback<List<OrgOwner>>() {

View File

@ -9,22 +9,31 @@ import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.gitnex.tea4j.models.Files;
import org.gitnex.tea4j.models.Organization;
import org.gitnex.tea4j.models.PullRequests;
import org.gitnex.tea4j.models.UserInfo;
import org.gitnex.tea4j.models.UserRepositories;
import org.jetbrains.annotations.NotNull;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.databinding.ActivityDeeplinksBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.UrlHelper;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import io.mikael.urlbuilder.UrlBuilder;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
@ -40,6 +49,8 @@ public class DeepLinksActivity extends BaseActivity {
private Intent mainIntent;
private Intent issueIntent;
private Intent repoIntent;
private Intent orgIntent;
private Intent userIntent;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -52,6 +63,8 @@ public class DeepLinksActivity extends BaseActivity {
mainIntent = new Intent(ctx, MainActivity.class);
issueIntent = new Intent(ctx, IssueDetailActivity.class);
repoIntent = new Intent(ctx, RepoDetailActivity.class);
orgIntent = new Intent(ctx, OrganizationDetailActivity.class);
userIntent = new Intent(ctx, ProfileActivity.class);
Intent intent = getIntent();
Uri data = intent.getData();
@ -59,13 +72,14 @@ public class DeepLinksActivity extends BaseActivity {
// check for login
if(!tinyDB.getBoolean("loggedInMode")) {
Intent loginIntent = new Intent(ctx, LoginActivity.class);
loginIntent.putExtra("instanceUrl", data.getHost());
ctx.startActivity(loginIntent);
finish();
ctx.startActivity(new Intent(ctx, LoginActivity.class));
}
// check for the links(URI) to be in the db
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
UserAccountsApi userAccountsApi = BaseApi.getInstance(ctx, UserAccountsApi.class);
List<UserAccount> userAccounts = userAccountsApi.usersAccounts();
for(UserAccount userAccount : userAccounts) {
@ -79,40 +93,94 @@ public class DeepLinksActivity extends BaseActivity {
accountFound = true;
tinyDB.putString("loginUid", userAccount.getUserName());
tinyDB.putString("userLogin", userAccount.getUserName());
tinyDB.putString(userAccount.getUserName() + "-token", userAccount.getToken());
tinyDB.putString("instanceUrl", userAccount.getInstanceUrl());
tinyDB.putInt("currentActiveAccountId", userAccount.getAccountId());
AppUtil.switchToAccount(ctx, userAccount);
break;
}
}
if(accountFound) {
// redirect to proper fragment/activity, If no action is there, show options where user to want to go like repos, profile, notifications etc
if(data.getPathSegments().size() > 0) {
viewBinding.progressBar.setVisibility(View.GONE);
String[] restOfUrl = Objects.requireNonNull(data.getPath()).split("/");
if(data.getPathSegments().contains("issues")) { // issue
// redirect to proper fragment/activity, if no action is there, show options where user to want to go like repos, profile, notifications etc
if(data.getPathSegments().size() == 1) {
if(data.getLastPathSegment().equals("notifications")) { // notifications
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
ctx.startActivity(mainIntent);
finish();
}
else if(data.getLastPathSegment().equals("explore")) { // explore
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
}
else if(data.getLastPathSegment().equals(tinyDB.getString("userLogin"))) { // your user profile
mainIntent.putExtra("launchFragmentByLinkHandler", "profile");
ctx.startActivity(mainIntent);
finish();
}
else if(data.getLastPathSegment().equals("admin")) {
mainIntent.putExtra("launchFragmentByLinkHandler", "admin");
ctx.startActivity(mainIntent);
finish();
}
else {
new Handler(Looper.getMainLooper()).postDelayed(() ->
getUserOrOrg(currentInstance, instanceToken, data.getLastPathSegment()), 500);
}
}
else if(data.getPathSegments().size() == 2) {
if(data.getPathSegments().get(0).equals("explore")) { // specific explore tab
if(data.getPathSegments().get(1).equals("organizations")) { // orgs
mainIntent.putExtra("exploreOrgs", true);
}
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
}
else if(data.getPathSegments().get(0).equals("user") && data.getPathSegments().get(1).equals("login")) { // open login
Intent loginIntent = new Intent(ctx, AddNewAccountActivity.class);
loginIntent.putExtra("instanceUrl", data.getHost());
loginIntent.putExtra("instanceProtocol", data.getScheme());
ctx.startActivity(loginIntent);
finish();
}
else if(data.getPathSegments().get(0).equals("admin")) {
mainIntent.putExtra("launchFragmentByLinkHandler", "admin");
mainIntent.putExtra("giteaAdminAction", data.getLastPathSegment());
ctx.startActivity(mainIntent);
finish();
}
else if(!data.getPathSegments().get(0).equals("") & !data.getLastPathSegment().equals("")) { // go to repo
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getLastPathSegment(), "repo"), 500);
}
else { // no action, show options
showNoActionButtons();
}
}
else if(data.getPathSegments().size() >= 3) {
if(data.getPathSegments().get(2).equals("issues")) { // issue
if(!Objects.requireNonNull(data.getLastPathSegment()).contains("issues") & StringUtils.isNumeric(data.getLastPathSegment())) {
issueIntent.putExtra("issueNumber", data.getLastPathSegment());
issueIntent.putExtra("openedFromLink", "true");
String[] urlSplitted = data.toString().split("#");
if (urlSplitted.length == 2) {
issueIntent.putExtra("issueComment", urlSplitted[1]);
}
tinyDB.putString("issueNumber", data.getLastPathSegment());
tinyDB.putString("issueType", "Issue");
tinyDB.putString("repoFullName", restOfUrl[restOfUrl.length - 4] + "/" + restOfUrl[restOfUrl.length - 3]);
tinyDB.putString("repoFullName", data.getPathSegments().get(0) + "/" + data.getPathSegments().get(1));
final String repoOwner = restOfUrl[restOfUrl.length - 4];
final String repoName = restOfUrl[restOfUrl.length - 3];
final String repoOwner = data.getPathSegments().get(0);
final String repoName = data.getPathSegments().get(1);
int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(ctx);
RepositoriesApi repositoryData = BaseApi.getInstance(ctx, RepositoriesApi.class);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
@ -131,125 +199,121 @@ public class DeepLinksActivity extends BaseActivity {
finish();
}
else if(Objects.requireNonNull(data.getLastPathSegment()).contains("issues")) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 3], restOfUrl[restOfUrl.length - 2], "issue");
}, 500);
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "issue"), 500);
}
else if(data.getLastPathSegment().equals("new")) {
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "issueNew"), 500);
}
else {
ctx.startActivity(mainIntent);
finish();
}
}
else if(data.getPathSegments().contains("pulls")) { // pr
else if(data.getPathSegments().get(2).equals("pulls")) { // pr
if(!Objects.requireNonNull(data.getLastPathSegment()).contains("pulls") & StringUtils.isNumeric(data.getLastPathSegment())) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
getPullRequest(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 4], restOfUrl[restOfUrl.length - 3], Integer.parseInt(data.getLastPathSegment()));
String[] urlSplitted = data.toString().split("#");
if (urlSplitted.length == 2) {
issueIntent.putExtra("issueComment", urlSplitted[1]);
}
getPullRequest(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), Integer.parseInt(data.getLastPathSegment()));
}, 500);
}
else if(Objects.requireNonNull(data.getLastPathSegment()).contains("pulls")) {
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "pull"), 500);
}
else if(data.getLastPathSegment().equals("files")) { // pr diff
new Handler(Looper.getMainLooper()).postDelayed(() -> {
goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 3], restOfUrl[restOfUrl.length - 2], "pull");
issueIntent.putExtra("openPrDiff", "true");
getPullRequest(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), Integer.parseInt(data.getPathSegments().get(3)));
}, 500);
}
else {
ctx.startActivity(mainIntent);
finish();
}
}
else if(data.getPathSegments().contains("commit")) { // commits (no API yet to properly implement)
new Handler(Looper.getMainLooper()).postDelayed(() -> {
goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 4], restOfUrl[restOfUrl.length - 3], "pull");
}, 500);
else if(data.getPathSegments().get(2).equals("compare")) { // new pull request
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "pullNew"), 500);
}
else if(!restOfUrl[restOfUrl.length - 2].equals("") & !restOfUrl[restOfUrl.length - 1].equals("")) { // go to repo
new Handler(Looper.getMainLooper()).postDelayed(() -> {
goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 2], restOfUrl[restOfUrl.length - 1], "repo");
}, 500);
else if(data.getPathSegments().get(2).equals("commit")) { // commits (no API yet to properly implement)
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "pull"), 500);
}
else if(data.getPathSegments().get(2).equals("commits")) { // commits list
String branch = data.getLastPathSegment();
repoIntent.putExtra("branchName", branch);
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "commitsList"), 500);
}
else if(data.getPathSegments().get(2).equals("milestones") && data.getLastPathSegment().equals("new")) { // new milestone
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "milestonesNew"), 500);
}
else if(data.getPathSegments().get(2).equals("milestones")) { // milestones
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "milestones"), 500);
}
else if(data.getPathSegments().get(2).equals("milestone")) { // milestone
repoIntent.putExtra("milestoneId", data.getLastPathSegment());
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "milestones"), 500);
}
else if(data.getPathSegments().get(2).equals("releases") && data.getLastPathSegment().equals("new")) { // new release
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "newRelease"), 500);
}
else if(data.getPathSegments().get(2).equals("releases")) { // releases
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "releases"), 500);
}
else if(data.getPathSegments().get(2).equals("releases") && data.getPathSegments().get(3).equals("tag") && data.getPathSegments().size() == 5) { // release
repoIntent.putExtra("releaseTagName", data.getLastPathSegment());
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "releases"), 500);
}
else if(data.getPathSegments().get(2).equals("labels")) { // labels
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "labels"), 500);
}
else if(data.getPathSegments().get(2).equals("settings")) { // repo settings
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "settings"), 500);
}
else if(data.getLastPathSegment().equals("branches")) { // branches list
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "branchesList"), 500);
}
else if(data.getPathSegments().size() == 5 && data.getPathSegments().get(2).equals("src") && data.getPathSegments().get(3).equals("branch")) { // branch
repoIntent.putExtra("selectedBranch", data.getLastPathSegment());
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "branch"), 500);
}
else if(data.getPathSegments().get(2).equals("src") && data.getPathSegments().get(3).equals("branch")) { // file/dir
StringBuilder filePath = new StringBuilder();
ArrayList<String> segments = new ArrayList<>(data.getPathSegments());
segments.subList(0, 5).clear();
for (String item : segments) {
filePath.append(item);
filePath.append("/");
}
filePath.deleteCharAt(filePath.toString().length() - 1);
new Handler(Looper.getMainLooper()).postDelayed(() ->
getFile(currentInstance, instanceToken, data.getPathSegments().get(0),
data.getPathSegments().get(1), filePath.toString(), data.getPathSegments().get(4)), 500);
}
else { // no action, show options
if(tinyDB.getInt("defaultScreenId") == 1) { // repos
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDB.getInt("defaultScreenId") == 2) { // org
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDB.getInt("defaultScreenId") == 3) { // notifications
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDB.getInt("defaultScreenId") == 4) { // explore
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDB.getInt("defaultScreenId") == 0) { // show options
viewBinding.noActionFrame.setVisibility(View.VISIBLE);
viewBinding.addNewAccountFrame.setVisibility(View.GONE);
viewBinding.repository.setOnClickListener(repository -> {
tinyDB.putInt("defaultScreenId", 1);
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.organization.setOnClickListener(organization -> {
tinyDB.putInt("defaultScreenId", 2);
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.notification.setOnClickListener(notification -> {
tinyDB.putInt("defaultScreenId", 3);
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.explore.setOnClickListener(explore -> {
tinyDB.putInt("defaultScreenId", 4);
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.launchApp2.setOnClickListener(launchApp2 -> {
tinyDB.putInt("defaultScreenId", 0);
ctx.startActivity(mainIntent);
finish();
});
}
showNoActionButtons();
}
}
else {
@ -268,6 +332,7 @@ public class DeepLinksActivity extends BaseActivity {
viewBinding.addNewAccount.setOnClickListener(addNewAccount -> {
Intent accountIntent = new Intent(ctx, AddNewAccountActivity.class);
accountIntent.putExtra("instanceUrl", data.getHost());
startActivity(accountIntent);
finish();
});
@ -318,6 +383,7 @@ public class DeepLinksActivity extends BaseActivity {
issueIntent.putExtra("issueNumber", index);
issueIntent.putExtra("prMergeable", prInfo.isMergeable());
issueIntent.putExtra("openedFromLink", "true");
if(prInfo.getHead() != null) {
@ -344,7 +410,7 @@ public class DeepLinksActivity extends BaseActivity {
tinyDB.putString("repoFullName", repoOwner + "/" + repoName);
int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(ctx);
RepositoriesApi repositoryData = BaseApi.getInstance(ctx, RepositoriesApi.class);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
@ -415,7 +481,7 @@ public class DeepLinksActivity extends BaseActivity {
tinyDB.putString("repoBranch", repoInfo.getDefault_branch());
int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(ctx);
RepositoriesApi repositoryData = BaseApi.getInstance(ctx, RepositoriesApi.class);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
@ -452,4 +518,181 @@ public class DeepLinksActivity extends BaseActivity {
}
});
}
private void getUserOrOrg(String url, String instanceToken, String userOrgName) {
Call<Organization> call = RetrofitClient.getApiInterface(ctx, url).getOrganization(instanceToken, userOrgName);
call.enqueue(new Callback<Organization>() {
@Override
public void onResponse(@NotNull Call<Organization> call, @NotNull Response<Organization> response) {
if(response.code() == 404) { // org doesn't exist or it's a user user
Log.d("getUserOrOrg-404", String.valueOf(response.code()));
getUser(url, instanceToken, userOrgName);
}
else if(response.code() == 200) { // org
assert response.body() != null;
orgIntent.putExtra("orgName", response.body().getUsername());
TinyDB tinyDb = TinyDB.getInstance(ctx);
tinyDb.putString("orgName", response.body().getUsername());
tinyDb.putString("organizationId", String.valueOf(response.body().getId()));
tinyDb.putBoolean("organizationAction", true);
ctx.startActivity(orgIntent);
finish();
}
else {
Log.e("getUserOrOrg-code", String.valueOf(response.code()));
ctx.startActivity(mainIntent);
finish();
}
}
@Override
public void onFailure(@NotNull Call<Organization> call, @NotNull Throwable t) {
Log.e("onFailure-getUserOrOrg", t.toString());
}
});
}
private void getUser(String url, String instanceToken, String userName) {
Call<UserInfo> call = RetrofitClient.getApiInterface(ctx, url).getUserProfile(instanceToken, userName);
call.enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(@NotNull Call<UserInfo> call, @NotNull Response<UserInfo> response) {
if(response.code() == 200) {
assert response.body() != null;
userIntent.putExtra("username", response.body().getLogin());
ctx.startActivity(userIntent);
}
else {
Log.e("getUser-code", String.valueOf(response.code()));
ctx.startActivity(mainIntent);
}
finish();
}
@Override
public void onFailure(@NotNull Call<UserInfo> call, @NotNull Throwable t) {
Log.e("onFailure-getUser", t.toString());
ctx.startActivity(mainIntent);
finish();
}
});
}
private void getFile(String url, String instanceToken, String owner, String repo, String filePath, String branch) {
Call<Files> call = RetrofitClient.getApiInterface(ctx, url).getSingleFileContents(instanceToken, owner, repo, filePath, branch);
call.enqueue(new Callback<Files>() {
@Override
public void onResponse(@NotNull Call<Files> call, @NotNull Response<Files> response) {
if(response.code() == 200) {
// check if file and open file/dir
Files file = response.body();
assert file != null;
if(file.getType().equals("file")) {
repoIntent.putExtra("file", file);
repoIntent.putExtra("branch", branch);
goToRepoSection(url, instanceToken, owner, repo, "file");
}
}
else {
Log.e("getFile-onFailure", String.valueOf(response.code()));
ctx.startActivity(mainIntent);
finish();
}
}
@Override
public void onFailure(@NotNull Call<Files> call, @NotNull Throwable t) {
Log.e("getFile-onFailure", t.toString());
// maybe it's a directory
getDir(url, instanceToken, owner, repo, filePath, branch);
}
});
}
private void getDir(String url, String instanceToken, String owner, String repo, String filePath, String branch) {
repoIntent.putExtra("branch", branch);
repoIntent.putExtra("dir", filePath);
goToRepoSection(url, instanceToken, owner, repo, "dir");
}
private void showNoActionButtons() {
viewBinding.progressBar.setVisibility(View.GONE);
if(tinyDB.getInt("defaultScreenId") == 1) { // repos
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDB.getInt("defaultScreenId") == 2) { // org
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDB.getInt("defaultScreenId") == 3) { // notifications
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDB.getInt("defaultScreenId") == 4) { // explore
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDB.getInt("defaultScreenId") == 0) { // show options
viewBinding.noActionFrame.setVisibility(View.VISIBLE);
viewBinding.addNewAccountFrame.setVisibility(View.GONE);
viewBinding.repository.setOnClickListener(repository -> {
tinyDB.putInt("defaultScreenId", 1);
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.organization.setOnClickListener(organization -> {
tinyDB.putInt("defaultScreenId", 2);
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.notification.setOnClickListener(notification -> {
tinyDB.putInt("defaultScreenId", 3);
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.explore.setOnClickListener(explore -> {
tinyDB.putInt("defaultScreenId", 4);
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.launchApp2.setOnClickListener(launchApp2 -> {
tinyDB.putInt("defaultScreenId", 0);
ctx.startActivity(mainIntent);
finish();
});
}
}
}

View File

@ -106,23 +106,23 @@ public class FileDiffActivity extends BaseActivity {
break;
case 401:
AlertDialogs.authorizationTokenRevokedDialog(ctx,
runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(ctx,
getString(R.string.alertDialogTokenRevokedTitle),
getString(R.string.alertDialogTokenRevokedMessage),
getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
getString(R.string.alertDialogTokenRevokedCopyPositiveButton)));
break;
case 403:
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
runOnUiThread(() -> Toasty.error(ctx, ctx.getString(R.string.authorizeError)));
break;
case 404:
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
runOnUiThread(() -> Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)));
break;
default:
Toasty.error(ctx, getString(R.string.labelGeneralError));
runOnUiThread(() -> Toasty.error(ctx, getString(R.string.labelGeneralError)));
}
} catch(IOException ignored) {}

View File

@ -15,7 +15,6 @@ import android.view.View;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.core.app.NotificationCompat;
import com.github.barteksc.pdfviewer.util.FitPolicy;
import com.vdurmont.emoji.EmojiParser;
import org.apache.commons.io.FileUtils;
import org.gitnex.tea4j.models.Files;
@ -45,8 +44,6 @@ import retrofit2.Response;
public class FileViewActivity extends BaseActivity implements BottomSheetFileViewerFragment.BottomSheetListener {
private ActivityFileViewBinding binding;
private Boolean pdfNightMode;
private Files file;
@Override
@ -55,8 +52,8 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
super.onCreate(savedInstanceState);
binding = ActivityFileViewBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
tinyDB.putBoolean("enableMarkdownInFileView", false);
@ -84,7 +81,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
super.onResume();
if(tinyDB.getBoolean("fileModified")) {
String repoFullName = tinyDB.getString("repoFullName");
String repoBranch = tinyDB.getString("repoBranch");
String[] parts = repoFullName.split("/");
@ -93,7 +89,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
getSingleFileContents(repoOwner, repoName, file.getPath(), repoBranch);
tinyDB.putBoolean("fileModified", false);
}
}
@ -116,7 +111,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if(responseBody != null) {
runOnUiThread(() -> binding.progressBar.setVisibility(View.GONE));
String fileExtension = FileUtils.getExtension(filename);
boolean processable = false;
@ -133,14 +127,11 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
byte[] pictureBytes = responseBody.bytes();
runOnUiThread(() -> {
binding.contents.setVisibility(View.GONE);
binding.pdfViewFrame.setVisibility(View.GONE);
binding.markdownFrame.setVisibility(View.GONE);
binding.photoView.setVisibility(View.VISIBLE);
binding.photoView.setImageBitmap(Images.scaleImage(pictureBytes, 1920));
});
}
break;
@ -153,78 +144,39 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
}
processable = true;
String text = responseBody.string();
runOnUiThread(() -> {
binding.photoView.setVisibility(View.GONE);
binding.markdownFrame.setVisibility(View.GONE);
binding.pdfViewFrame.setVisibility(View.GONE);
binding.contents.setVisibility(View.VISIBLE);
binding.contents.setContent(text, fileExtension);
});
break;
if(tinyDB.getBoolean("enableMarkdownInFileView")) {
Markdown.render(ctx, EmojiParser.parseToUnicode(text), binding.markdown);
case DOCUMENT:
if(fileExtension.equalsIgnoreCase("pdf")) {
processable = true;
byte[] documentBytes = responseBody.bytes();
runOnUiThread(() -> {
binding.photoView.setVisibility(View.GONE);
binding.markdownFrame.setVisibility(View.GONE);
binding.contents.setVisibility(View.GONE);
pdfNightMode = tinyDB.getBoolean("enablePdfMode");
binding.pdfViewFrame.setVisibility(View.VISIBLE);
binding.pdfView.fromBytes(documentBytes)
.enableSwipe(true)
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
.enableAnnotationRendering(false)
.password(null)
.scrollHandle(null)
.enableAntialiasing(true)
.spacing(0)
.autoSpacing(true)
.pageFitPolicy(FitPolicy.WIDTH)
.fitEachPage(true)
.pageSnap(false)
.pageFling(true)
.nightMode(pdfNightMode).load();
});
}
binding.markdownFrame.setVisibility(View.VISIBLE);
} else {
binding.markdownFrame.setVisibility(View.GONE);
binding.contents.setVisibility(View.VISIBLE);
}
});
break;
}
if(!processable) { // While the file could still be non-binary,
// it's better we don't show it (to prevent any crashes and/or unwanted behavior) and let the user download it instead.
responseBody.close();
runOnUiThread(() -> {
binding.photoView.setVisibility(View.GONE);
binding.contents.setVisibility(View.GONE);
binding.pdfViewFrame.setVisibility(View.GONE);
binding.markdownFrame.setVisibility(View.VISIBLE);
binding.markdown.setText(getString(R.string.excludeFilesInFileViewer));
binding.markdown.setGravity(Gravity.CENTER);
binding.markdown.setTypeface(null, Typeface.BOLD);
});
}
} else {
@ -233,30 +185,29 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
binding.markdown.setText("");
binding.progressBar.setVisibility(View.GONE);
});
}
} else {
switch(response.code()) {
case 401:
AlertDialogs.authorizationTokenRevokedDialog(ctx,
runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(ctx,
getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)));
break;
case 403:
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
runOnUiThread(() -> Toasty.error(ctx, ctx.getString(R.string.authorizeError)));
break;
case 404:
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
runOnUiThread(() -> Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)));
break;
default:
Toasty.error(ctx, getString(R.string.labelGeneralError));
runOnUiThread(() -> Toasty.error(ctx, getString(R.string.labelGeneralError)));
}
}
@ -304,27 +255,22 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} else if(id == R.id.markdown) {
if(!tinyDB.getBoolean("enableMarkdownInFileView")) {
new Markdown(ctx, EmojiParser.parseToUnicode(binding.contents.getContent()), binding.markdown);
Markdown.render(ctx, EmojiParser.parseToUnicode(binding.contents.getContent()), binding.markdown);
binding.contents.setVisibility(View.GONE);
binding.markdownFrame.setVisibility(View.VISIBLE);
tinyDB.putBoolean("enableMarkdownInFileView", true);
} else {
binding.markdownFrame.setVisibility(View.GONE);
binding.contents.setVisibility(View.VISIBLE);
tinyDB.putBoolean("enableMarkdownInFileView", false);
}
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
@ -333,19 +279,16 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
public void onButtonClicked(String text) {
if("downloadFile".equals(text)) {
requestFileDownload();
}
if("deleteFile".equals(text)) {
Intent intent = new Intent(ctx, CreateFileActivity.class);
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_DELETE);
intent.putExtra("filePath", file.getPath());
intent.putExtra("fileSha", file.getSha());
ctx.startActivity(intent);
}
if("editFile".equals(text)) {
@ -363,7 +306,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
ctx.startActivity(intent);
} else {
Toasty.error(ctx, getString(R.string.fileTypeCannotBeEdited));
}
}

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.activities;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
@ -196,6 +197,10 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
getSingleIssue(repoOwner, repoName, issueIndex);
fetchDataAsync(repoOwner, repoName, issueIndex);
if(getIntent().getStringExtra("openPrDiff") != null && getIntent().getStringExtra("openPrDiff").equals("true")) {
startActivity(new Intent(ctx, FileDiffActivity.class));
}
}
@Override
@ -434,6 +439,11 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
if(id == android.R.id.home) {
if(getIntent().getStringExtra("openedFromLink") != null && getIntent().getStringExtra("openedFromLink").equals("true")) {
Intent intent = new Intent(ctx, RepoDetailActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
finish();
return true;
}
@ -569,7 +579,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
}
TinyDB tinyDb = TinyDB.getInstance(appCtx);
final String locale = tinyDb.getString("locale");
final Locale locale = getResources().getConfiguration().locale;
final String timeFormat = tinyDb.getString("dateFormat");
tinyDb.putString("issueState", singleIssue.getState());
tinyDb.putString("issueTitle", singleIssue.getTitle());
@ -582,7 +592,18 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + EmojiParser.parseToUnicode(singleIssue.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY));
String cleanIssueDescription = singleIssue.getBody().trim();
new Markdown(ctx, EmojiParser.parseToUnicode(cleanIssueDescription), viewBinding.issueDescription);
viewBinding.assigneeAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(ctx, ProfileActivity.class);
intent.putExtra("username", singleIssue.getUser().getLogin());
ctx.startActivity(intent);
});
viewBinding.assigneeAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(ctx, singleIssue.getUser().getLogin(), ctx.getString(R.string.copyLoginIdToClipBoard, singleIssue.getUser().getLogin()));
return true;
});
Markdown.render(ctx, EmojiParser.parseToUnicode(cleanIssueDescription), viewBinding.issueDescription);
RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams) viewBinding.issueDescription.getLayoutParams();
@ -603,7 +624,20 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.frameAssignees.addView(assigneesView);
assigneesView.setLayoutParams(params1);
if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) {
int finalI = i;
assigneesView.setOnClickListener(loginId -> {
Intent intent = new Intent(ctx, ProfileActivity.class);
intent.putExtra("username", singleIssue.getAssignees().get(finalI).getLogin());
ctx.startActivity(intent);
});
assigneesView.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(ctx, singleIssue.getAssignees().get(finalI).getLogin(), ctx.getString(R.string.copyLoginIdToClipBoard, singleIssue.getAssignees().get(finalI).getLogin()));
return true;
});
/*if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) {
assigneesView.setOnClickListener(
new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getFull_name()), ctx));
@ -612,7 +646,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
assigneesView.setOnClickListener(
new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getLogin()), ctx));
}
}*/
}
}
else {
@ -660,7 +694,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
if(timeFormat.equals("normal") || timeFormat.equals("pretty")) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", locale);
String dueDate = formatter.format(singleIssue.getDue_date());
viewBinding.issueDueDate.setText(dueDate);
viewBinding.issueDueDate
@ -668,7 +702,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
}
else if(timeFormat.equals("normal1")) {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", locale);
String dueDate = formatter.format(singleIssue.getDue_date());
viewBinding.issueDueDate.setText(dueDate);
}
@ -714,7 +748,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.issueDescription.setLayoutParams(paramsDesc);
}
viewBinding.issueCreatedTime.setText(TimeHelper.formatTime(singleIssue.getCreated_at(), new Locale(locale), timeFormat, ctx));
viewBinding.issueCreatedTime.setText(TimeHelper.formatTime(singleIssue.getCreated_at(), locale, timeFormat, ctx));
viewBinding.issueCreatedTime.setVisibility(View.VISIBLE);
if(timeFormat.equals("pretty")) {
@ -750,7 +784,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.issueMilestone.setVisibility(View.GONE);
}
if(!singleIssue.getUser().getFull_name().equals("")) {
/*if(!singleIssue.getUser().getFull_name().equals("")) {
viewBinding.assigneeAvatar.setOnClickListener(
new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), ctx));
@ -759,7 +793,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.assigneeAvatar.setOnClickListener(
new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), ctx));
}
}*/
viewBinding.progressBar.setVisibility(View.GONE);
}

View File

@ -17,6 +17,7 @@ import org.gitnex.tea4j.models.UserInfo;
import org.gitnex.tea4j.models.UserTokens;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.databinding.ActivityLoginBinding;
@ -76,6 +77,8 @@ public class LoginActivity extends BaseActivity {
ArrayAdapter<Protocol> adapterProtocols = new ArrayAdapter<>(LoginActivity.this, R.layout.list_spinner_items, Protocol.values());
instanceUrlET.setText(getIntent().getStringExtra("instanceUrl"));
protocolSpinner.setAdapter(adapterProtocols);
protocolSpinner.setSelection(0);
protocolSpinner.setOnItemClickListener((parent, view, position, id) -> {
@ -358,19 +361,19 @@ public class LoginActivity extends BaseActivity {
// insert new account to db if does not exist
String accountName = userDetails.getUsername() + "@" + TinyDB.getInstance(ctx).getString("instanceUrl");
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
int checkAccount = userAccountsApi.getCount(accountName);
UserAccountsApi userAccountsApi = BaseApi.getInstance(ctx, UserAccountsApi.class);
boolean userAccountExists = userAccountsApi.userAccountExists(accountName);
long accountId;
if(checkAccount == 0) {
if(!userAccountExists) {
accountId = userAccountsApi.insertNewAccount(accountName, TinyDB.getInstance(ctx).getString("instanceUrl"), userDetails.getUsername(), loginToken, "");
accountId = userAccountsApi.createNewAccount(accountName, TinyDB.getInstance(ctx).getString("instanceUrl"), userDetails.getUsername(), loginToken, "");
tinyDB.putInt("currentActiveAccountId", (int) accountId);
}
else {
userAccountsApi.updateTokenByAccountName(accountName, loginToken);
UserAccount data = userAccountsApi.getAccountData(accountName);
UserAccount data = userAccountsApi.getAccountByName(accountName);
tinyDB.putInt("currentActiveAccountId", data.getAccountId());
}
@ -546,20 +549,20 @@ public class LoginActivity extends BaseActivity {
// insert new account to db if does not exist
String accountName = userDetails.getUsername() + "@" + TinyDB.getInstance(ctx).getString("instanceUrl");
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
int checkAccount = userAccountsApi.getCount(accountName);
UserAccountsApi userAccountsApi = BaseApi.getInstance(ctx, UserAccountsApi.class);
boolean userAccountExists = userAccountsApi.userAccountExists(accountName);
long accountId;
if(checkAccount == 0) {
if(!userAccountExists) {
accountId = userAccountsApi
.insertNewAccount(accountName, TinyDB.getInstance(ctx).getString("instanceUrl"), userDetails.getUsername(), newToken.getSha1(), "");
.createNewAccount(accountName, TinyDB.getInstance(ctx).getString("instanceUrl"), userDetails.getUsername(), newToken.getSha1(), "");
tinyDB.putInt("currentActiveAccountId", (int) accountId);
}
else {
userAccountsApi.updateTokenByAccountName(accountName, newToken.getSha1());
UserAccount data = userAccountsApi.getAccountData(accountName);
UserAccount data = userAccountsApi.getAccountByName(accountName);
tinyDB.putInt("currentActiveAccountId", data.getAccountId());
}

View File

@ -17,9 +17,7 @@ import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.biometric.BiometricPrompt;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.cardview.widget.CardView;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
@ -33,6 +31,7 @@ import org.mian.gitnex.R;
import org.mian.gitnex.adapters.UserAccountsNavAdapter;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.databinding.ActivityMainBinding;
@ -43,7 +42,7 @@ import org.mian.gitnex.fragments.ExploreFragment;
import org.mian.gitnex.fragments.MyRepositoriesFragment;
import org.mian.gitnex.fragments.NotificationsFragment;
import org.mian.gitnex.fragments.OrganizationsFragment;
import org.mian.gitnex.fragments.ProfileFragment;
import org.mian.gitnex.fragments.MyProfileFragment;
import org.mian.gitnex.fragments.RepositoriesFragment;
import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.fragments.StarredRepositoriesFragment;
@ -59,7 +58,6 @@ import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import jp.wasabeef.picasso.transformations.BlurTransformation;
import retrofit2.Call;
import retrofit2.Callback;
@ -71,10 +69,6 @@ import retrofit2.Callback;
public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener, BottomSheetDraftsFragment.BottomSheetListener {
private DrawerLayout drawer;
private TextView userFullName;
private TextView userEmail;
private ImageView userAvatar;
private ImageView userAvatarBackground;
private TextView toolbarTitle;
private Typeface myTypeface;
@ -93,38 +87,25 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
ActivityMainBinding activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(activityMainBinding.getRoot());
tinyDB.putBoolean("noConnection", false);
String currentVersion = tinyDB.getString("giteaVersion");
Intent mainIntent = getIntent();
String launchFragment = mainIntent.getStringExtra("launchFragment");
// DO NOT MOVE
if(mainIntent.hasExtra("switchAccountId") &&
AppUtil.switchToAccount(ctx, BaseApi.getInstance(ctx, UserAccountsApi.class)
.getAccountById(mainIntent.getIntExtra("switchAccountId", 0)))) {
mainIntent.removeExtra("switchAccountId");
recreate();
return;
}
// DO NOT MOVE
tinyDB.putBoolean("noConnection", false);
loginUid = tinyDB.getString("loginUid");
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
if(tinyDB.getString("dateFormat").isEmpty()) {
tinyDB.putString("dateFormat", "pretty");
}
if(tinyDB.getString("codeBlockStr").isEmpty()) {
tinyDB.putInt("codeBlockColor", ResourcesCompat.getColor(getResources(), R.color.colorLightGreen, null));
tinyDB.putInt("codeBlockBackground", ResourcesCompat.getColor(getResources(), R.color.black, null));
}
if(tinyDB.getString("enableCounterIssueBadgeInit").isEmpty()) {
tinyDB.putBoolean("enableCounterIssueBadge", true);
}
if(tinyDB.getString("homeScreenStr").isEmpty()) {
tinyDB.putString("homeScreenStr", "yes");
tinyDB.putInt("homeScreenId", 0);
}
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if(!tinyDB.getBoolean("loggedInMode")) {
@ -133,9 +114,10 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
return;
}
if(tinyDB.getInt("currentActiveAccountId") <= 0) {
AlertDialogs.forceLogoutDialog(ctx, getResources().getString(R.string.forceLogoutDialogHeader), getResources().getString(R.string.forceLogoutDialogDescription), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
if(tinyDB.getInt("currentActiveAccountId", -1) <= 0) {
AlertDialogs.forceLogoutDialog(ctx,
getResources().getString(R.string.forceLogoutDialogHeader),
getResources().getString(R.string.forceLogoutDialogDescription), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
Toolbar toolbar = activityMainBinding.toolbar;
@ -144,53 +126,16 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
switch(tinyDB.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/roboto.ttf");
break;
case 2:
case 2:
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
default:
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/manroperegular.ttf");
break;
}
// biometric auth
if(tinyDB.getBoolean("biometricStatus")) {
Executor executor = ContextCompat.getMainExecutor(this);
BiometricPrompt biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
// Authentication error, close the app
if(errorCode == BiometricPrompt.ERROR_USER_CANCELED ||
errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
finish();
}
}
// Authentication succeeded, continue to app
@Override public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) { super.onAuthenticationSucceeded(result); }
// Authentication failed, close the app
@Override public void onAuthenticationFailed() { super.onAuthenticationFailed(); }
});
BiometricPrompt.PromptInfo biometricPromptBuilder = new BiometricPrompt.PromptInfo.Builder()
.setTitle(getString(R.string.biometricAuthTitle))
.setSubtitle(getString(R.string.biometricAuthSubTitle))
.setNegativeButtonText(getString(R.string.cancelButton)).build();
biometricPrompt.authenticate(biometricPromptBuilder);
}
@ -201,43 +146,33 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
Fragment fragmentById = fm.findFragmentById(R.id.fragment_container);
if(fragmentById instanceof SettingsFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings));
}
else if(fragmentById instanceof MyRepositoriesFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
}
else if(fragmentById instanceof StarredRepositoriesFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
}
else if(fragmentById instanceof OrganizationsFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
}
else if(fragmentById instanceof ExploreFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
}
else if(fragmentById instanceof NotificationsFragment) {
toolbarTitle.setText(R.string.pageTitleNotifications);
}
else if(fragmentById instanceof ProfileFragment) {
else if(fragmentById instanceof MyProfileFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
}
else if(fragmentById instanceof DraftsFragment) {
toolbarTitle.setText(getResources().getString(R.string.titleDrafts));
}
else if(fragmentById instanceof AdministrationFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration));
}
else if(fragmentById instanceof UserAccountsFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleUserAccounts));
}
@ -269,27 +204,26 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
String userFullNameNav = tinyDB.getString("userFullname");
String userAvatarNav = tinyDB.getString("userAvatar");
userEmail = hView.findViewById(R.id.userEmail);
userFullName = hView.findViewById(R.id.userFullname);
userAvatar = hView.findViewById(R.id.userAvatar);
userAvatarBackground = hView.findViewById(R.id.userAvatarBackground);
TextView userEmail = hView.findViewById(R.id.userEmail);
TextView userFullName = hView.findViewById(R.id.userFullname);
ImageView userAvatar = hView.findViewById(R.id.userAvatar);
ImageView userAvatarBackground = hView.findViewById(R.id.userAvatarBackground);
CardView navRecyclerViewFrame = hView.findViewById(R.id.userAccountsFrame);
List<UserAccount> userAccountsList;
userAccountsList = new ArrayList<>();
List<UserAccount> userAccountsList = new ArrayList<>();
UserAccountsApi userAccountsApi;
userAccountsApi = new UserAccountsApi(ctx);
userAccountsApi = BaseApi.getInstance(ctx, UserAccountsApi.class);
RecyclerView navRecyclerViewUserAccounts = hView.findViewById(R.id.navRecyclerViewUserAccounts);
RecyclerView navRecyclerViewUserAccounts = hView.findViewById(R.id.userAccounts);
UserAccountsNavAdapter adapterUserAccounts;
adapterUserAccounts = new UserAccountsNavAdapter(ctx, userAccountsList, drawer, toolbarTitle);
userAccountsApi.getAllAccounts().observe((AppCompatActivity) ctx, userAccounts -> {
if(userAccounts.size() > 0) {
userAccountsList.addAll(userAccounts);
navRecyclerViewUserAccounts.setAdapter(adapterUserAccounts);
navRecyclerViewFrame.setVisibility(View.VISIBLE);
}
});
@ -297,21 +231,21 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
userFullName.setTypeface(myTypeface);
if(!userEmailNav.equals("")) {
userEmail.setText(userEmailNav);
}
if(!userFullNameNav.equals("")) {
userFullName.setText(Html.fromHtml(userFullNameNav));
}
if(!userAvatarNav.equals("")) {
int avatarRadius = AppUtil.getPixelsFromDensity(ctx, 3);
PicassoService.getInstance(ctx).get()
.load(userAvatarNav)
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0))
.transform(new RoundedTransformation(avatarRadius, 0))
.resize(160, 160)
.centerCrop().into(userAvatar);
@ -322,7 +256,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
@Override
public void onSuccess() {
int textColor = new ColorInverter().getImageViewContrastColor(userAvatar);
int textColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground);
userFullName.setTextColor(textColor);
userEmail.setTextColor(textColor);
@ -335,7 +269,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
userAvatar.setOnClickListener(v -> {
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 MyProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
drawer.closeDrawers();
@ -348,7 +282,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
navigationView.getMenu().findItem(R.id.nav_administration).setVisible(tinyDB.getBoolean("userIsAdmin"));
navigationView.getMenu().findItem(R.id.nav_notifications).setVisible(new Version(currentVersion).higherOrEqual("1.12.3"));
navigationView.getMenu().findItem(R.id.nav_notifications).setVisible(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.3"));
}
@Override
@ -362,6 +297,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
toggle.syncState();
toolbar.setNavigationIcon(R.drawable.ic_menu);
String launchFragment = mainIntent.getStringExtra("launchFragment");
if(launchFragment != null) {
mainIntent.removeExtra("launchFragment");
@ -369,13 +306,12 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
switch(launchFragment) {
case "drafts":
toolbarTitle.setText(getResources().getString(R.string.titleDrafts));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new DraftsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_comments_draft);
return;
case "notifications":
case "notifications":
toolbarTitle.setText(getResources().getString(R.string.pageTitleNotifications));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_notifications);
@ -404,21 +340,31 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
case "notification":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_notifications);
setActionBarTitle(getResources().getString(R.string.pageTitleNotifications));
return;
case "explore":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit();
navigationView.setCheckedItem(R.id.nav_explore);
return;
case "profile":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
return;
case "admin":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AdministrationFragment()).commit();
navigationView.setCheckedItem(R.id.nav_administration);
return;
}
}
if(savedInstanceState == null) {
if(!new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.3")) {
if(tinyDB.getInt("homeScreenId") == 7) {
tinyDB.putInt("homeScreenId", 0);
}
}
@ -445,7 +391,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
case 4:
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 MyProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
break;
@ -583,7 +529,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
else if(id == R.id.nav_profile) {
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 MyProfileFragment()).commit();
}
else if(id == R.id.nav_repositories) {
@ -659,29 +605,22 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
private void giteaVersion() {
final TinyDB tinyDb = TinyDB.getInstance(appCtx);
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
Call<GiteaVersion> callVersion = RetrofitClient.getApiInterface(ctx).getGiteaVersionWithToken(token);
Call<GiteaVersion> callVersion = RetrofitClient.getApiInterface(ctx).getGiteaVersionWithToken(Authorization.get(ctx));
callVersion.enqueue(new Callback<GiteaVersion>() {
@Override
public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) {
if(responseVersion.code() == 200) {
if(responseVersion.code() == 200 && responseVersion.body() != null) {
String version = responseVersion.body().getVersion();
GiteaVersion version = responseVersion.body();
assert version != null;
tinyDb.putString("giteaVersion", version.getVersion());
tinyDB.putString("giteaVersion", version);
BaseApi.getInstance(ctx, UserAccountsApi.class).updateServerVersion(version, tinyDB.getInt("currentActiveAccountId"));
}
}
@Override
public void onFailure(@NonNull Call<GiteaVersion> callVersion, @NonNull Throwable t) {
Log.e("onFailure-version", t.toString());
}
});

View File

@ -12,6 +12,7 @@ import com.google.gson.JsonElement;
import org.gitnex.tea4j.models.MergePullRequest;
import org.gitnex.tea4j.models.MergePullRequestSpinner;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.PullRequestActions;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityMergePullRequestBinding;
import org.mian.gitnex.helpers.AlertDialogs;
@ -187,7 +188,7 @@ public class MergePullRequestActivity extends BaseActivity {
final String repoOwner = parts[0];
final String repoName = parts[1];
deleteBranchFunction(repoOwner, repoName);
PullRequestActions.deleteHeadBranch(ctx, repoOwner, repoName, tinyDB.getString("prHeadBranch"), false);
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg));
tinyDB.putBoolean("prMerged", true);
@ -201,7 +202,7 @@ public class MergePullRequestActivity extends BaseActivity {
final String repoOwner = parts[0];
final String repoName = parts[1];
deleteBranchFunction(repoOwner, repoName);
PullRequestActions.deleteHeadBranch(ctx, repoOwner, repoName, tinyDB.getString("prHeadBranch"), false);
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg));
tinyDB.putBoolean("prMerged", true);
@ -253,36 +254,6 @@ public class MergePullRequestActivity extends BaseActivity {
}
private void deleteBranchFunction(String repoOwner, String repoName) {
String branchName = tinyDB.getString("prHeadBranch");
Call<JsonElement> call = RetrofitClient
.getApiInterface(ctx)
.deleteBranch(Authorization.get(ctx), repoOwner, repoName, branchName);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 204) {
Log.i("deleteBranch", "Branch deleted successfully");
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
enableProcessButton();
}
});
}
private void disableProcessButton() {
viewBinding.mergeButton.setEnabled(false);

View File

@ -30,7 +30,7 @@ import retrofit2.Callback;
* Author M M Arif
*/
public class ProfileEmailActivity extends BaseActivity {
public class MyProfileEmailActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private EditText userEmail;

View File

@ -0,0 +1,143 @@
package org.mian.gitnex.activities;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import org.mian.gitnex.R;
import org.mian.gitnex.fragments.profile.DetailFragment;
import org.mian.gitnex.fragments.profile.FollowersFragment;
import org.mian.gitnex.fragments.profile.FollowingFragment;
import org.mian.gitnex.fragments.profile.OrganizationsFragment;
import org.mian.gitnex.fragments.profile.RepositoriesFragment;
import org.mian.gitnex.fragments.profile.StarredRepositoriesFragment;
import org.mian.gitnex.helpers.Toasty;
import java.util.Objects;
/**
* Author M M Arif
*/
public class ProfileActivity extends BaseActivity {
private String username;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
Intent profileIntent = getIntent();
Typeface myTypeface;
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = findViewById(R.id.toolbarTitle);
if(profileIntent.getStringExtra("username") != null && !Objects.equals(profileIntent.getStringExtra("username"), "")) {
username = profileIntent.getStringExtra("username");
}
else {
Toasty.warning(ctx, ctx.getResources().getString(R.string.userInvalidUserName));
finish();
}
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(username);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ViewPager2 viewPager = findViewById(R.id.profileContainer);
viewPager.setOffscreenPageLimit(1);
TabLayout tabLayout = findViewById(R.id.tabs);
switch(tinyDB.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf");
break;
}
toolbarTitle.setTypeface(myTypeface);
toolbarTitle.setText(username);
viewPager.setAdapter(new ViewPagerAdapter(this));
String[] tabTitles = {ctx.getResources().getString(R.string.tabTextInfo), ctx.getResources().getString(R.string.navRepos), ctx.getResources().getString(R.string.navStarredRepos), ctx.getResources().getString(R.string.navOrg), ctx.getResources().getString(R.string.profileTabFollowers), ctx.getResources().getString(R.string.profileTabFollowing)};
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText(tabTitles[position])).attach();
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildCount = vgTab.getChildCount();
for (int i = 0; i < tabChildCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(myTypeface);
}
}
}
}
public class ViewPagerAdapter extends FragmentStateAdapter {
public ViewPagerAdapter(@NonNull FragmentActivity fa) { super(fa); }
@NonNull
@Override
public Fragment createFragment(int position) {
switch(position) {
case 0: // detail
return DetailFragment.newInstance(username);
case 1: // repos
return RepositoriesFragment.newInstance(username);
case 2: // starred repos
return StarredRepositoriesFragment.newInstance(username);
case 3: // organizations
return OrganizationsFragment.newInstance(username);
case 4: // followers
return FollowersFragment.newInstance(username);
case 5: // following
return FollowingFragment.newInstance(username);
}
return null;
}
@Override
public int getItemCount() {
return 6;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if(id == android.R.id.home) {
finish();
return true;
}
else {
return super.onOptionsItemSelected(item);
}
}
}

View File

@ -17,6 +17,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
@ -70,9 +71,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
private FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone;
private FragmentRefreshListenerFiles fragmentRefreshListenerFiles;
private String loginUid;
private String instanceToken;
private String repositoryOwner;
private String repositoryName;
@ -93,15 +91,20 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = findViewById(R.id.toolbar_title);
ImageView repoTypeToolbar = findViewById(R.id.repoTypeToolbar);
if(tinyDB.getString("repoType").equalsIgnoreCase("private")) {
repoTypeToolbar.setVisibility(View.VISIBLE);
}
else {
repoTypeToolbar.setVisibility(View.GONE);
}
toolbarTitle.setText(repositoryName);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(repositoryName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
loginUid = tinyDB.getString("loginUid");
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
tinyDB.putString("repoIssuesState", "open");
tinyDB.putString("repoPrState", "open");
tinyDB.putString("milestoneState", "open");
@ -229,13 +232,84 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
mainIntent.removeExtra("goToSection");
mainIntent.removeExtra("goToSectionType");
if(goToSectionType.equals("issue")) {
RepoDetailActivity.mViewPager.setCurrentItem(2);
}
else if(goToSectionType.equals("pull")) {
RepoDetailActivity.mViewPager.setCurrentItem(3);
switch(goToSectionType) {
case "branchesList":
RepoDetailActivity.mViewPager.setCurrentItem(1);
chooseBranch();
break;
case "branch":
RepoDetailActivity.mViewPager.setCurrentItem(1);
String selectedBranch = mainIntent.getStringExtra("selectedBranch");
tinyDB.putString("repoBranch", selectedBranch);
if(getFragmentRefreshListenerFiles() != null) {
getFragmentRefreshListenerFiles().onRefresh(selectedBranch);
}
break;
case "file":
RepoDetailActivity.mViewPager.setCurrentItem(1);
String branch1 = mainIntent.getStringExtra("branch");
tinyDB.putString("repoBranch", branch1);
if(getFragmentRefreshListenerFiles() != null) {
getFragmentRefreshListenerFiles().onRefresh(branch1);
}
Intent intent = new Intent(ctx, FileViewActivity.class);
intent.putExtra("file", mainIntent.getSerializableExtra("file"));
startActivity(intent);
break;
case "dir":
RepoDetailActivity.mViewPager.setCurrentItem(1);
String branch2 = mainIntent.getStringExtra("branch");
tinyDB.putString("repoBranch", branch2);
if(getFragmentRefreshListenerFiles() != null) {
getFragmentRefreshListenerFiles().onRefresh(branch2);
}
//((SectionsPagerAdapter) Objects.requireNonNull(RepoDetailActivity.mViewPager.getAdapter())).getItem(1);
break;
case "commitsList":
RepoDetailActivity.mViewPager.setCurrentItem(1);
String branch = mainIntent.getStringExtra("branchName");
tinyDB.putString("repoBranch", branch);
if(getFragmentRefreshListenerFiles() != null) {
getFragmentRefreshListenerFiles().onRefresh(branch);
}
Intent intent1 = new Intent(ctx, CommitsActivity.class);
intent1.putExtra("branchName", branch);
ctx.startActivity(intent1);
break;
case "issue":
RepoDetailActivity.mViewPager.setCurrentItem(2);
break;
case "issueNew":
RepoDetailActivity.mViewPager.setCurrentItem(2);
startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class));
break;
case "pull":
RepoDetailActivity.mViewPager.setCurrentItem(3);
break;
case "pullNew":
RepoDetailActivity.mViewPager.setCurrentItem(3);
startActivity(new Intent(RepoDetailActivity.this, CreatePullRequestActivity.class));
break;
case "releases":
RepoDetailActivity.mViewPager.setCurrentItem(4);
break;
case "newRelease":
RepoDetailActivity.mViewPager.setCurrentItem(4);
startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
break;
case "milestones":
RepoDetailActivity.mViewPager.setCurrentItem(5);
break;
case "milestonesNew":
RepoDetailActivity.mViewPager.setCurrentItem(5);
startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class));
break;
case "labels":
RepoDetailActivity.mViewPager.setCurrentItem(6);
break;
case "settings":
startActivity(new Intent(RepoDetailActivity.this, RepositorySettingsActivity.class));
break;
}
}
@ -267,46 +341,49 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
int id = item.getItemId();
switch(id) {
case android.R.id.home:
finish();
return true;
case R.id.repoMenu:
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment();
bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet");
return true;
case R.id.filter:
BottomSheetIssuesFilterFragment filterBottomSheet = new BottomSheetIssuesFilterFragment();
filterBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuBottomSheet");
return true;
case R.id.filterPr:
BottomSheetPullRequestFilterFragment filterPrBottomSheet = new BottomSheetPullRequestFilterFragment();
filterPrBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuPrBottomSheet");
return true;
case R.id.filterMilestone:
BottomSheetMilestonesFilterFragment filterMilestoneBottomSheet = new BottomSheetMilestonesFilterFragment();
filterMilestoneBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuMilestoneBottomSheet");
return true;
case R.id.switchBranches:
chooseBranch();
return true;
case R.id.branchCommits:
Intent intent = new Intent(ctx, CommitsActivity.class);
intent.putExtra("branchName", tinyDB.getString("repoBranch"));
ctx.startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
if(id == android.R.id.home) {
finish();
return true;
}
else if(id == R.id.repoMenu) {
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment();
bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet");
return true;
}
else if(id == R.id.filter) {
BottomSheetIssuesFilterFragment filterBottomSheet = new BottomSheetIssuesFilterFragment();
filterBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuBottomSheet");
return true;
}
else if(id == R.id.filterPr) {
BottomSheetPullRequestFilterFragment filterPrBottomSheet = new BottomSheetPullRequestFilterFragment();
filterPrBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuPrBottomSheet");
return true;
}
else if(id == R.id.filterMilestone) {
BottomSheetMilestonesFilterFragment filterMilestoneBottomSheet = new BottomSheetMilestonesFilterFragment();
filterMilestoneBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuMilestoneBottomSheet");
return true;
}
else if(id == R.id.switchBranches) {
chooseBranch();
return true;
}
else if(id == R.id.branchCommits) {
Intent intent = new Intent(ctx, CommitsActivity.class);
intent.putExtra("branchName", tinyDB.getString("repoBranch"));
ctx.startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
@ -421,7 +498,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
Call<List<Branches>> call = RetrofitClient
.getApiInterface(ctx)
.getBranches(instanceToken, repositoryOwner, repositoryName);
.getBranches(Authorization.get(ctx), repositoryOwner, repositoryName);
call.enqueue(new Callback<List<Branches>>() {

View File

@ -45,7 +45,7 @@ public class RepoForksActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private TextView noData;
private ProgressBar progressBar;
private String TAG = "RepositoryForks";
private final String TAG = "RepositoryForks";
private int resultLimit = Constants.resultLimitOldGiteaInstances;
private int pageSize = 1;

View File

@ -14,6 +14,7 @@ import org.gitnex.tea4j.models.RepositoryTransfer;
import org.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.databinding.ActivityRepositorySettingsBinding;
import org.mian.gitnex.databinding.CustomRepositoryDeleteDialogBinding;
@ -139,7 +140,7 @@ public class RepositorySettingsActivity extends BaseActivity {
Toasty.success(ctx, getString(R.string.repoTransferSuccess));
finish();
RepositoriesApi.deleteRepository((int) tinyDB.getLong("repositoryId", 0));
BaseApi.getInstance(ctx, RepositoriesApi.class).deleteRepository((int) tinyDB.getLong("repositoryId", 0));
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
RepositorySettingsActivity.this.startActivity(intent);
}
@ -220,7 +221,7 @@ public class RepositorySettingsActivity extends BaseActivity {
Toasty.success(ctx, getString(R.string.repoDeletionSuccess));
finish();
RepositoriesApi.deleteRepository((int) tinyDB.getLong("repositoryId", 0));
BaseApi.getInstance(ctx, RepositoriesApi.class).deleteRepository((int) tinyDB.getLong("repositoryId", 0));
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
RepositorySettingsActivity.this.startActivity(intent);
}
@ -383,7 +384,7 @@ public class RepositorySettingsActivity extends BaseActivity {
if(!repositoryName.equals(repoName)) {
finish();
RepositoriesApi.updateRepositoryOwnerAndName(repositoryOwner, repoName, (int) tinyDB.getLong("repositoryId", 0));
BaseApi.getInstance(ctx, RepositoriesApi.class).updateRepositoryOwnerAndName(repositoryOwner, repoName, (int) tinyDB.getLong("repositoryId", 0));
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
RepositorySettingsActivity.this.startActivity(intent);
}

View File

@ -1,14 +1,20 @@
package org.mian.gitnex.activities;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TimePicker;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import com.google.android.material.switchmaterial.SwitchMaterial;
import org.jetbrains.annotations.NotNull;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsAppearanceBinding;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
/**
@ -19,13 +25,13 @@ public class SettingsAppearanceActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private static final String[] timeList = {"Pretty", "Normal"};
private static String[] timeList;
private static int timeSelectedChoice = 0;
private static final String[] customFontList = {"Roboto", "Manrope", "Source Code Pro"};
private static String[] customFontList;
private static int customFontSelectedChoice = 0;
private static final String[] themeList = {"Dark", "Light", "Auto (Light / Dark)", "Retro", "Auto (Retro / Dark)", "Pitch Black"};
private static String[] themeList;
private static int themeSelectedChoice = 0;
@Override
@ -38,48 +44,51 @@ public class SettingsAppearanceActivity extends BaseActivity {
ImageView closeActivity = activitySettingsAppearanceBinding.close;
final TextView tvDateTimeSelected = activitySettingsAppearanceBinding.tvDateTimeSelected; // setter for time
final TextView customFontSelected = activitySettingsAppearanceBinding.customFontSelected; // setter for custom font
final TextView themeSelected = activitySettingsAppearanceBinding.themeSelected; // setter for theme
LinearLayout timeFrame = activitySettingsAppearanceBinding.timeFrame;
LinearLayout customFontFrame = activitySettingsAppearanceBinding.customFontFrame;
LinearLayout themeFrame = activitySettingsAppearanceBinding.themeSelectionFrame;
LinearLayout lightTimeFrame = activitySettingsAppearanceBinding.lightThemeTimeSelectionFrame;
LinearLayout darkTimeFrame = activitySettingsAppearanceBinding.darkThemeTimeSelectionFrame;
SwitchMaterial counterBadgesSwitch = activitySettingsAppearanceBinding.switchCounterBadge;
timeList = getResources().getStringArray(R.array.timeFormats);
customFontList = getResources().getStringArray(R.array.fonts);
themeList = getResources().getStringArray(R.array.themes);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
if(!tinyDB.getString("timeStr").isEmpty()) {
String lightMinute = String.valueOf(tinyDB.getInt("lightThemeTimeMinute"));
String lightHour = String.valueOf(tinyDB.getInt("lightThemeTimeHour"));
if(lightMinute.length() == 1) lightMinute = "0" + lightMinute;
if(lightHour.length() == 1) lightHour = "0" + lightHour;
tvDateTimeSelected.setText(tinyDB.getString("timeStr"));
String darkMinute = String.valueOf(tinyDB.getInt("darkThemeTimeMinute"));
String darkHour = String.valueOf(tinyDB.getInt("darkThemeTimeHour"));
if(darkMinute.length() == 1) darkMinute = "0" + darkMinute;
if(darkHour.length() == 1) darkHour = "0" + darkHour;
activitySettingsAppearanceBinding.lightThemeSelectedTime.setText(ctx.getResources().getString(R.string.settingsThemeTimeSelectedHint, lightHour,
lightMinute));
activitySettingsAppearanceBinding.darkThemeSelectedTime.setText(ctx.getResources().getString(R.string.settingsThemeTimeSelectedHint, darkHour,
darkMinute));
activitySettingsAppearanceBinding.tvDateTimeSelected.setText(tinyDB.getString("timeStr"));
activitySettingsAppearanceBinding.customFontSelected.setText(tinyDB.getString("customFontStr", "Manrope"));
activitySettingsAppearanceBinding.themeSelected.setText(tinyDB.getString("themeStr", "Dark"));
if(tinyDB.getString("themeStr").startsWith("Auto")) {
darkTimeFrame.setVisibility(View.VISIBLE);
lightTimeFrame.setVisibility(View.VISIBLE);
}
else {
darkTimeFrame.setVisibility(View.GONE);
lightTimeFrame.setVisibility(View.GONE);
}
if(!tinyDB.getString("customFontStr").isEmpty()) {
customFontSelected.setText(tinyDB.getString("customFontStr"));
}
if(!tinyDB.getString("themeStr").isEmpty()) {
themeSelected.setText(tinyDB.getString("themeStr"));
}
if(timeSelectedChoice == 0) {
timeSelectedChoice = tinyDB.getInt("timeId");
}
if(customFontSelectedChoice == 0) {
customFontSelectedChoice = tinyDB.getInt("customFontId", 1);
}
if(themeSelectedChoice == 0) {
themeSelectedChoice = tinyDB.getInt("themeId");
}
timeSelectedChoice = tinyDB.getInt("timeId");
customFontSelectedChoice = tinyDB.getInt("customFontId", 1);
themeSelectedChoice = tinyDB.getInt("themeId");
counterBadgesSwitch.setChecked(tinyDB.getBoolean("enableCounterBadges"));
@ -101,7 +110,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
tsBuilder.setSingleChoiceItems(themeList, themeSelectedChoice, (dialogInterfaceTheme, i) -> {
themeSelectedChoice = i;
themeSelected.setText(themeList[i]);
activitySettingsAppearanceBinding.themeSelected.setText(themeList[i]);
tinyDB.putString("themeStr", themeList[i]);
tinyDB.putInt("themeId", i);
@ -116,6 +125,16 @@ public class SettingsAppearanceActivity extends BaseActivity {
cfDialog.show();
});
lightTimeFrame.setOnClickListener(view -> {
LightTimePicker timePicker = new LightTimePicker();
timePicker.show(getSupportFragmentManager(), "timePicker");
});
darkTimeFrame.setOnClickListener(view -> {
DarkTimePicker timePicker = new DarkTimePicker();
timePicker.show(getSupportFragmentManager(), "timePicker");
});
// custom font dialog
customFontFrame.setOnClickListener(view -> {
@ -127,7 +146,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
cfBuilder.setSingleChoiceItems(customFontList, customFontSelectedChoice, (dialogInterfaceCustomFont, i) -> {
customFontSelectedChoice = i;
customFontSelected.setText(customFontList[i]);
activitySettingsAppearanceBinding.customFontSelected.setText(customFontList[i]);
tinyDB.putString("customFontStr", customFontList[i]);
tinyDB.putInt("customFontId", i);
@ -153,17 +172,17 @@ public class SettingsAppearanceActivity extends BaseActivity {
tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, (dialogInterfaceTime, i) -> {
timeSelectedChoice = i;
tvDateTimeSelected.setText(timeList[i]);
activitySettingsAppearanceBinding.tvDateTimeSelected.setText(timeList[i]);
tinyDB.putString("timeStr", timeList[i]);
tinyDB.putInt("timeId", i);
if("Normal".equals(timeList[i])) {
tinyDB.putString("dateFormat", "normal");
}
else {
tinyDB.putString("dateFormat", "pretty");
switch(i) {
case 0:
tinyDB.putString("dateFormat", "pretty");
break;
case 1:
tinyDB.putString("dateFormat", "normal");
break;
}
dialogInterfaceTime.dismiss();
@ -180,4 +199,54 @@ public class SettingsAppearanceActivity extends BaseActivity {
onClickListener = view -> finish();
}
public static class LightTimePicker extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
TinyDB db = TinyDB.getInstance(getContext());
@NotNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int hour = db.getInt("lightThemeTimeHour");
int minute = db.getInt("lightThemeTimeMinute");
return new TimePickerDialog(getActivity(), this, hour, minute, true);
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
db.putInt("lightThemeTimeHour", hourOfDay);
db.putInt("lightThemeTimeMinute", minute);
db.putBoolean("refreshParent", true);
requireActivity().overridePendingTransition(0, 0);
this.dismiss();
Toasty.success(requireActivity().getApplicationContext(), requireContext().getResources().getString(R.string.settingsSave));
requireActivity().recreate();
}
}
public static class DarkTimePicker extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
TinyDB db = TinyDB.getInstance(getContext());
@NotNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int hour = db.getInt("darkThemeTimeHour");
int minute = db.getInt("darkThemeTimeMinute");
return new TimePickerDialog(getActivity(), this, hour, minute, true);
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
db.putInt("darkThemeTimeHour", hourOfDay);
db.putInt("darkThemeTimeMinute", minute);
db.putBoolean("refreshParent", true);
requireActivity().overridePendingTransition(0, 0);
this.dismiss();
Toasty.success(requireActivity().getApplicationContext(), requireContext().getResources().getString(R.string.settingsSave));
requireActivity().recreate();
}
}
}

View File

@ -23,7 +23,7 @@ public class SettingsGeneralActivity extends BaseActivity {
private List<String> homeScreenList;
private static int homeScreenSelectedChoice = 0;
private List<String> defaultScreen;
private List<String> linkHandlerDefaultScreen;
private static int defaultLinkHandlerScreenSelectedChoice = 0;
@Override
@ -38,20 +38,16 @@ public class SettingsGeneralActivity extends BaseActivity {
viewBinding.close.setOnClickListener(onClickListener);
// home screen
String[] homeDefaultScreen_ = {getResources().getString(R.string.pageTitleMyRepos), getResources().getString(R.string.pageTitleStarredRepos), getResources().getString(R.string.pageTitleOrganizations),
getResources().getString(R.string.pageTitleRepositories), getResources().getString(R.string.pageTitleProfile), getResources().getString(R.string.pageTitleExplore),
getResources().getString(R.string.titleDrafts)};
String[] appHomeDefaultScreen = getResources().getStringArray(R.array.appDefaultHomeScreen);
String[] homeDefaultScreenNew = {getResources().getString(R.string.pageTitleMyRepos), getResources().getString(R.string.pageTitleStarredRepos), getResources().getString(R.string.pageTitleOrganizations),
getResources().getString(R.string.pageTitleRepositories), getResources().getString(R.string.pageTitleProfile), getResources().getString(R.string.pageTitleExplore),
getResources().getString(R.string.titleDrafts), getResources().getString(R.string.pageTitleNotifications)};
String[] appHomeDefaultScreenNew = getResources().getStringArray(R.array.appDefaultHomeScreenNew);
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.3")) {
homeDefaultScreen_ = homeDefaultScreenNew;
appHomeDefaultScreen = appHomeDefaultScreenNew;
}
homeScreenList = new ArrayList<>(Arrays.asList(homeDefaultScreen_));
homeScreenList = new ArrayList<>(Arrays.asList(appHomeDefaultScreen));
String[] homeScreenArray = new String[homeScreenList.size()];
homeScreenList.toArray(homeScreenArray);
@ -113,34 +109,14 @@ public class SettingsGeneralActivity extends BaseActivity {
// home screen
// link handler
String[] defaultScreen_ = {getResources().getString(R.string.generalDeepLinkSelectedText), getResources().getString(R.string.navRepos), getResources().getString(R.string.navOrg), getResources().getString(R.string.pageTitleNotifications), getResources().getString(R.string.navExplore)};
defaultScreen = new ArrayList<>(Arrays.asList(defaultScreen_));
String[] linkHandlerDefaultScreenList = getResources().getStringArray(R.array.linkHandlerDefaultScreen);
linkHandlerDefaultScreen = new ArrayList<>(Arrays.asList(linkHandlerDefaultScreenList));
String[] linksArray = new String[defaultScreen.size()];
defaultScreen.toArray(linksArray);
String[] linksArray = new String[linkHandlerDefaultScreen.size()];
linkHandlerDefaultScreen.toArray(linksArray);
if(defaultLinkHandlerScreenSelectedChoice == 0) {
defaultLinkHandlerScreenSelectedChoice = tinyDB.getInt("defaultScreenId");
viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.generalDeepLinkSelectedText));
}
if(defaultLinkHandlerScreenSelectedChoice == 1) {
viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.navRepos));
}
else if(defaultLinkHandlerScreenSelectedChoice == 2) {
viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.navOrg));
}
else if(defaultLinkHandlerScreenSelectedChoice == 3) {
viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.pageTitleNotifications));
}
else if(defaultLinkHandlerScreenSelectedChoice == 4) {
viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.navExplore));
}
defaultLinkHandlerScreenSelectedChoice = tinyDB.getInt("defaultScreenId");
viewBinding.generalDeepLinkSelected.setText(linksArray[defaultLinkHandlerScreenSelectedChoice]);
viewBinding.setDefaultLinkHandler.setOnClickListener(setDefaultLinkHandler -> {

View File

@ -43,7 +43,13 @@ public class SettingsNotificationsActivity extends BaseActivity {
viewBinding.enableNotificationsMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
tinyDB.putBoolean("notificationsEnabled", isChecked);
if(!isChecked) Notifications.stopWorker(ctx);
if(isChecked) {
Notifications.startWorker(ctx);
} else {
Notifications.stopWorker(ctx);
}
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});

View File

@ -31,10 +31,10 @@ public class SettingsSecurityActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private static final String[] cacheSizeDataList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"};
private static String[] cacheSizeDataList;
private static int cacheSizeDataSelectedChoice = 0;
private static final String[] cacheSizeImagesList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"};
private static String[] cacheSizeImagesList;
private static int cacheSizeImagesSelectedChoice = 0;
@Override
@ -61,6 +61,9 @@ public class SettingsSecurityActivity extends BaseActivity {
SwitchMaterial switchBiometric = activitySettingsSecurityBinding.switchBiometric;
cacheSizeDataList = getResources().getStringArray(R.array.cacheSizeList);
cacheSizeImagesList = getResources().getStringArray(R.array.cacheSizeList);
if(!tinyDB.getString("cacheSizeStr").isEmpty()) {
cacheSizeDataSelected.setText(tinyDB.getString("cacheSizeStr"));

View File

@ -11,6 +11,9 @@ import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsTranslationBinding;
import org.mian.gitnex.helpers.Toasty;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.TreeMap;
/**
* Author M M Arif
@ -20,8 +23,6 @@ public class SettingsTranslationActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private static String[] langList = {"English", "Arabic", "Chinese", "Czech", "Finnish", "French", "German", "Italian", "Latvian", "Persian",
"Polish", "Portuguese/Brazilian", "Russian", "Serbian", "Spanish", "Turkish", "Ukrainian"};
private static int langSelectedChoice = 0;
@Override
@ -29,6 +30,12 @@ public class SettingsTranslationActivity extends BaseActivity {
super.onCreate(savedInstanceState);
LinkedHashMap<String, String> langs = new LinkedHashMap<>();
langs.put("", getString(R.string.settingsLanguageSystem));
for(String langCode : getResources().getStringArray(R.array.languages)) {
langs.put(langCode, getLanguageDisplayName(langCode));
}
ActivitySettingsTranslationBinding activitySettingsTranslationBinding = ActivitySettingsTranslationBinding.inflate(getLayoutInflater());
setContentView(activitySettingsTranslationBinding.getRoot());
@ -52,15 +59,9 @@ public class SettingsTranslationActivity extends BaseActivity {
});
if(!tinyDB.getString("localeStr").isEmpty()) {
tvLanguageSelected.setText(tinyDB.getString("localeStr"));
tvLanguageSelected.setText(tinyDB.getString("localeStr"));
}
if(langSelectedChoice == 0) {
langSelectedChoice = tinyDB.getInt("langId");
}
langSelectedChoice = tinyDB.getInt("langId");
// language dialog
langFrame.setOnClickListener(view -> {
@ -70,89 +71,18 @@ public class SettingsTranslationActivity extends BaseActivity {
lBuilder.setTitle(R.string.settingsLanguageSelectorDialogTitle);
lBuilder.setCancelable(langSelectedChoice != -1);
lBuilder.setSingleChoiceItems(langList, langSelectedChoice, (dialogInterface, i) -> {
lBuilder.setSingleChoiceItems(langs.values().toArray(new String[0]), langSelectedChoice, (dialogInterface, i) -> {
langSelectedChoice = i;
tvLanguageSelected.setText(langList[i]);
tinyDB.putString("localeStr", langList[i]);
String selectedLanguage = langs.keySet().toArray(new String[0])[i];
tinyDB.putString("localeStr", langs.get(selectedLanguage));
tinyDB.putInt("langId", i);
switch(langList[i]) {
case "Arabic":
tinyDB.putString("locale", "ar");
break;
case "Chinese":
tinyDB.putString("locale", "zh");
break;
case "Czech":
tinyDB.putString("locale", "cs");
break;
case "Finnish":
tinyDB.putString("locale", "fi");
break;
case "French":
tinyDB.putString("locale", "fr");
break;
case "German":
tinyDB.putString("locale", "de");
break;
case "Italian":
tinyDB.putString("locale", "it");
break;
case "Latvian":
tinyDB.putString("locale", "lv");
break;
case "Persian":
tinyDB.putString("locale", "fa");
break;
case "Polish":
tinyDB.putString("locale", "pl");
break;
case "Portuguese/Brazilian":
tinyDB.putString("locale", "pt");
break;
case "Russian":
tinyDB.putString("locale", "ru");
break;
case "Serbian":
tinyDB.putString("locale", "sr");
break;
case "Spanish":
tinyDB.putString("locale", "es");
break;
case "Turkish":
tinyDB.putString("locale", "tr");
break;
case "Ukrainian":
tinyDB.putString("locale", "uk");
break;
default:
tinyDB.putString("locale", "en");
break;
}
tinyDB.putString("locale", selectedLanguage);
tinyDB.putBoolean("refreshParent", true);
this.recreate();
this.overridePendingTransition(0, 0);
dialogInterface.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
this.recreate();
});
lBuilder.setNeutralButton(getString(R.string.cancelButton), null);
@ -167,4 +97,10 @@ public class SettingsTranslationActivity extends BaseActivity {
onClickListener = view -> finish();
}
private static String getLanguageDisplayName(String langCode) {
Locale english = new Locale("en");
Locale translated = new Locale(langCode);
return String.format("%s (%s)", translated.getDisplayName(translated), translated.getDisplayName(english));
}
}

View File

@ -31,30 +31,26 @@ import retrofit2.Callback;
public class AdminCronTasksAdapter extends RecyclerView.Adapter<AdminCronTasksAdapter.CronTasksViewHolder> {
private final List<CronTasks> tasksList;
private final Context mCtx;
private static TinyDB tinyDb;
static class CronTasksViewHolder extends RecyclerView.ViewHolder {
private CronTasks cronTasks;
private final ImageView runTask;
private final TextView taskName;
private final LinearLayout cronTasksInfo;
private final LinearLayout cronTasksRun;
private CronTasksViewHolder(View itemView) {
super(itemView);
Context ctx = itemView.getContext();
final String locale = tinyDb.getString("locale");
final Locale locale = ctx.getResources().getConfiguration().locale;
final String timeFormat = tinyDb.getString("dateFormat");
runTask = itemView.findViewById(R.id.runTask);
ImageView runTask = itemView.findViewById(R.id.runTask);
taskName = itemView.findViewById(R.id.taskName);
cronTasksInfo = itemView.findViewById(R.id.cronTasksInfo);
cronTasksRun = itemView.findViewById(R.id.cronTasksRun);
LinearLayout cronTasksInfo = itemView.findViewById(R.id.cronTasksInfo);
LinearLayout cronTasksRun = itemView.findViewById(R.id.cronTasksRun);
cronTasksInfo.setOnClickListener(taskInfo -> {
@ -62,10 +58,10 @@ public class AdminCronTasksAdapter extends RecyclerView.Adapter<AdminCronTasksAd
String lastRun = "";
if(cronTasks.getNext() != null) {
nextRun = TimeHelper.formatTime(cronTasks.getNext(), new Locale(locale), timeFormat, ctx);
nextRun = TimeHelper.formatTime(cronTasks.getNext(), locale, timeFormat, ctx);
}
if(cronTasks.getPrev() != null) {
lastRun = TimeHelper.formatTime(cronTasks.getPrev(), new Locale(locale), timeFormat, ctx);
lastRun = TimeHelper.formatTime(cronTasks.getPrev(), locale, timeFormat, ctx);
}
View view = LayoutInflater.from(ctx).inflate(R.layout.layout_cron_task_info, null);
@ -96,10 +92,9 @@ public class AdminCronTasksAdapter extends RecyclerView.Adapter<AdminCronTasksAd
}
}
public AdminCronTasksAdapter(Context mCtx, List<CronTasks> tasksListMain) {
public AdminCronTasksAdapter(Context ctx, List<CronTasks> tasksListMain) {
tinyDb = TinyDB.getInstance(mCtx);
this.mCtx = mCtx;
tinyDb = TinyDB.getInstance(ctx);
this.tasksList = tasksListMain;
}

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@ -15,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -28,10 +30,10 @@ import java.util.List;
public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdapter.UsersViewHolder> implements Filterable {
private final List<UserInfo> usersList;
private final Context mCtx;
private final Context context;
private final List<UserInfo> usersListFull;
static class UsersViewHolder extends RecyclerView.ViewHolder {
class UsersViewHolder extends RecyclerView.ViewHolder {
private String userLoginId;
@ -51,18 +53,22 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
userEmail = itemView.findViewById(R.id.userEmail);
userRole = itemView.findViewById(R.id.userRole);
userAvatar.setOnClickListener(loginId -> {
Context context = loginId.getContext();
itemView.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
userAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
public AdminGetUsersAdapter(Context mCtx, List<UserInfo> usersListMain) {
public AdminGetUsersAdapter(Context ctx, List<UserInfo> usersListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.usersList = usersListMain;
usersListFull = new ArrayList<>(usersList);
}
@ -79,17 +85,18 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
public void onBindViewHolder(@NonNull AdminGetUsersAdapter.UsersViewHolder holder, int position) {
UserInfo currentItem = usersList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
holder.userLoginId = currentItem.getLogin();
if(!currentItem.getFullname().equals("")) {
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
}
else {
holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userFullName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userName.setVisibility(View.GONE);
}
@ -107,12 +114,12 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
holder.userRole.setVisibility(View.VISIBLE);
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.textColor(ResourcesCompat.getColor(mCtx.getResources(), R.color.colorWhite, null))
.textColor(ResourcesCompat.getColor(context.getResources(), R.color.colorWhite, null))
.fontSize(44)
.width(180)
.height(60)
.endConfig()
.buildRoundRect(mCtx.getResources().getString(R.string.userRoleAdmin).toLowerCase(), ResourcesCompat.getColor(mCtx.getResources(), R.color.releasePre, null), 8);
.buildRoundRect(context.getResources().getString(R.string.userRoleAdmin).toLowerCase(), ResourcesCompat.getColor(context.getResources(), R.color.releasePre, null), 8);
holder.userRole.setImageDrawable(drawable);
}
else {
@ -120,7 +127,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
holder.userRole.setVisibility(View.GONE);
}
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
@Override

View File

@ -13,6 +13,7 @@ import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.Collaborators;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import java.util.ArrayList;
import java.util.LinkedHashSet;
@ -24,7 +25,7 @@ import java.util.List;
public class AssigneesListAdapter extends RecyclerView.Adapter<AssigneesListAdapter.AssigneesViewHolder> {
private final Context mCtx;
private final Context context;
private final List<Collaborators> assigneesList;
private List<String> assigneesStrings = new ArrayList<>();
private List<String> currentAssignees;
@ -36,9 +37,9 @@ public class AssigneesListAdapter extends RecyclerView.Adapter<AssigneesListAdap
void assigneesInterface(List<String> data);
}
public AssigneesListAdapter(Context mCtx, List<Collaborators> dataMain, AssigneesListAdapterListener assigneesListener, List<String> currentAssignees) {
public AssigneesListAdapter(Context ctx, List<Collaborators> dataMain, AssigneesListAdapterListener assigneesListener, List<String> currentAssignees) {
this.mCtx = mCtx;
this.context = ctx;
this.assigneesList = dataMain;
this.assigneesListener = assigneesListener;
this.currentAssignees = currentAssignees;
@ -73,6 +74,7 @@ public class AssigneesListAdapter extends RecyclerView.Adapter<AssigneesListAdap
public void onBindViewHolder(@NonNull AssigneesListAdapter.AssigneesViewHolder holder, int position) {
Collaborators currentItem = assigneesList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
if(currentItem.getFull_name().equals("")) {
@ -83,7 +85,7 @@ public class AssigneesListAdapter extends RecyclerView.Adapter<AssigneesListAdap
holder.assigneesName.setText(Html.fromHtml(currentItem.getFull_name()));
}
PicassoService
.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(holder.assigneesAvatar);
.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(holder.assigneesAvatar);
for(int i = 0; i < assigneesList.size(); i++) {

View File

@ -2,6 +2,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@ -11,6 +12,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.Collaborators;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -23,9 +25,9 @@ import java.util.List;
public class CollaboratorsAdapter extends BaseAdapter {
private final List<Collaborators> collaboratorsList;
private final Context mCtx;
private final Context context;
private static class ViewHolder {
private class ViewHolder {
private String userLoginId;
@ -38,17 +40,21 @@ public class CollaboratorsAdapter extends BaseAdapter {
collaboratorName = v.findViewById(R.id.collaboratorName);
collaboratorAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
Context context = loginId.getContext();
collaboratorAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
public CollaboratorsAdapter(Context mCtx, List<Collaborators> collaboratorsListMain) {
public CollaboratorsAdapter(Context ctx, List<Collaborators> collaboratorsListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.collaboratorsList = collaboratorsListMain;
}
@ -75,7 +81,7 @@ public class CollaboratorsAdapter extends BaseAdapter {
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_collaborators, null);
finalView = LayoutInflater.from(context).inflate(R.layout.list_collaborators, null);
viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder);
}
@ -90,8 +96,10 @@ public class CollaboratorsAdapter extends BaseAdapter {
private void initData(ViewHolder viewHolder, int position) {
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Collaborators currentItem = collaboratorsList.get(position);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.collaboratorAvatar);
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(viewHolder.collaboratorAvatar);
viewHolder.userLoginId = currentItem.getLogin();

View File

@ -26,7 +26,7 @@ import java.util.Locale;
public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context ctx;
private final Context context;
private final int TYPE_LOAD = 0;
private List<Commits> commitsList;
private CommitsAdapter.OnLoadMoreListener loadMoreListener;
@ -35,16 +35,15 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
public CommitsAdapter(Context ctx, List<Commits> commitsListMain) {
this.ctx = ctx;
this.context = ctx;
this.commitsList = commitsListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(ctx);
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new CommitsHolder(inflater.inflate(R.layout.list_commits, parent, false));
@ -52,25 +51,19 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((CommitsHolder) holder).bindData(commitsList.get(position));
}
}
@Override
@ -82,14 +75,12 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
else {
return 1;
}
}
@Override
public int getItemCount() {
return commitsList.size();
}
class CommitsHolder extends RecyclerView.ViewHolder {
@ -107,27 +98,23 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
commitCommitter = itemView.findViewById(R.id.commitCommitterVw);
commitDate = itemView.findViewById(R.id.commitDateVw);
commitHtmlUrl = itemView.findViewById(R.id.commitHtmlUrlVw);
}
@SuppressLint("SetTextI18n")
void bindData(Commits commitsModel) {
final TinyDB tinyDb = TinyDB.getInstance(ctx);
final String locale = tinyDb.getString("locale");
final TinyDB tinyDb = TinyDB.getInstance(context);
Locale locale = context.getResources().getConfiguration().locale;
final String timeFormat = tinyDb.getString("dateFormat");
commitTitle.setText(EmojiParser.parseToUnicode(commitsModel.getCommit().getMessage()));
commitCommitter.setText(ctx.getString(R.string.commitCommittedBy, commitsModel.getCommit().getCommitter().getName()));
commitDate.setText(TimeHelper.formatTime(commitsModel.getCommit().getCommitter().getDate(), new Locale(locale), timeFormat, ctx));
commitCommitter.setText(context.getString(R.string.commitCommittedBy, commitsModel.getCommit().getCommitter().getName()));
commitDate.setText(TimeHelper.formatTime(commitsModel.getCommit().getCommitter().getDate(), locale, timeFormat, context));
if(timeFormat.equals("pretty")) {
commitDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(commitsModel.getCommit().getCommitter().getDate()), ctx));
commitDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(commitsModel.getCommit().getCommitter().getDate()), context));
}
commitHtmlUrl.setOnClickListener(v -> ctx.startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(commitsModel.getHtml_url()))));
commitHtmlUrl.setOnClickListener(v -> context.startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(commitsModel.getHtml_url()))));
}
}
@ -135,41 +122,29 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(CommitsAdapter.OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Commits> list) {
commitsList = list;
notifyDataSetChanged();
}
}

View File

@ -1,59 +0,0 @@
package org.mian.gitnex.adapters;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import java.util.List;
/**
* Author M M Arif
*/
public class CreditsAdapter extends RecyclerView.Adapter<CreditsAdapter.CreditsViewHolder> {
private List<CharSequence> creditsList;
static class CreditsViewHolder extends RecyclerView.ViewHolder {
private TextView creditText;
private CreditsViewHolder(View itemView) {
super(itemView);
creditText = itemView.findViewById(R.id.creditText);
}
}
public CreditsAdapter(List<CharSequence> creditsListMain) {
this.creditsList = creditsListMain;
}
@NonNull
@Override
public CreditsAdapter.CreditsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.credits, parent, false);
return new CreditsAdapter.CreditsViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull CreditsAdapter.CreditsViewHolder holder, int position) {
SpannableStringBuilder strBuilder = new SpannableStringBuilder(creditsList.get(position));
holder.creditText.setText((strBuilder));
holder.creditText.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
public int getItemCount() {
return creditsList.size();
}
}

View File

@ -17,6 +17,7 @@ import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.database.models.DraftWithRepository;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
@ -33,7 +34,7 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
private List<DraftWithRepository> draftsList;
private final FragmentManager fragmentManager;
private final Context mCtx;
private final Context context;
class DraftsViewHolder extends RecyclerView.ViewHolder {
@ -56,7 +57,9 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
int getDraftId = draftWithRepository.getDraftId();
deleteDraft(getAdapterPosition());
DraftsApi draftsApi = new DraftsApi(mCtx);
DraftsApi draftsApi = BaseApi.getInstance(context, DraftsApi.class);
assert draftsApi != null;
draftsApi.deleteSingleDraft(getDraftId);
});
@ -76,24 +79,23 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
bundle.putString("commentAction", "edit");
}
TinyDB tinyDb = TinyDB.getInstance(mCtx);
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("issueNumber", String.valueOf(draftWithRepository.getIssueId()));
tinyDb.putLong("repositoryId", draftWithRepository.getRepositoryId());
tinyDb.putString("issueType", draftWithRepository.getIssueType());
tinyDb.putString("repoFullName", draftWithRepository.getRepositoryOwner() + "/" + draftWithRepository.getRepositoryName());
BottomSheetReplyFragment bottomSheetReplyFragment = BottomSheetReplyFragment.newInstance(bundle);
bottomSheetReplyFragment.setOnInteractedListener(() -> mCtx.startActivity(new Intent(mCtx, IssueDetailActivity.class)));
bottomSheetReplyFragment.setOnInteractedListener(() -> context.startActivity(new Intent(context, IssueDetailActivity.class)));
bottomSheetReplyFragment.show(fragmentManager, "replyBottomSheet");
});
}
}
public DraftsAdapter(Context mCtx, FragmentManager fragmentManager, List<DraftWithRepository> draftsListMain) {
this.mCtx = mCtx;
public DraftsAdapter(Context ctx, FragmentManager fragmentManager, List<DraftWithRepository> draftsListMain) {
this.context = ctx;
this.fragmentManager = fragmentManager;
this.draftsList = draftsListMain;
}
@ -103,8 +105,7 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
draftsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, draftsList.size());
Toasty.success(mCtx, mCtx.getResources().getString(R.string.draftsSingleDeleteSuccess));
Toasty.success(context, context.getResources().getString(R.string.draftsSingleDeleteSuccess));
}
@NonNull
@ -120,14 +121,14 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
DraftWithRepository currentItem = draftsList.get(position);
String issueNumber = "<font color='" + ResourcesCompat.getColor(mCtx.getResources(), R.color.lightGray, null) + "'>" + mCtx.getResources().getString(R.string.hash) + currentItem.getIssueId() + "</font>";
String issueNumber = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + context.getResources().getString(R.string.hash) + currentItem.getIssueId() + "</font>";
Spanned headTitle = HtmlCompat
.fromHtml(issueNumber + " " + currentItem.getRepositoryOwner() + " / " + currentItem.getRepositoryName(), HtmlCompat.FROM_HTML_MODE_LEGACY);
holder.repoInfo.setText(headTitle);
holder.draftWithRepository = currentItem;
new Markdown(mCtx, currentItem.getDraftText(), holder.draftText);
Markdown.render(context, currentItem.getDraftText(), holder.draftText);
if(!currentItem.getCommentId().equalsIgnoreCase("new")) {
holder.editCommentStatus.setVisibility(View.VISIBLE);

View File

@ -14,7 +14,9 @@ import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.Issues;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
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.helpers.AppUtil;
@ -32,23 +34,22 @@ import java.util.Locale;
* Author M M Arif
*/
public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapter.SearchViewHolder> {
public class ExploreIssuesAdapter extends RecyclerView.Adapter<ExploreIssuesAdapter.SearchViewHolder> {
private final List<Issues> searchedList;
private final Context mCtx;
private final Context context;
private final TinyDB tinyDb;
public SearchIssuesAdapter(List<Issues> dataList, Context mCtx) {
public ExploreIssuesAdapter(List<Issues> dataList, Context ctx) {
this.mCtx = mCtx;
this.context = ctx;
this.searchedList = dataList;
this.tinyDb = TinyDB.getInstance(mCtx);
this.tinyDb = TinyDB.getInstance(context);
}
class SearchViewHolder extends RecyclerView.ViewHolder {
private Issues issue;
private final ImageView issueAssigneeAvatar;
private final TextView issueTitle;
private final TextView issueCreatedTime;
@ -63,10 +64,7 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapte
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
issueTitle.setOnClickListener(v -> {
Context context = v.getContext();
itemView.setOnClickListener(v -> {
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issue.getNumber());
@ -80,60 +78,64 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapte
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
assert repositoryData != null;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
context.startActivity(intent);
});
issueAssigneeAvatar.setOnClickListener(v -> {
Context context = v.getContext();
String userLoginId = issue.getUser().getLogin();
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", issue.getUser().getLogin());
context.startActivity(intent);
});
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
issueAssigneeAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, issue.getUser().getLogin(), context.getString(R.string.copyLoginIdToClipBoard, issue.getUser().getLogin()));
return true;
});
}
}
@NonNull
@Override
public SearchIssuesAdapter.SearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
public ExploreIssuesAdapter.SearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_issues, parent, false);
return new SearchIssuesAdapter.SearchViewHolder(v);
return new ExploreIssuesAdapter.SearchViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull final SearchIssuesAdapter.SearchViewHolder holder, int position) {
public void onBindViewHolder(@NonNull final ExploreIssuesAdapter.SearchViewHolder holder, int position) {
Issues currentItem = searchedList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String locale = tinyDb.getString("locale");
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
PicassoService.getInstance(mCtx).get()
PicassoService.getInstance(context).get()
.load(currentItem.getUser().getAvatar_url())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0))
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(holder.issueAssigneeAvatar);
String issueNumber_ = "<font color='" + ResourcesCompat.getColor(mCtx.getResources(), R.color.lightGray, null) + "'>" + currentItem.getRepository().getFull_name() + mCtx.getResources().getString(R.string.hash) + currentItem.getNumber() + "</font>";
String issueNumber_ = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + currentItem.getRepository().getFull_name() + context.getResources().getString(R.string.hash) + currentItem.getNumber() + "</font>";
holder.issue = currentItem;
holder.issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + currentItem.getTitle(), HtmlCompat.FROM_HTML_MODE_LEGACY));
@ -141,20 +143,20 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapte
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getCreated_at());
holder.issueCreatedTime.setText(createdTime);
holder.issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx));
holder.issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCreatedTime.setText(createdTime);
break;
@ -164,12 +166,10 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapte
@Override
public int getItemCount() {
return searchedList.size();
}
public void notifyDataChanged() {
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,148 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.Organization;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OrganizationDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import java.util.List;
/**
* Author M M Arif
*/
public class ExplorePublicOrganizationsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final int TYPE_LOAD = 0;
private List<Organization> organizationsList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public ExplorePublicOrganizationsAdapter(Context ctx, List<Organization> organizationsListMain) {
this.context = ctx;
this.organizationsList = organizationsListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new ExplorePublicOrganizationsAdapter.OrganizationsHolder(inflater.inflate(R.layout.list_organizations, parent, false));
}
else {
return new ExplorePublicOrganizationsAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((ExplorePublicOrganizationsAdapter.OrganizationsHolder) holder).bindData(organizationsList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(organizationsList.get(position).getFull_name() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return organizationsList.size();
}
class OrganizationsHolder extends RecyclerView.ViewHolder {
private Organization organization;
private final ImageView image;
private final TextView orgName;
private final TextView orgDescription;
OrganizationsHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.imageAvatar);
orgName = itemView.findViewById(R.id.orgName);
orgDescription = itemView.findViewById(R.id.orgDescription);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, OrganizationDetailActivity.class);
intent.putExtra("orgName", organization.getUsername());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("orgName", organization.getUsername());
tinyDb.putString("organizationId", String.valueOf(organization.getId()));
tinyDb.putBoolean("organizationAction", true);
context.startActivity(intent);
});
}
@SuppressLint("SetTextI18n")
void bindData(Organization organization) {
this.organization = organization;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
orgName.setText(organization.getUsername());
PicassoService.getInstance(context).get()
.load(organization.getAvatar_url())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(image);
if (!organization.getDescription().equals("")) {
orgDescription.setText(organization.getDescription());
}
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Organization> list) {
organizationsList = list;
notifyDataSetChanged();
}
}

View File

@ -1,8 +1,5 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
@ -11,30 +8,31 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
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 com.google.android.material.bottomsheet.BottomSheetDialog;
import org.gitnex.tea4j.models.UserRepositories;
import org.gitnex.tea4j.models.WatchInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoForksActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
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.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.Toasty;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Objects;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
@ -44,85 +42,78 @@ import retrofit2.Callback;
public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepositoriesAdapter.ReposSearchViewHolder> {
private List<UserRepositories> searchedReposList;
private Context mCtx;
private final List<UserRepositories> reposList;
private final Context context;
public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context mCtx) {
public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context ctx) {
this.mCtx = mCtx;
this.searchedReposList = dataList;
this.context = ctx;
this.reposList = dataList;
}
static class ReposSearchViewHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView repoName;
private TextView repoDescription;
private TextView fullName;
private UserRepositories userRepositories;
private final ImageView image;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private TextView htmlUrl;
private final TextView repoStars;
private final TextView repoLastUpdated;
private ReposSearchViewHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
image = itemView.findViewById(R.id.imageAvatar);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName);
TinyDB tinyDb = TinyDB.getInstance(context);
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", repoFullName.getText().toString());
intent.putExtra("repoFullName", userRepositories.getFullName());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putString("repoFullName", userRepositories.getFullName());
tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString());
tinyDb.putString("repoBranch", userRepositories.getDefault_branch());
String[] parts = fullName.getText().toString().split("/");
if(userRepositories.getPrivateFlag()) {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPrivate));
}
else {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPublic));
}
String[] parts = userRepositories.getFullName().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
assert repositoryData != null;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
//store if user is watching this repo
@ -131,117 +122,35 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchInfo watch = new WatchInfo();
Call<WatchInfo> call;
call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchInfo>() {
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.error(context, context.getString(R.string.genericApiStatusError));
}
}
else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.error(context, context.getString(R.string.genericApiStatusError));
}
}
}
@Override
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.error(context, context.getString(R.string.genericApiStatusError));
}
});
}
context.startActivity(intent);
});
reposDropdownMenu.setOnClickListener(v -> {
final Context context = v.getContext();
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
});
}
}
@ -257,20 +166,26 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
@Override
public void onBindViewHolder(@NonNull final ExploreRepositoriesAdapter.ReposSearchViewHolder holder, int position) {
UserRepositories currentItem = searchedReposList.get(position);
holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
TinyDB tinyDb = TinyDB.getInstance(context);
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
holder.repoStars.setText(currentItem.getStars_count());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
if(currentItem.getAvatar_url() != null) {
if(!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
}
else {
holder.image.setImageDrawable(drawable);
@ -280,41 +195,51 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
holder.image.setImageDrawable(drawable);
}
holder.repoName.setText(currentItem.getName());
if(currentItem.getUpdated_at() != null) {
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
}
else {
holder.repoLastUpdated.setVisibility(View.GONE);
}
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
}
holder.fullName.setText(currentItem.getFullName());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
}
else {
holder.repoPrivatePublic.setVisibility(View.GONE);
holder.repoType.setText(R.string.strPublic);
holder.repoDescription.setText(context.getString(R.string.noDataDescription));
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
holder.isRepoAdmin = new CheckBox(context);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return searchedReposList.size();
return reposList.size();
}
public void notifyDataChanged() {

View File

@ -27,7 +27,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
private final List<Files> originalFiles = new ArrayList<>();
private final List<Files> alteredFiles = new ArrayList<>();
private final Context mCtx;
private final Context context;
private final FilesAdapterListener filesListener;
@ -40,8 +40,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
private Files file;
private final LinearLayout fileFrame;
private final ImageView fileTypeIs;
private final ImageView fileTypeIs;
private final TextView fileName;
private final TextView fileInfo;
@ -49,7 +48,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
super(itemView);
fileFrame = itemView.findViewById(R.id.fileFrame);
LinearLayout fileFrame = itemView.findViewById(R.id.fileFrame);
fileName = itemView.findViewById(R.id.fileName);
fileTypeIs = itemView.findViewById(R.id.fileTypeIs);
fileInfo = itemView.findViewById(R.id.fileInfo);
@ -124,11 +123,10 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
}
}
public FilesAdapter(Context mCtx, FilesAdapterListener filesListener) {
public FilesAdapter(Context ctx, FilesAdapterListener filesListener) {
this.mCtx = mCtx;
this.context = ctx;
this.filesListener = filesListener;
}
public List<Files> getOriginalFiles() {
@ -141,7 +139,6 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
alteredFiles.addAll(originalFiles);
notifyDataSetChanged();
}
@NonNull
@ -162,28 +159,28 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
switch(currentItem.getType()) {
case "file":
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_file));
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_file));
holder.fileInfo.setVisibility(View.VISIBLE);
holder.fileInfo.setText(FileUtils.byteCountToDisplaySize(currentItem.getSize()));
break;
case "dir":
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_directory));
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_directory));
holder.fileInfo.setVisibility(View.GONE);
break;
case "submodule":
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_submodule));
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_submodule));
holder.fileInfo.setVisibility(View.GONE);
break;
case "symlink":
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_symlink));
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_symlink));
holder.fileInfo.setVisibility(View.GONE);
break;
default:
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(mCtx, R.drawable.ic_question));
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_question));
}
}

View File

@ -54,7 +54,6 @@ public class FilesDiffAdapter extends BaseAdapter {
COLOR_NORMAL = AppUtil.getColorFromAttribute(context, R.attr.primaryBackgroundColor);
COLOR_SELECTED = AppUtil.getColorFromAttribute(context, R.attr.diffSelectedColor);
COLOR_FONT = AppUtil.getColorFromAttribute(context, R.attr.inputTextColor);
}
@Override
@ -94,7 +93,6 @@ public class FilesDiffAdapter extends BaseAdapter {
diffStats.setVisibility(View.GONE);
diffLines.addView(getMessageView(context.getResources().getString(R.string.binaryFileError)));
}
else {
@ -168,7 +166,6 @@ public class FilesDiffAdapter extends BaseAdapter {
}
diffTextView.setOnClickListener(v -> {
if(((DiffTextView) v).getCurrentBackgroundColor() != COLOR_SELECTED) {
@ -197,7 +194,6 @@ public class FilesDiffAdapter extends BaseAdapter {
stringBuilder.append(((DiffTextView) view).getText());
stringBuilder.append("\n");
}
stringBuilder.append("```\n\n");
@ -209,7 +205,6 @@ public class FilesDiffAdapter extends BaseAdapter {
bundle.putBoolean("cursorToEnd", true);
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
}
return true;
@ -226,7 +221,6 @@ public class FilesDiffAdapter extends BaseAdapter {
else {
diffLines.addView(getMessageView(context.getResources().getString(R.string.fileTooLarge)));
}
}
@ -248,13 +242,11 @@ public class FilesDiffAdapter extends BaseAdapter {
textView.setText(message);
return textView;
}
private String[] getLines(String content) {
return content.split("\\R");
}
}

View File

@ -20,6 +20,7 @@ import com.google.gson.JsonElement;
import com.vdurmont.emoji.EmojiParser;
import org.gitnex.tea4j.models.IssueComments;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
@ -44,23 +45,23 @@ import retrofit2.Callback;
public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> {
private final Context ctx;
private final Context context;
private final TinyDB tinyDB;
private final Bundle bundle;
private final List<IssueComments> issuesComments;
private final FragmentManager fragmentManager;
private final BottomSheetReplyFragment.OnInteractedListener onInteractedListener;
private final Locale locale;
public IssueCommentsAdapter(Context ctx, Bundle bundle, List<IssueComments> issuesCommentsMain, FragmentManager fragmentManager, BottomSheetReplyFragment.OnInteractedListener onInteractedListener) {
this.ctx = ctx;
this.context = ctx;
this.bundle = bundle;
this.issuesComments = issuesCommentsMain;
this.fragmentManager = fragmentManager;
this.onInteractedListener = onInteractedListener;
tinyDB = TinyDB.getInstance(ctx);
locale = ctx.getResources().getConfiguration().locale;
}
class IssueCommentViewHolder extends RecyclerView.ViewHolder {
@ -87,10 +88,9 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
menu.setOnClickListener(v -> {
final Context ctx = v.getContext();
final String loginUid = tinyDB.getString("loginUid");
@SuppressLint("InflateParams") View vw = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_issue_comments, null);
@SuppressLint("InflateParams") View vw = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_issue_comments, null);
TextView commentMenuEdit = vw.findViewById(R.id.commentMenuEdit);
TextView commentShare = vw.findViewById(R.id.issueCommentShare);
@ -108,7 +108,7 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
commentMenuCopy.setVisibility(View.GONE);
}
BottomSheetDialog dialog = new BottomSheetDialog(ctx);
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(vw);
dialog.show();
@ -118,20 +118,17 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
bundle1.putAll(bundle);
bundle1.putInt("commentId", issueComment.getId());
ReactionSpinner reactionSpinner = new ReactionSpinner(ctx, bundle1);
ReactionSpinner reactionSpinner = new ReactionSpinner(context, bundle1);
reactionSpinner.setOnInteractedListener(() -> {
tinyDB.putBoolean("commentEdited", true);
onInteractedListener.onInteracted();
dialog.dismiss();
});
linearLayout.addView(reactionSpinner);
commentMenuEdit.setOnClickListener(v1 -> {
Bundle bundle = new Bundle();
bundle.putInt("commentId", issueComment.getId());
bundle.putString("commentAction", "edit");
@ -142,56 +139,48 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
bottomSheetReplyFragment.show(fragmentManager, "replyBottomSheet");
dialog.dismiss();
});
commentShare.setOnClickListener(v1 -> {
// get comment Url
CharSequence commentUrl = issueComment.getHtml_url();
// share issue comment
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
String intentHeader = tinyDB.getString("issueNumber") + ctx.getResources().getString(R.string.hash) + "issuecomment-" + issueComment.getId() + " " + tinyDB.getString("issueTitle");
String intentHeader = tinyDB.getString("issueNumber") + context.getResources().getString(R.string.hash) + "issuecomment-" + issueComment.getId() + " " + tinyDB.getString("issueTitle");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, intentHeader);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, commentUrl);
ctx.startActivity(Intent.createChooser(sharingIntent, intentHeader));
context.startActivity(Intent.createChooser(sharingIntent, intentHeader));
dialog.dismiss();
});
issueCommentCopyUrl.setOnClickListener(v1 -> {
// comment Url
CharSequence commentUrl = issueComment.getHtml_url();
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
assert clipboard != null;
ClipData clip = ClipData.newPlainText(commentUrl, commentUrl);
clipboard.setPrimaryClip(clip);
dialog.dismiss();
Toasty.success(ctx, ctx.getString(R.string.copyIssueUrlToastMsg));
Toasty.success(context, context.getString(R.string.copyIssueUrlToastMsg));
});
commentMenuQuote.setOnClickListener(v1 -> {
StringBuilder stringBuilder = new StringBuilder();
String commenterName = issueComment.getUser().getUsername();
if(!commenterName.equals(tinyDB.getString("userLogin"))) {
stringBuilder.append("@").append(commenterName).append("\n\n");
}
String[] lines = issueComment.getBody().split("\\R");
for(String line : lines) {
stringBuilder.append(">").append(line).append("\n");
}
@ -203,40 +192,37 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
dialog.dismiss();
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
});
commentMenuCopy.setOnClickListener(v1 -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
assert clipboard != null;
ClipData clip = ClipData.newPlainText("Comment on issue #" + tinyDB.getString("issueNumber"), issueComment.getBody());
clipboard.setPrimaryClip(clip);
dialog.dismiss();
Toasty.success(ctx, ctx.getString(R.string.copyIssueCommentToastMsg));
Toasty.success(context, context.getString(R.string.copyIssueCommentToastMsg));
});
commentMenuDelete.setOnClickListener(v1 -> {
deleteIssueComment(ctx, issueComment.getId(), getAdapterPosition());
deleteIssueComment(context, issueComment.getId(), getAdapterPosition());
dialog.dismiss();
});
});
avatar.setOnClickListener(loginId -> {
Context context = loginId.getContext();
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
avatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
private void updateAdapter(int position) {
@ -244,7 +230,6 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
issuesComments.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, issuesComments.size());
}
private void deleteIssueComment(final Context ctx, final int commentId, int position) {
@ -311,48 +296,43 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_issue_comments, parent, false);
return new IssueCommentsAdapter.IssueCommentViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull IssueCommentsAdapter.IssueCommentViewHolder holder, int position) {
String timeFormat = tinyDB.getString("dateFormat");
IssueComments issueComment = issuesComments.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
holder.userLoginId = issueComment.getUser().getLogin();
holder.issueComment = issueComment;
holder.author.setText(issueComment.getUser().getUsername());
PicassoService.getInstance(ctx).get()
PicassoService.getInstance(context).get()
.load(issueComment.getUser().getAvatar_url())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(4, 0))
.resize(AppUtil.getPixelsFromDensity(ctx, 35), AppUtil.getPixelsFromDensity(ctx, 35))
.transform(new RoundedTransformation(imgRadius, 0))
.resize(AppUtil.getPixelsFromDensity(context, 35), AppUtil.getPixelsFromDensity(context, 35))
.centerCrop()
.into(holder.avatar);
new Markdown(ctx, EmojiParser.parseToUnicode(issueComment.getBody()), holder.comment);
Markdown.render(context, EmojiParser.parseToUnicode(issueComment.getBody()), holder.comment);
StringBuilder informationBuilder = null;
if(issueComment.getCreated_at() != null) {
if(timeFormat.equals("pretty")) {
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), Locale.getDefault(), "pretty", ctx));
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), locale, "pretty", context));
holder.information.setOnClickListener(v -> TimeHelper.customDateFormatForToastDateFormat(issueComment.getCreated_at()));
}
else if(timeFormat.equals("normal")) {
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), Locale.getDefault(), "normal", ctx));
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), locale, "normal", context));
}
if(!issueComment.getCreated_at().equals(issueComment.getUpdated_at())) {
if(informationBuilder != null) {
informationBuilder.append(ctx.getString(R.string.colorfulBulletSpan)).append(ctx.getString(R.string.modifiedText));
informationBuilder.append(context.getString(R.string.colorfulBulletSpan)).append(context.getString(R.string.modifiedText));
}
}
}
@ -363,7 +343,7 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
bundle1.putAll(bundle);
bundle1.putInt("commentId", issueComment.getId());
ReactionList reactionList = new ReactionList(ctx, bundle1);
ReactionList reactionList = new ReactionList(context, bundle1);
holder.commentReactionBadges.addView(reactionList);
reactionList.setOnReactionAddedListener(() -> {
@ -377,7 +357,6 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
@Override
public int getItemCount() {
return issuesComments.size();
}

View File

@ -7,7 +7,6 @@ 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;
@ -17,6 +16,7 @@ import com.vdurmont.emoji.EmojiParser;
import org.gitnex.tea4j.models.Issues;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
@ -41,11 +41,10 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public IssuesAdapter(Context context, List<Issues> issuesListMain) {
public IssuesAdapter(Context ctx, List<Issues> issuesListMain) {
this.context = context;
this.context = ctx;
this.issuesList = issuesListMain;
}
@NonNull
@ -60,7 +59,6 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
@ -70,15 +68,12 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((IssuesHolder) holder).bindData(issuesList.get(position));
}
}
@Override
@ -90,14 +85,12 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
else {
return 1;
}
}
@Override
public int getItemCount() {
return issuesList.size();
}
class IssuesHolder extends RecyclerView.ViewHolder {
@ -112,17 +105,12 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
IssuesHolder(View itemView) {
super(itemView);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
issueTitle.setOnClickListener(title -> {
Context context = title.getContext();
itemView.setOnClickListener(layoutView -> {
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issue.getNumber());
@ -130,43 +118,33 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
tinyDb.putString("issueNumber", String.valueOf(issue.getNumber()));
tinyDb.putString("issueType", "Issue");
context.startActivity(intent);
});
frameCommentsCount.setOnClickListener(commentsCount -> {
Context context = commentsCount.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issue.getNumber());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("issueNumber", String.valueOf(issue.getNumber()));
tinyDb.putString("issueType", "Issue");
context.startActivity(intent);
});
issueAssigneeAvatar.setOnClickListener(v -> {
Context context = v.getContext();
String userLoginId = issue.getUser().getLogin();
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", issue.getUser().getLogin());
context.startActivity(intent);
});
issueAssigneeAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, issue.getUser().getLogin(), context.getString(R.string.copyLoginIdToClipBoard, issue.getUser().getLogin()));
return true;
});
}
@SuppressLint("SetTextI18n")
void bindData(Issues issue) {
TinyDB tinyDb = TinyDB.getInstance(context);
String locale = tinyDb.getString("locale");
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context).get()
.load(issue.getUser().getAvatar_url())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0))
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(issueAssigneeAvatar);
@ -179,20 +157,20 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(issue.getCreated_at());
this.issueCreatedTime.setText(createdTime);
this.issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issue.getCreated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(issue.getCreated_at());
this.issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(issue.getCreated_at());
this.issueCreatedTime.setText(createdTime);
break;
@ -209,32 +187,27 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Issues> list) {

View File

@ -20,7 +20,6 @@ import org.mian.gitnex.R;
import org.mian.gitnex.activities.CreateLabelActivity;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.ColorInverter;
import java.util.ArrayList;
import java.util.List;
/**
@ -29,21 +28,17 @@ import java.util.List;
public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsViewHolder> {
private List<Labels> labelsList;
final private Context mCtx;
private ArrayList<Integer> labelsArray = new ArrayList<>();
private final List<Labels> labelsList;
private static String type;
private static String orgName;
static class LabelsViewHolder extends RecyclerView.ViewHolder {
private TextView labelTitle;
private TextView labelId;
private TextView labelColor;
private Labels labels;
private CardView labelView;
private ImageView labelIcon;
private TextView labelName;
private final CardView labelView;
private final ImageView labelIcon;
private final TextView labelName;
private LabelsViewHolder(View itemView) {
super(itemView);
@ -52,9 +47,6 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
labelIcon = itemView.findViewById(R.id.labelIcon);
labelName = itemView.findViewById(R.id.labelName);
ImageView labelsOptionsMenu = itemView.findViewById(R.id.labelsOptionsMenu);
labelTitle = itemView.findViewById(R.id.labelTitle);
labelId = itemView.findViewById(R.id.labelId);
labelColor = itemView.findViewById(R.id.labelColor);
labelsOptionsMenu.setOnClickListener(v -> {
@ -67,7 +59,7 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
TextView labelMenuDelete = view.findViewById(R.id.labelMenuDelete);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(labelTitle.getText());
bottomSheetHeader.setText(labels.getName());
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
@ -75,27 +67,25 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
labelMenuEdit.setOnClickListener(editLabel -> {
Intent intent = new Intent(context, CreateLabelActivity.class);
intent.putExtra("labelId", labelId.getText());
intent.putExtra("labelTitle", labelTitle.getText());
intent.putExtra("labelColor", labelColor.getText());
intent.putExtra("labelId", String.valueOf(labels.getId()));
intent.putExtra("labelTitle", labels.getName());
intent.putExtra("labelColor", labels.getColor());
intent.putExtra("labelAction", "edit");
intent.putExtra("type", type);
intent.putExtra("orgName", orgName);
context.startActivity(intent);
dialog.dismiss();
});
labelMenuDelete.setOnClickListener(deleteLabel -> {
AlertDialogs.labelDeleteDialog(context, labelTitle.getText().toString(), labelId.getText().toString(),
AlertDialogs.labelDeleteDialog(context, labels.getName(), String.valueOf(labels.getId()),
context.getResources().getString(R.string.labelDeleteTitle),
context.getResources().getString(R.string.labelDeleteMessage),
context.getResources().getString(R.string.labelDeleteTitle),
context.getResources().getString(R.string.labelDeleteNegativeButton),
type, orgName);
dialog.dismiss();
});
});
@ -103,10 +93,9 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
}
}
public LabelsAdapter(Context mCtx, List<Labels> labelsMain, String type, String orgName) {
public LabelsAdapter(Context ctx, List<Labels> labelsMain, String type, String orgName) {
this.mCtx = mCtx;
this.labelsList = labelsMain;
this.labelsList = labelsMain;
LabelsAdapter.type = type;
LabelsAdapter.orgName = orgName;
}
@ -122,10 +111,7 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
public void onBindViewHolder(@NonNull LabelsAdapter.LabelsViewHolder holder, int position) {
Labels currentItem = labelsList.get(position);
holder.labelTitle.setText(currentItem.getName());
holder.labelId.setText(String.valueOf(currentItem.getId()));
holder.labelColor.setText(currentItem.getColor());
holder.labels = currentItem;
String labelColor = currentItem.getColor();
String labelName = currentItem.getName();
@ -138,7 +124,6 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
holder.labelName.setTextColor(contrastColor);
holder.labelName.setText(labelName);
holder.labelView.setCardBackgroundColor(color);
}
@Override

View File

@ -22,11 +22,11 @@ import java.util.List;
public class LabelsListAdapter extends RecyclerView.Adapter<LabelsListAdapter.LabelsViewHolder> {
private List<Integer> currentLabelsIds;
private List<Labels> labels;
private List<String> labelsStrings = new ArrayList<>();
private final List<Labels> labels;
private final List<String> labelsStrings = new ArrayList<>();
private List<Integer> labelsIds = new ArrayList<>();
private LabelsListAdapterListener labelsListener;
private final LabelsListAdapterListener labelsListener;
public interface LabelsListAdapterListener {
@ -43,9 +43,9 @@ public class LabelsListAdapter extends RecyclerView.Adapter<LabelsListAdapter.La
static class LabelsViewHolder extends RecyclerView.ViewHolder {
private CheckBox labelSelection;
private TextView labelText;
private ImageView labelColor;
private final CheckBox labelSelection;
private final TextView labelText;
private final ImageView labelColor;
private LabelsViewHolder(View itemView) {

View File

@ -2,6 +2,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@ -13,6 +14,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -26,10 +28,10 @@ import java.util.List;
public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
private final List<UserInfo> membersList;
private final Context mCtx;
private final Context context;
private final List<UserInfo> membersListFull;
private static class ViewHolder {
private class ViewHolder {
private String userLoginId;
@ -42,17 +44,21 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
memberName = v.findViewById(R.id.memberName);
memberAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
Context context = loginId.getContext();
memberAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
public MembersByOrgAdapter(Context mCtx, List<UserInfo> membersListMain) {
public MembersByOrgAdapter(Context ctx, List<UserInfo> membersListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.membersList = membersListMain;
membersListFull = new ArrayList<>(membersList);
}
@ -80,7 +86,7 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_members_by_org, null);
finalView = LayoutInflater.from(context).inflate(R.layout.list_members_by_org, null);
viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder);
}
@ -96,7 +102,9 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
private void initData(MembersByOrgAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = membersList.get(position);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(viewHolder.memberAvatar);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(viewHolder.memberAvatar);
viewHolder.userLoginId = currentItem.getLogin();
@ -108,7 +116,6 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
viewHolder.memberName.setText(currentItem.getLogin());
}
}
@Override

View File

@ -35,19 +35,17 @@ import java.util.Locale;
public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private final Context context;
private final int TYPE_LOAD = 0;
private List<Milestones> dataList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false;
private boolean isMoreDataAvailable = true;
private String TAG = Constants.tagMilestonesAdapter;
public MilestonesAdapter(Context context, List<Milestones> dataListMain) {
public MilestonesAdapter(Context ctx, List<Milestones> dataListMain) {
this.context = context;
this.context = ctx;
this.dataList = dataListMain;
}
@NonNull
@ -62,7 +60,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
else {
return new MilestonesAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
@ -72,33 +69,29 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((MilestonesAdapter.DataHolder) holder).bindData(dataList.get(position));
}
}
class DataHolder extends RecyclerView.ViewHolder {
private TextView milestoneId;
private TextView msTitle;
private TextView msDescription;
private TextView msOpenIssues;
private TextView msClosedIssues;
private TextView msDueDate;
private ProgressBar msProgress;
private TextView milestoneStatus;
private Milestones milestones;
private final TextView msTitle;
private final TextView msDescription;
private final TextView msOpenIssues;
private final TextView msClosedIssues;
private final TextView msDueDate;
private final ProgressBar msProgress;
DataHolder(View itemView) {
super(itemView);
milestoneId = itemView.findViewById(R.id.milestoneId);
msTitle = itemView.findViewById(R.id.milestoneTitle);
msDescription = itemView.findViewById(R.id.milestoneDescription);
msOpenIssues = itemView.findViewById(R.id.milestoneIssuesOpen);
@ -106,12 +99,11 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
msDueDate = itemView.findViewById(R.id.milestoneDueDate);
msProgress = itemView.findViewById(R.id.milestoneProgress);
ImageView milestonesMenu = itemView.findViewById(R.id.milestonesMenu);
milestoneStatus = itemView.findViewById(R.id.milestoneStatus);
milestonesMenu.setOnClickListener(v -> {
Context ctx = v.getContext();
int milestoneId_ = Integer.parseInt(milestoneId.getText().toString());
int milestoneId_ = Integer.parseInt(String.valueOf(milestones.getId()));
@SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_milestones_in_list, null);
@ -122,17 +114,15 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
dialog.setContentView(view);
dialog.show();
if(milestoneStatus.getText().toString().equals("open")) {
if(milestones.getState().equals("open")) {
closeMilestone.setVisibility(View.VISIBLE);
openMilestone.setVisibility(View.GONE);
}
else {
closeMilestone.setVisibility(View.GONE);
openMilestone.setVisibility(View.VISIBLE);
}
closeMilestone.setOnClickListener(v12 -> {
@ -140,7 +130,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
MilestoneActions.closeMilestone(ctx, milestoneId_);
dialog.dismiss();
updateAdapter(getAdapterPosition());
});
openMilestone.setOnClickListener(v12 -> {
@ -148,7 +137,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
MilestoneActions.openMilestone(ctx, milestoneId_);
dialog.dismiss();
updateAdapter(getAdapterPosition());
});
});
@ -158,18 +146,16 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
@SuppressLint("SetTextI18n")
void bindData(Milestones dataModel) {
this.milestones = dataModel;
final TinyDB tinyDb = TinyDB.getInstance(context);
final String locale = tinyDb.getString("locale");
final String locale = context.getResources().getConfiguration().locale.getLanguage();
final String timeFormat = tinyDb.getString("dateFormat");
milestoneId.setText(String.valueOf(dataModel.getId()));
milestoneStatus.setText(dataModel.getState());
new Markdown(context, dataModel.getTitle(), msTitle);
Markdown.render(context, dataModel.getTitle(), msTitle);
if(!dataModel.getDescription().equals("")) {
new Markdown(context, EmojiParser.parseToUnicode(dataModel.getDescription()), msDescription);
Markdown.render(context, EmojiParser.parseToUnicode(dataModel.getDescription()), msDescription);
}
else {
@ -185,14 +171,12 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
msProgress.setProgress(100);
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 100), context));
}
else {
int msCompletion = 100 * dataModel.getClosed_issues() / (dataModel.getOpen_issues() + dataModel.getClosed_issues());
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, msCompletion), context));
msProgress.setProgress(msCompletion);
}
}
@ -200,11 +184,11 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
msProgress.setProgress(0);
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 0), context));
}
if(dataModel.getDue_on() != null) {
String TAG = Constants.tagMilestonesAdapter;
if(timeFormat.equals("normal") || timeFormat.equals("pretty")) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
@ -226,7 +210,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
msDueDate.setText(dueDate);
msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(dataModel.getDue_on()), context));
}
else if(timeFormat.equals("normal1")) {
@ -244,7 +227,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
assert date1 != null;
String dueDate = formatter.format(date1);
msDueDate.setText(dueDate);
}
}
@ -262,7 +244,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
dataList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, dataList.size());
}
@Override
@ -274,14 +255,12 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
else {
return 1;
}
}
@Override
public int getItemCount() {
return dataList.size();
}
static class LoadHolder extends RecyclerView.ViewHolder {
@ -290,32 +269,27 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Milestones> list) {

View File

@ -18,15 +18,15 @@ import java.util.List;
* Author M M Arif
*/
public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdapter.EmailsViewHolder> {
public class MyProfileEmailsAdapter extends RecyclerView.Adapter<MyProfileEmailsAdapter.EmailsViewHolder> {
private List<Emails> emailsList;
private Context mCtx;
private final List<Emails> emailsList;
private final Context context;
static class EmailsViewHolder extends RecyclerView.ViewHolder {
private ImageView emailPrimary;
private TextView userEmail;
private final ImageView emailPrimary;
private final TextView userEmail;
private EmailsViewHolder(View itemView) {
super(itemView);
@ -37,20 +37,20 @@ public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdap
}
}
public ProfileEmailsAdapter(Context mCtx, List<Emails> emailsListMain) {
this.mCtx = mCtx;
public MyProfileEmailsAdapter(Context ctx, List<Emails> emailsListMain) {
this.context = ctx;
this.emailsList = emailsListMain;
}
@NonNull
@Override
public ProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
public MyProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_emails, parent, false);
return new ProfileEmailsAdapter.EmailsViewHolder(v);
return new MyProfileEmailsAdapter.EmailsViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ProfileEmailsAdapter.EmailsViewHolder holder, int position) {
public void onBindViewHolder(@NonNull MyProfileEmailsAdapter.EmailsViewHolder holder, int position) {
Emails currentItem = emailsList.get(position);
@ -59,12 +59,12 @@ public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdap
if(currentItem.getPrimary()) {
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.textColor(ResourcesCompat.getColor(mCtx.getResources(), R.color.colorWhite, null))
.textColor(ResourcesCompat.getColor(context.getResources(), R.color.colorWhite, null))
.fontSize(36)
.width(220)
.height(60)
.endConfig()
.buildRoundRect(mCtx.getResources().getString(R.string.emailTypeText), ResourcesCompat.getColor(mCtx.getResources(), R.color.tooltipBackground, null), 8);
.buildRoundRect(context.getResources().getString(R.string.emailTypeText), ResourcesCompat.getColor(context.getResources(), R.color.tooltipBackground, null), 8);
holder.emailPrimary.setImageDrawable(drawable);
}
else {

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@ -11,6 +12,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -20,12 +22,12 @@ import java.util.List;
* Author M M Arif
*/
public class ProfileFollowersAdapter extends RecyclerView.Adapter<ProfileFollowersAdapter.FollowersViewHolder> {
public class MyProfileFollowersAdapter extends RecyclerView.Adapter<MyProfileFollowersAdapter.FollowersViewHolder> {
private final List<UserInfo> followersList;
private final Context mCtx;
private final Context context;
static class FollowersViewHolder extends RecyclerView.ViewHolder {
class FollowersViewHolder extends RecyclerView.ViewHolder {
private String userLoginId;
@ -41,48 +43,51 @@ public class ProfileFollowersAdapter extends RecyclerView.Adapter<ProfileFollowe
userFullName = itemView.findViewById(R.id.userFullName);
userName = itemView.findViewById(R.id.userName);
userAvatar.setOnClickListener(loginId -> {
Context context = loginId.getContext();
itemView.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
itemView.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
public ProfileFollowersAdapter(Context mCtx, List<UserInfo> followersListMain) {
public MyProfileFollowersAdapter(Context ctx, List<UserInfo> followersListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.followersList = followersListMain;
}
@NonNull
@Override
public ProfileFollowersAdapter.FollowersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
public MyProfileFollowersAdapter.FollowersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_followers, parent, false);
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_followers_following, parent, false);
return new FollowersViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ProfileFollowersAdapter.FollowersViewHolder holder, int position) {
public void onBindViewHolder(@NonNull MyProfileFollowersAdapter.FollowersViewHolder holder, int position) {
UserInfo currentItem = followersList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
holder.userLoginId = currentItem.getLogin();
if(!currentItem.getFullname().equals("")) {
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
}
else {
holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userFullName.setText(currentItem.getUsername());
holder.userName.setVisibility(View.GONE);
}
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
@Override

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@ -11,6 +12,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -20,12 +22,12 @@ import java.util.List;
* Author M M Arif
*/
public class ProfileFollowingAdapter extends RecyclerView.Adapter<ProfileFollowingAdapter.FollowingViewHolder> {
public class MyProfileFollowingAdapter extends RecyclerView.Adapter<MyProfileFollowingAdapter.FollowingViewHolder> {
private final List<UserInfo> followingList;
private final Context mCtx;
private final Context context;
static class FollowingViewHolder extends RecyclerView.ViewHolder {
class FollowingViewHolder extends RecyclerView.ViewHolder {
private String userLoginId;
@ -41,48 +43,51 @@ public class ProfileFollowingAdapter extends RecyclerView.Adapter<ProfileFollowi
userFullName = itemView.findViewById(R.id.userFullName);
userName = itemView.findViewById(R.id.userName);
userAvatar.setOnClickListener(loginId -> {
Context context = loginId.getContext();
itemView.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
itemView.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
public ProfileFollowingAdapter(Context mCtx, List<UserInfo> followingListMain) {
public MyProfileFollowingAdapter(Context ctx, List<UserInfo> followingListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.followingList = followingListMain;
}
@NonNull
@Override
public ProfileFollowingAdapter.FollowingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
public MyProfileFollowingAdapter.FollowingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_following, parent, false);
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_followers_following, parent, false);
return new FollowingViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ProfileFollowingAdapter.FollowingViewHolder holder, int position) {
public void onBindViewHolder(@NonNull MyProfileFollowingAdapter.FollowingViewHolder holder, int position) {
UserInfo currentItem = followingList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
holder.userLoginId = currentItem.getLogin();
if(!currentItem.getFullname().equals("")) {
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
}
else {
holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userFullName.setText(currentItem.getUsername());
holder.userName.setVisibility(View.GONE);
}
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
@Override

View File

@ -1,8 +1,5 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
@ -13,31 +10,32 @@ import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
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 com.google.android.material.bottomsheet.BottomSheetDialog;
import org.gitnex.tea4j.models.UserRepositories;
import org.gitnex.tea4j.models.WatchInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoForksActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
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.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.Toasty;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
@ -47,79 +45,73 @@ import retrofit2.Callback;
public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.MyReposViewHolder> implements Filterable {
private List<UserRepositories> reposList;
private Context mCtx;
private List<UserRepositories> reposListFull;
private final List<UserRepositories> reposList;
private final Context context;
private final List<UserRepositories> reposListFull;
static class MyReposViewHolder extends RecyclerView.ViewHolder {
private ImageView imageAvatar;
private TextView repoName;
private TextView repoDescription;
private TextView repoFullName;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private UserRepositories userRepositories;
private final ImageView image;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private LinearLayout archiveRepo;
private TextView repoBranch;
private TextView htmlUrl;
private final TextView repoStars;
private final TextView repoLastUpdated;
private MyReposViewHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
imageAvatar = itemView.findViewById(R.id.imageAvatar);
repoFullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
image = itemView.findViewById(R.id.imageAvatar);
repoStars = itemView.findViewById(R.id.repoStars);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
TinyDB tinyDb = TinyDB.getInstance(context);
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", repoFullName.getText().toString());
intent.putExtra("repoFullName", userRepositories.getFullName());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString());
tinyDb.putString("repoFullName", userRepositories.getFullName());
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString());
tinyDb.putString("repoBranch", userRepositories.getDefault_branch());
String[] parts = repoFullName.getText().toString().split("/");
if(userRepositories.getPrivateFlag()) {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPrivate));
}
else {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPublic));
}
String[] parts = userRepositories.getFullName().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
assert repositoryData != null;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
//store if user is watching this repo
@ -172,81 +164,13 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
context.startActivity(intent);
});
reposDropdownMenu.setOnClickListener(v -> {
final Context context = v.getContext();
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", repoFullName.getText().toString().split("/")[0], repoFullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", repoFullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", repoFullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", repoFullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", repoFullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
});
}
}
public MyReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
public MyReposListAdapter(Context ctx, List<UserRepositories> reposListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList);
}
@ -262,59 +186,74 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
@Override
public void onBindViewHolder(@NonNull MyReposListAdapter.MyReposViewHolder holder, int position) {
TinyDB tinyDb = TinyDB.getInstance(context);
UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
holder.repoStars.setText(currentItem.getStars_count());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
if(currentItem.getAvatar_url() != null) {
if(!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.imageAvatar);
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
}
else {
holder.imageAvatar.setImageDrawable(drawable);
holder.image.setImageDrawable(drawable);
}
}
else {
holder.imageAvatar.setImageDrawable(drawable);
holder.image.setImageDrawable(drawable);
}
if(currentItem.getUpdated_at() != null) {
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
}
else {
holder.repoLastUpdated.setVisibility(View.GONE);
}
holder.repoName.setText(currentItem.getName());
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
}
holder.repoFullName.setText(currentItem.getFullName());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
}
else {
holder.repoPrivatePublic.setVisibility(View.GONE);
holder.repoType.setText(R.string.strPublic);
holder.repoDescription.setText(context.getString(R.string.noDataDescription));
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
holder.isRepoAdmin = new CheckBox(context);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override
@ -329,7 +268,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
return myReposFilter;
}
private Filter myReposFilter = new Filter() {
private final Filter myReposFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {

View File

@ -13,6 +13,7 @@ import androidx.core.text.HtmlCompat;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.NotificationThread;
import org.mian.gitnex.R;
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.helpers.TinyDB;
@ -24,11 +25,11 @@ import java.util.List;
public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.NotificationsViewHolder> {
private Context context;
private List<NotificationThread> notificationThreads;
private OnMoreClickedListener onMoreClickedListener;
private OnNotificationClickedListener onNotificationClickedListener;
private TinyDB tinyDb;
private final Context context;
private final List<NotificationThread> notificationThreads;
private final OnMoreClickedListener onMoreClickedListener;
private final OnNotificationClickedListener onNotificationClickedListener;
private final TinyDB tinyDb;
public NotificationsAdapter(Context context, List<NotificationThread> notificationThreads, OnMoreClickedListener onMoreClickedListener, OnNotificationClickedListener onNotificationClickedListener) {
@ -37,19 +38,18 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
this.notificationThreads = notificationThreads;
this.onMoreClickedListener = onMoreClickedListener;
this.onNotificationClickedListener = onNotificationClickedListener;
}
static class NotificationsViewHolder extends RecyclerView.ViewHolder {
private LinearLayout frame;
private TextView subject;
private TextView repository;
private ImageView typePr;
private ImageView typeIssue;
private ImageView typeUnknown;
private ImageView pinned;
private ImageView more;
private final LinearLayout frame;
private final TextView subject;
private final TextView repository;
private final ImageView typePr;
private final ImageView typeIssue;
private final ImageView typeUnknown;
private final ImageView pinned;
private final ImageView more;
public NotificationsViewHolder(@NonNull View itemView) {
@ -63,7 +63,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
typeUnknown = itemView.findViewById(R.id.typeUnknown);
pinned = itemView.findViewById(R.id.pinned);
more = itemView.findViewById(R.id.more);
}
}
@ -73,7 +72,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
View v = LayoutInflater.from(context).inflate(R.layout.list_notifications, parent, false);
return new NotificationsAdapter.NotificationsViewHolder(v);
}
@Override
@ -90,8 +88,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
if(notificationThread.isPinned()) {
holder.pinned.setVisibility(View.VISIBLE);
}
else {
} else {
holder.pinned.setVisibility(View.GONE);
}
@ -126,26 +123,20 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
} else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
});
holder.more.setOnClickListener(v -> onMoreClickedListener.onMoreClicked(notificationThread));
}
@Override

View File

@ -16,6 +16,7 @@ import org.gitnex.tea4j.models.UserOrganizations;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OrganizationDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import java.util.ArrayList;
@ -27,42 +28,42 @@ import java.util.List;
public class OrganizationsListAdapter extends RecyclerView.Adapter<OrganizationsListAdapter.OrganizationsViewHolder> implements Filterable {
private List<UserOrganizations> orgList;
private Context mCtx;
private List<UserOrganizations> orgListFull;
private final List<UserOrganizations> orgList;
private final Context context;
private final List<UserOrganizations> orgListFull;
static class OrganizationsViewHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView mTextView1;
private TextView mTextView2;
private TextView organizationId;
private UserOrganizations userOrganizations;
private final ImageView image;
private final TextView orgName;
private final TextView orgDescription;
private OrganizationsViewHolder(View itemView) {
super(itemView);
mTextView1 = itemView.findViewById(R.id.orgUsername);
mTextView2 = itemView.findViewById(R.id.orgDescription);
orgName = itemView.findViewById(R.id.orgName);
orgDescription = itemView.findViewById(R.id.orgDescription);
image = itemView.findViewById(R.id.imageAvatar);
organizationId = itemView.findViewById(R.id.organizationId);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, OrganizationDetailActivity.class);
intent.putExtra("orgName", mTextView1.getText().toString());
intent.putExtra("orgName", userOrganizations.getUsername());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("orgName", mTextView1.getText().toString());
tinyDb.putString("organizationId", organizationId.getText().toString());
tinyDb.putString("orgName", userOrganizations.getUsername());
tinyDb.putString("organizationId", String.valueOf(userOrganizations.getId()));
tinyDb.putBoolean("organizationAction", true);
context.startActivity(intent);
});
}
}
public OrganizationsListAdapter(Context mCtx, List<UserOrganizations> orgsListMain) {
public OrganizationsListAdapter(Context ctx, List<UserOrganizations> orgsListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.orgList = orgsListMain;
orgListFull = new ArrayList<>(orgList);
}
@ -80,16 +81,16 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<Organizations
public void onBindViewHolder(@NonNull OrganizationsViewHolder holder, int position) {
UserOrganizations currentItem = orgList.get(position);
holder.mTextView2.setVisibility(View.GONE);
holder.organizationId.setText(Integer.toString(currentItem.getId()));
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
holder.mTextView1.setText(currentItem.getUsername());
holder.userOrganizations = currentItem;
holder.orgName.setText(currentItem.getUsername());
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE);
holder.mTextView2.setText(currentItem.getDescription());
holder.orgDescription.setText(currentItem.getDescription());
}
}

View File

@ -7,7 +7,6 @@ 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;
@ -17,6 +16,7 @@ import com.vdurmont.emoji.EmojiParser;
import org.gitnex.tea4j.models.PullRequests;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
@ -39,10 +39,8 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
private boolean isLoading = false, isMoreDataAvailable = true;
public PullRequestsAdapter(Context context, List<PullRequests> prListMain) {
this.context = context;
this.prList = prListMain;
}
@NonNull
@ -57,7 +55,6 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
else {
return new PullRequestsAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
@ -87,9 +84,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
@Override
public int getItemCount() {
return prList.size();
}
class PullRequestsHolder extends RecyclerView.ViewHolder {
@ -104,46 +99,12 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
PullRequestsHolder(View itemView) {
super(itemView);
assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
prTitle = itemView.findViewById(R.id.prTitle);
prCommentsCount = itemView.findViewById(R.id.prCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
prCreatedTime = itemView.findViewById(R.id.prCreatedTime);
prTitle.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", pullRequest.getNumber());
intent.putExtra("prMergeable", pullRequest.isMergeable());
intent.putExtra("prHeadBranch", pullRequest.getHead().getRef());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("issueNumber", String.valueOf(pullRequest.getNumber()));
tinyDb.putString("prMergeable", String.valueOf(pullRequest.isMergeable()));
tinyDb.putString("prHeadBranch", pullRequest.getHead().getRef());
if(pullRequest.getHead() != null && pullRequest.getHead().getRepo() != null) {
tinyDb.putString("prIsFork", String.valueOf(pullRequest.getHead().getRepo().isFork()));
tinyDb.putString("prForkFullName", pullRequest.getHead().getRepo().getFull_name());
}
else {
// pull was done from a deleted fork
tinyDb.putString("prIsFork", "true");
tinyDb.putString("prForkFullName", context.getString(R.string.prDeletedFork));
}
tinyDb.putString("issueType", "Pull");
context.startActivity(intent);
});
frameCommentsCount.setOnClickListener(v -> {
Context context = v.getContext();
itemView.setOnClickListener(v -> {
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", pullRequest.getNumber());
intent.putExtra("prMergeable", pullRequest.isMergeable());
@ -170,25 +131,29 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
});
assigneeAvatar.setOnClickListener(v -> {
Context context = v.getContext();
String userLoginId = pullRequest.getUser().getLogin();
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", pullRequest.getUser().getLogin());
context.startActivity(intent);
});
assigneeAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, pullRequest.getUser().getLogin(), context.getString(R.string.copyLoginIdToClipBoard, pullRequest.getUser().getLogin()));
return true;
});
}
@SuppressLint("SetTextI18n")
void bindData(PullRequests pullRequest) {
TinyDB tinyDb = TinyDB.getInstance(context);
String locale = tinyDb.getString("locale");
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context).get()
.load(pullRequest.getUser().getAvatar_url())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0))
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(this.assigneeAvatar);
@ -199,7 +164,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
this.prTitle.setText(HtmlCompat.fromHtml(prNumber_ + " " + EmojiParser.parseToUnicode(pullRequest.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY));
this.prCommentsCount.setText(String.valueOf(pullRequest.getComments()));
this.prCreatedTime.setText(TimeHelper.formatTime(pullRequest.getCreated_at(), new Locale(locale), timeFormat, context));
this.prCreatedTime.setText(TimeHelper.formatTime(pullRequest.getCreated_at(), locale, timeFormat, context));
if(timeFormat.equals("pretty")) {
this.prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(pullRequest.getCreated_at()), context));
@ -210,41 +175,30 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(PullRequestsAdapter.OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<PullRequests> list) {
prList = list;
notifyDataSetChanged();
}
}

View File

@ -1,13 +1,13 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.text.HtmlCompat;
@ -15,7 +15,9 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.Releases;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -30,25 +32,26 @@ import java.util.Locale;
public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.ReleasesViewHolder> {
private List<Releases> releasesList;
private Context mCtx;
private final List<Releases> releasesList;
private final Context context;
static class ReleasesViewHolder extends RecyclerView.ViewHolder {
private TextView releaseType;
private TextView releaseName;
private ImageView authorAvatar;
private TextView authorName;
private TextView releaseTag;
private TextView releaseCommitSha;
private TextView releaseDate;
private TextView releaseBodyContent;
private LinearLayout downloadFrame;
private RelativeLayout downloads;
private TextView releaseZipDownload;
private TextView releaseTarDownload;
private ImageView downloadDropdownIcon;
private RecyclerView downloadList;
private Releases releases;
private final TextView releaseType;
private final TextView releaseName;
private final ImageView authorAvatar;
private final TextView authorName;
private final TextView releaseTag;
private final TextView releaseDate;
private final TextView releaseBodyContent;
private final LinearLayout downloadFrame;
private final LinearLayout downloads;
private final TextView releaseZipDownload;
private final TextView releaseTarDownload;
private final ImageView downloadDropdownIcon;
private final RecyclerView downloadList;
private ReleasesViewHolder(View itemView) {
@ -59,7 +62,7 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
authorAvatar = itemView.findViewById(R.id.authorAvatar);
authorName = itemView.findViewById(R.id.authorName);
releaseTag = itemView.findViewById(R.id.releaseTag);
releaseCommitSha = itemView.findViewById(R.id.releaseCommitSha);
TextView releaseCommitSha = itemView.findViewById(R.id.releaseCommitSha);
releaseDate = itemView.findViewById(R.id.releaseDate);
releaseBodyContent = itemView.findViewById(R.id.releaseBodyContent);
downloadFrame = itemView.findViewById(R.id.downloadFrame);
@ -72,11 +75,18 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
downloadList.setHasFixedSize(true);
downloadList.setLayoutManager(new LinearLayoutManager(itemView.getContext()));
authorAvatar.setOnClickListener(loginId -> {
Context context = loginId.getContext();
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", releases.getAuthor().getLogin());
context.startActivity(intent);
});
}
}
public ReleasesAdapter(Context mCtx, List<Releases> releasesMain) {
this.mCtx = mCtx;
public ReleasesAdapter(Context ctx, List<Releases> releasesMain) {
this.context = ctx;
this.releasesList = releasesMain;
}
@ -90,11 +100,13 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
@Override
public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) {
final TinyDB tinyDb = TinyDB.getInstance(mCtx);
final String locale = tinyDb.getString("locale");
final TinyDB tinyDb = TinyDB.getInstance(context);
final Locale locale = context.getResources().getConfiguration().locale;
final String timeFormat = tinyDb.getString("dateFormat");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Releases currentItem = releasesList.get(position);
holder.releases = currentItem;
holder.releaseName.setText(currentItem.getName());
@ -111,25 +123,25 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
}
if(currentItem.getAuthor().getAvatar_url() != null) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAuthor().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.authorAvatar);
PicassoService.getInstance(context).get().load(currentItem.getAuthor().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.authorAvatar);
}
holder.authorName.setText(mCtx.getResources().getString(R.string.releasePublishedBy, currentItem.getAuthor().getUsername()));
holder.authorName.setText(context.getResources().getString(R.string.releasePublishedBy, currentItem.getAuthor().getUsername()));
if(currentItem.getTag_name() != null) {
holder.releaseTag.setText(currentItem.getTag_name());
}
if(currentItem.getPublished_at() != null) {
holder.releaseDate.setText(TimeHelper.formatTime(currentItem.getPublished_at(), new Locale(locale), timeFormat, mCtx));
holder.releaseDate.setText(TimeHelper.formatTime(currentItem.getPublished_at(), locale, timeFormat, context));
}
if(timeFormat.equals("pretty")) {
holder.releaseDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getPublished_at()), mCtx));
holder.releaseDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getPublished_at()), context));
}
if(!currentItem.getBody().equals("")) {
new Markdown(mCtx, currentItem.getBody(), holder.releaseBodyContent);
Markdown.render(context, currentItem.getBody(), holder.releaseBodyContent);
}
else {
holder.releaseBodyContent.setText(R.string.noReleaseBodyContent);
@ -141,28 +153,25 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
holder.downloadDropdownIcon.setImageResource(R.drawable.ic_chevron_down);
holder.downloads.setVisibility(View.VISIBLE);
}
else {
holder.downloadDropdownIcon.setImageResource(R.drawable.ic_chevron_right);
holder.downloads.setVisibility(View.GONE);
}
});
holder.releaseZipDownload.setText(
HtmlCompat.fromHtml("<a href='" + currentItem.getZipball_url() + "'>" + mCtx.getResources().getString(R.string.zipArchiveDownloadReleasesTab) + "</a> ", HtmlCompat.FROM_HTML_MODE_LEGACY));
HtmlCompat.fromHtml("<a href='" + currentItem.getZipball_url() + "'>" + context.getResources().getString(R.string.zipArchiveDownloadReleasesTab) + "</a> ", HtmlCompat.FROM_HTML_MODE_LEGACY));
holder.releaseZipDownload.setMovementMethod(LinkMovementMethod.getInstance());
holder.releaseTarDownload.setText(
HtmlCompat.fromHtml("<a href='" + currentItem.getTarball_url() + "'>" + mCtx.getResources().getString(R.string.tarArchiveDownloadReleasesTab) + "</a> ", HtmlCompat.FROM_HTML_MODE_LEGACY));
HtmlCompat.fromHtml("<a href='" + currentItem.getTarball_url() + "'>" + context.getResources().getString(R.string.tarArchiveDownloadReleasesTab) + "</a> ", HtmlCompat.FROM_HTML_MODE_LEGACY));
holder.releaseTarDownload.setMovementMethod(LinkMovementMethod.getInstance());
ReleasesDownloadsAdapter adapter = new ReleasesDownloadsAdapter(currentItem.getAssets());
holder.downloadList.setAdapter(adapter);
}
@Override

View File

@ -18,18 +18,16 @@ import java.util.List;
public class ReleasesDownloadsAdapter extends RecyclerView.Adapter<ReleasesDownloadsAdapter.ReleasesDownloadsViewHolder> {
private List<Releases.assetsObject> releasesDownloadsList;
private final List<Releases.assetsObject> releasesDownloadsList;
static class ReleasesDownloadsViewHolder extends RecyclerView.ViewHolder {
private TextView downloadName;
private final TextView downloadName;
private ReleasesDownloadsViewHolder(View itemView) {
super(itemView);
downloadName = itemView.findViewById(R.id.downloadName);
}
}
@ -57,7 +55,6 @@ public class ReleasesDownloadsAdapter extends RecyclerView.Adapter<ReleasesDownl
holder.downloadName.setMovementMethod(LinkMovementMethod.getInstance());
}
}
@Override

View File

@ -9,29 +9,31 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
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 com.google.android.material.bottomsheet.BottomSheetDialog;
import org.gitnex.tea4j.models.UserRepositories;
import org.gitnex.tea4j.models.WatchInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoForksActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
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.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.Toasty;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
@ -41,7 +43,7 @@ import retrofit2.Callback;
public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context ctx;
private final Context context;
private final int TYPE_LOAD = 0;
private List<UserRepositories> forksList;
private OnLoadMoreListener loadMoreListener;
@ -50,16 +52,15 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
public RepoForksAdapter(Context ctx, List<UserRepositories> forksListMain) {
this.ctx = ctx;
this.context = ctx;
this.forksList = forksListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(ctx);
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new RepoForksAdapter.ForksHolder(inflater.inflate(R.layout.list_repositories, parent, false));
@ -67,7 +68,6 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
@ -77,15 +77,12 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((RepoForksAdapter.ForksHolder) holder).bindData(forksList.get(position));
}
}
@Override
@ -97,69 +94,63 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
else {
return 1;
}
}
@Override
public int getItemCount() {
return forksList.size();
}
class ForksHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView repoName;
private TextView repoDescription;
private TextView fullName;
private UserRepositories userRepositories;
private final ImageView image;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private ImageView reposDropdownMenu;
private final TextView repoStars;
private final TextView repoLastUpdated;
ForksHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
}
@SuppressLint("SetTextI18n")
void bindData(UserRepositories forksModel) {
repoDescription.setVisibility(View.GONE);
repoBranch.setText(forksModel.getDefault_branch());
TinyDB tinyDb = TinyDB.getInstance(context);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
this.userRepositories = forksModel;
orgName.setText(forksModel.getFullName().split("/")[0]);
repoName.setText(forksModel.getFullName().split("/")[1]);
repoStars.setText(forksModel.getStars_count());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(forksModel.getName());
String firstCharacter = String.valueOf(forksModel.getName().charAt(0));
String firstCharacter = String.valueOf(forksModel.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28)
.endConfig().buildRoundRect(firstCharacter, color, 3);
if(forksModel.getAvatar_url() != null) {
if(!forksModel.getAvatar_url().equals("")) {
PicassoService.getInstance(ctx).get().load(forksModel.getAvatar_url()).placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(image);
PicassoService.getInstance(context).get().load(forksModel.getAvatar_url()).placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(image);
}
else {
image.setImageDrawable(drawable);
@ -169,76 +160,85 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
image.setImageDrawable(drawable);
}
repoName.setText(forksModel.getName());
if(forksModel.getUpdated_at() != null) {
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(forksModel.getUpdated_at());
repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(forksModel.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(forksModel.getUpdated_at());
repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(forksModel.getUpdated_at());
repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
}
else {
repoLastUpdated.setVisibility(View.GONE);
}
if(!forksModel.getDescription().equals("")) {
repoDescription.setVisibility(View.VISIBLE);
repoDescription.setText(forksModel.getDescription());
}
fullName.setText(forksModel.getFullName());
if(forksModel.getPrivateFlag()) {
repoPrivatePublic.setImageResource(R.drawable.ic_lock);
repoType.setText(R.string.strPrivate);
}
else {
repoPrivatePublic.setVisibility(View.GONE);
repoType.setText(R.string.strPublic);
repoDescription.setText(context.getString(R.string.noDataDescription));
}
repoStars.setText(forksModel.getStars_count());
repoForks.setText(forksModel.getForks_count());
repoOpenIssuesCount.setText(forksModel.getOpen_issues_count());
if(isRepoAdmin == null) {
isRepoAdmin = new CheckBox(ctx);
isRepoAdmin = new CheckBox(context);
}
isRepoAdmin.setChecked(forksModel.getPermissions().isAdmin());
if(forksModel.isArchived()) {
archiveRepo.setVisibility(View.VISIBLE);
}
else {
archiveRepo.setVisibility(View.GONE);
}
itemView.setOnClickListener(v -> {
Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName);
TextView repoType_ = v.findViewById(R.id.repoType);
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", repoFullName.getText().toString());
intent.putExtra("repoFullName", userRepositories.getFullName());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putString("repoType", repoType_.getText().toString());
tinyDb.putString("repoFullName", userRepositories.getFullName());
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString());
tinyDb.putString("repoBranch", userRepositories.getDefault_branch());
String[] parts = repoFullName.getText().toString().split("/");
if(userRepositories.getPrivateFlag()) {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPrivate));
}
else {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPublic));
}
String[] parts = userRepositories.getFullName().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
assert repositoryData != null;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
//store if user is watching this repo
@ -291,63 +291,6 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
context.startActivity(intent);
});
reposDropdownMenu.setOnClickListener(v -> {
final Context context = v.getContext();
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader
.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
repoForksList.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
});
}
}
@ -358,32 +301,27 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(RepoForksAdapter.OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<UserRepositories> list) {

View File

@ -2,6 +2,7 @@ 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;
@ -11,7 +12,9 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import java.util.List;
@ -22,22 +25,35 @@ import java.util.List;
public class RepoStargazersAdapter extends BaseAdapter {
private List<UserInfo> stargazersList;
private Context mCtx;
private final List<UserInfo> stargazersList;
private final Context context;
private static class ViewHolder {
private class ViewHolder {
private ImageView memberAvatar;
private TextView memberName;
private UserInfo userInfo;
private final ImageView memberAvatar;
private final TextView memberName;
ViewHolder(View v) {
memberAvatar = v.findViewById(R.id.memberAvatar);
memberName = v.findViewById(R.id.memberName);
memberAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userInfo.getLogin());
context.startActivity(intent);
});
memberAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
return true;
});
}
}
public RepoStargazersAdapter(Context mCtx, List<UserInfo> membersListMain) {
this.mCtx = mCtx;
public RepoStargazersAdapter(Context ctx, List<UserInfo> membersListMain) {
this.context = ctx;
this.stargazersList = membersListMain;
}
@ -63,7 +79,7 @@ public class RepoStargazersAdapter extends BaseAdapter {
RepoStargazersAdapter.ViewHolder viewHolder;
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_repo_stargazers, null);
finalView = LayoutInflater.from(context).inflate(R.layout.list_repo_stargazers, null);
viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder);
}
@ -79,23 +95,26 @@ public class RepoStargazersAdapter extends BaseAdapter {
private void initData(RepoStargazersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = stargazersList.get(position);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
viewHolder.userInfo = currentItem;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
final TinyDB tinyDb = TinyDB.getInstance(mCtx);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
final TinyDB tinyDb = TinyDB.getInstance(context);
Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/roboto.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/manroperegular.ttf");
break;
}

View File

@ -2,6 +2,7 @@ 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;
@ -11,7 +12,9 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import java.util.List;
@ -22,22 +25,35 @@ import java.util.List;
public class RepoWatchersAdapter extends BaseAdapter {
private List<UserInfo> watchersList;
private Context mCtx;
private final List<UserInfo> watchersList;
private final Context context;
private static class ViewHolder {
private class ViewHolder {
private ImageView memberAvatar;
private TextView memberName;
private UserInfo userInfo;
private final ImageView memberAvatar;
private final TextView memberName;
ViewHolder(View v) {
memberAvatar = v.findViewById(R.id.memberAvatar);
memberName = v.findViewById(R.id.memberName);
memberAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userInfo.getLogin());
context.startActivity(intent);
});
memberAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
return true;
});
}
}
public RepoWatchersAdapter(Context mCtx, List<UserInfo> membersListMain) {
this.mCtx = mCtx;
public RepoWatchersAdapter(Context ctx, List<UserInfo> membersListMain) {
this.context = ctx;
this.watchersList = membersListMain;
}
@ -63,7 +79,7 @@ public class RepoWatchersAdapter extends BaseAdapter {
RepoWatchersAdapter.ViewHolder viewHolder;
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_repo_watchers, null);
finalView = LayoutInflater.from(context).inflate(R.layout.list_repo_watchers, null);
viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder);
}
@ -79,23 +95,26 @@ public class RepoWatchersAdapter extends BaseAdapter {
private void initData(RepoWatchersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = watchersList.get(position);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
viewHolder.userInfo = currentItem;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
final TinyDB tinyDb = TinyDB.getInstance(mCtx);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
final TinyDB tinyDb = TinyDB.getInstance(context);
Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/roboto.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/manroperegular.ttf");
break;
}

View File

@ -1,8 +1,5 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
@ -13,31 +10,32 @@ import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
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 com.google.android.material.bottomsheet.BottomSheetDialog;
import org.gitnex.tea4j.models.UserRepositories;
import org.gitnex.tea4j.models.WatchInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoForksActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
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.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.Toasty;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
@ -47,81 +45,73 @@ import retrofit2.Callback;
public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.ReposViewHolder> implements Filterable {
private List<UserRepositories> reposList;
private Context mCtx;
private List<UserRepositories> reposListFull;
private final List<UserRepositories> reposList;
private final Context context;
private final List<UserRepositories> reposListFull;
static class ReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView repoName;
private TextView repoDescription;
private TextView fullName;
private UserRepositories userRepositories;
private final ImageView image;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private TextView htmlUrl;
private final TextView repoStars;
private final TextView repoLastUpdated;
private ReposViewHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName);
TextView repoType_ = v.findViewById(R.id.repoType);
TinyDB tinyDb = TinyDB.getInstance(context);
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", repoFullName.getText().toString());
intent.putExtra("repoFullName", userRepositories.getFullName());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putString("repoType", repoType_.getText().toString());
tinyDb.putString("repoFullName", userRepositories.getFullName());
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString());
tinyDb.putString("repoBranch", userRepositories.getDefault_branch());
String[] parts = repoFullName.getText().toString().split("/");
if(userRepositories.getPrivateFlag()) {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPrivate));
}
else {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPublic));
}
String[] parts = userRepositories.getFullName().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
assert repositoryData != null;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
//store if user is watching this repo
@ -173,81 +163,13 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
context.startActivity(intent);
});
reposDropdownMenu.setOnClickListener(v -> {
final Context context = v.getContext();
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
});
}
}
public ReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
public ReposListAdapter(Context ctx, List<UserRepositories> reposListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList);
}
@ -263,20 +185,26 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
@Override
public void onBindViewHolder(@NonNull ReposViewHolder holder, int position) {
TinyDB tinyDb = TinyDB.getInstance(context);
UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
holder.repoStars.setText(currentItem.getStars_count());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
if(currentItem.getAvatar_url() != null) {
if(!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
}
else {
holder.image.setImageDrawable(drawable);
@ -286,35 +214,45 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
holder.image.setImageDrawable(drawable);
}
holder.repoName.setText(currentItem.getName());
if(currentItem.getUpdated_at() != null) {
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
}
else {
holder.repoLastUpdated.setVisibility(View.GONE);
}
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
}
holder.fullName.setText(currentItem.getFullName());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
}
else {
holder.repoPrivatePublic.setVisibility(View.GONE);
holder.repoType.setText(R.string.strPublic);
holder.repoDescription.setText(context.getString(R.string.noDataDescription));
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
holder.isRepoAdmin = new CheckBox(context);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override
@ -329,7 +267,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
return reposFilter;
}
private Filter reposFilter = new Filter() {
private final Filter reposFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {

View File

@ -1,8 +1,5 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
@ -13,31 +10,32 @@ import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
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 com.google.android.material.bottomsheet.BottomSheetDialog;
import org.gitnex.tea4j.models.UserRepositories;
import org.gitnex.tea4j.models.WatchInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoForksActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
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.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.Toasty;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
@ -47,78 +45,73 @@ import retrofit2.Callback;
public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesByOrgAdapter.OrgReposViewHolder> implements Filterable {
private List<UserRepositories> reposList;
private Context mCtx;
private List<UserRepositories> reposListFull;
private final List<UserRepositories> reposList;
private final Context context;
private final List<UserRepositories> reposListFull;
static class OrgReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView repoName;
private TextView repoDescription;
private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private TextView htmlUrl;
private UserRepositories userRepositories;
private final ImageView image;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private final TextView repoStars;
private final TextView repoLastUpdated;
private OrgReposViewHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar);
repoStars = itemView.findViewById(R.id.repoStars);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
TinyDB tinyDb = TinyDB.getInstance(context);
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", fullName.getText().toString());
intent.putExtra("repoFullName", userRepositories.getFullName());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("repoFullName", fullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString());
tinyDb.putString("repoFullName", userRepositories.getFullName());
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString());
tinyDb.putString("repoBranch", userRepositories.getDefault_branch());
String[] parts = fullName.getText().toString().split("/");
if(userRepositories.getPrivateFlag()) {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPrivate));
}
else {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPublic));
}
String[] parts = userRepositories.getFullName().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
assert repositoryData != null;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
//store if user is watching this repo
@ -167,81 +160,13 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
context.startActivity(intent);
});
reposDropdownMenu.setOnClickListener(v -> {
final Context context = v.getContext();
@SuppressLint("InflateParams")
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
});
}
}
public RepositoriesByOrgAdapter(Context mCtx, List<UserRepositories> reposListMain) {
this.mCtx = mCtx;
public RepositoriesByOrgAdapter(Context ctx, List<UserRepositories> reposListMain) {
this.context = ctx;
this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList);
}
@ -249,6 +174,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
@NonNull
@Override
public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new RepositoriesByOrgAdapter.OrgReposViewHolder(v);
}
@ -256,14 +182,20 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
@Override
public void onBindViewHolder(@NonNull RepositoriesByOrgAdapter.OrgReposViewHolder holder, int position) {
UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
TinyDB tinyDb = TinyDB.getInstance(context);
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
holder.repoStars.setText(currentItem.getStars_count());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
@ -277,7 +209,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
@ -286,36 +218,45 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
holder.image.setImageDrawable(drawable);
}
holder.repoName.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
}
holder.fullName.setText(currentItem.getFullName());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
}
else {
holder.repoPrivatePublic.setVisibility(View.GONE);
holder.repoType.setText(R.string.strPublic);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(currentItem.getUpdated_at() != null) {
if (holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
}
else {
holder.archiveRepo.setVisibility(View.GONE);
holder.repoLastUpdated.setVisibility(View.GONE);
}
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setText(currentItem.getDescription());
}
else {
holder.repoDescription.setText(context.getString(R.string.noDataDescription));
}
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(context);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
}
@Override

View File

@ -1,59 +0,0 @@
package org.mian.gitnex.adapters;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import java.util.List;
/**
* Author M M Arif
*/
public class SponsorsAdapter extends RecyclerView.Adapter<SponsorsAdapter.SponsorsViewHolder> {
private List<CharSequence> sponsorsList;
static class SponsorsViewHolder extends RecyclerView.ViewHolder {
private TextView sponsorText;
private SponsorsViewHolder(View itemView) {
super(itemView);
sponsorText = itemView.findViewById(R.id.sponsorText);
}
}
public SponsorsAdapter(List<CharSequence> sponsorsListMain) {
this.sponsorsList = sponsorsListMain;
}
@NonNull
@Override
public SponsorsAdapter.SponsorsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.sponsors, parent, false);
return new SponsorsAdapter.SponsorsViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull SponsorsAdapter.SponsorsViewHolder holder, int position) {
SpannableStringBuilder strBuilder = new SpannableStringBuilder(sponsorsList.get(position));
holder.sponsorText.setText((strBuilder));
holder.sponsorText.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
public int getItemCount() {
return sponsorsList.size();
}
}

View File

@ -1,8 +1,5 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
@ -13,31 +10,32 @@ import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
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 com.google.android.material.bottomsheet.BottomSheetDialog;
import org.gitnex.tea4j.models.UserRepositories;
import org.gitnex.tea4j.models.WatchInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoForksActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
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.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.Toasty;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
@ -47,78 +45,73 @@ import retrofit2.Callback;
public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposListAdapter.StarredReposViewHolder> implements Filterable {
private List<UserRepositories> reposList;
private Context mCtx;
private List<UserRepositories> reposListFull;
private final List<UserRepositories> reposList;
private final Context context;
private final List<UserRepositories> reposListFull;
static class StarredReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView repoName;
private TextView repoDescription;
private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private TextView htmlUrl;
private UserRepositories userRepositories;
private final ImageView image;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private final TextView repoStars;
private final TextView repoLastUpdated;
private StarredReposViewHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar);
repoStars = itemView.findViewById(R.id.repoStars);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
TinyDB tinyDb = TinyDB.getInstance(context);
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", fullName.getText().toString());
intent.putExtra("repoFullName", userRepositories.getFullName());
TinyDB tinyDb = TinyDB.getInstance(context);
tinyDb.putString("repoFullName", fullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString());
tinyDb.putString("repoFullName", userRepositories.getFullName());
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString());
tinyDb.putString("repoBranch", userRepositories.getDefault_branch());
String[] parts = fullName.getText().toString().split("/");
if(userRepositories.getPrivateFlag()) {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPrivate));
}
else {
tinyDb.putString("repoType", context.getResources().getString(R.string.strPublic));
}
String[] parts = userRepositories.getFullName().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
assert repositoryData != null;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
//store if user is watching this repo
@ -170,81 +163,12 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
context.startActivity(intent);
});
reposDropdownMenu.setOnClickListener(v -> {
final Context context = v.getContext();
@SuppressLint("InflateParams")
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
});
}
}
public StarredReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
this.mCtx = mCtx;
public StarredReposListAdapter(Context ctx, List<UserRepositories> reposListMain) {
this.context = ctx;
this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList);
}
@ -259,14 +183,20 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
@Override
public void onBindViewHolder(@NonNull StarredReposListAdapter.StarredReposViewHolder holder, int position) {
UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
TinyDB tinyDb = TinyDB.getInstance(context);
UserRepositories currentItem = reposList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
holder.userRepositories = currentItem;
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
holder.repoStars.setText(currentItem.getStars_count());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
@ -280,7 +210,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
@ -289,35 +219,45 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
holder.image.setImageDrawable(drawable);
}
holder.repoName.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
}
holder.fullName.setText(currentItem.getFullName());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
if(currentItem.getUpdated_at() != null) {
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
String createdTime = formatter.format(currentItem.getUpdated_at());
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
}
else {
holder.repoPrivatePublic.setVisibility(View.GONE);
holder.repoType.setText(R.string.strPublic);
holder.repoLastUpdated.setVisibility(View.GONE);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if (holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setText(currentItem.getDescription());
}
else {
holder.archiveRepo.setVisibility(View.GONE);
holder.repoDescription.setText(context.getString(R.string.noDataDescription));
}
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(context);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
}
@Override
@ -330,7 +270,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
return starredReposFilter;
}
private Filter starredReposFilter = new Filter() {
private final Filter starredReposFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<UserRepositories> filteredList = new ArrayList<>();

View File

@ -2,6 +2,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.text.Html;
import android.view.LayoutInflater;
@ -12,6 +13,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@ -25,9 +27,9 @@ import java.util.List;
public class TeamMembersByOrgAdapter extends BaseAdapter {
private final List<UserInfo> teamMembersList;
private final Context mCtx;
private final Context context;
private static class ViewHolder {
private class ViewHolder {
private String userLoginId;
@ -40,17 +42,21 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
memberName = v.findViewById(R.id.memberName);
memberAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userLoginId);
context.startActivity(intent);
});
Context context = loginId.getContext();
memberAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
return true;
});
}
}
public TeamMembersByOrgAdapter(Context mCtx, List<UserInfo> membersListMain) {
public TeamMembersByOrgAdapter(Context ctx, List<UserInfo> membersListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.teamMembersList = membersListMain;
}
@ -77,7 +83,7 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_members_by_team_by_org, null);
finalView = LayoutInflater.from(context).inflate(R.layout.list_members_by_team_by_org, null);
viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder);
}
@ -93,25 +99,27 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
private void initData(TeamMembersByOrgAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = teamMembersList.get(position);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
viewHolder.userLoginId = currentItem.getLogin();
final TinyDB tinyDb = TinyDB.getInstance(mCtx);
final TinyDB tinyDb = TinyDB.getInstance(context);
Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/roboto.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/manroperegular.ttf");
break;
}

View File

@ -22,44 +22,41 @@ import java.util.List;
public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.OrgTeamsViewHolder> implements Filterable {
private List<Teams> teamList;
private Context mCtx;
private List<Teams> teamListFull;
private final List<Teams> teamList;
private final Context context;
private final List<Teams> teamListFull;
static class OrgTeamsViewHolder extends RecyclerView.ViewHolder {
private TextView teamTitle;
private TextView teamId;
private TextView teamDescription;
private TextView teamPermission;
private Teams teams;
private final TextView teamTitle;
private final TextView teamDescription;
private final TextView teamPermission;
private OrgTeamsViewHolder(View itemView) {
super(itemView);
teamTitle = itemView.findViewById(R.id.teamTitle);
teamId = itemView.findViewById(R.id.teamId);
teamDescription = itemView.findViewById(R.id.teamDescription);
teamPermission = itemView.findViewById(R.id.teamPermission);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemView.setOnClickListener(v -> {
Context context = v.getContext();
Context context = v.getContext();
Intent intent = new Intent(context, OrganizationTeamMembersActivity.class);
intent.putExtra("teamTitle", teamTitle.getText().toString());
intent.putExtra("teamId", teamId.getText().toString());
context.startActivity(intent);
}
Intent intent = new Intent(context, OrganizationTeamMembersActivity.class);
intent.putExtra("teamTitle", teams.getName());
intent.putExtra("teamId", String.valueOf(teams.getId()));
context.startActivity(intent);
});
}
}
public TeamsByOrgAdapter(Context mCtx, List<Teams> teamListMain) {
this.mCtx = mCtx;
public TeamsByOrgAdapter(Context ctx, List<Teams> teamListMain) {
this.context = ctx;
this.teamList = teamListMain;
teamListFull = new ArrayList<>(teamList);
}
@ -75,8 +72,10 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.Or
public void onBindViewHolder(@NonNull TeamsByOrgAdapter.OrgTeamsViewHolder holder, int position) {
Teams currentItem = teamList.get(position);
holder.teamId.setText(String.valueOf(currentItem.getId()));
holder.teams = currentItem;
holder.teamTitle.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.teamDescription.setVisibility(View.VISIBLE);
holder.teamDescription.setText(currentItem.getDescription());
@ -85,8 +84,7 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.Or
holder.teamDescription.setVisibility(View.GONE);
holder.teamDescription.setText("");
}
holder.teamPermission.setText(mCtx.getResources().getString(R.string.teamPermission, currentItem.getPermission()));
holder.teamPermission.setText(context.getResources().getString(R.string.teamPermission, currentItem.getPermission()));
}
@Override
@ -99,7 +97,7 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.Or
return orgTeamsFilter;
}
private Filter orgTeamsFilter = new Filter() {
private final Filter orgTeamsFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Teams> filteredList = new ArrayList<>();

View File

@ -14,8 +14,10 @@ import androidx.appcompat.content.res.AppCompatResources;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
@ -29,7 +31,7 @@ import io.mikael.urlbuilder.UrlBuilder;
public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapter.UserAccountsViewHolder> {
private final List<UserAccount> userAccountsList;
private final Context mCtx;
private final Context context;
private TinyDB tinyDB;
class UserAccountsViewHolder extends RecyclerView.ViewHolder {
@ -55,49 +57,45 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
deleteAccount.setOnClickListener(itemDelete -> {
new AlertDialog.Builder(mCtx)
.setIcon(AppCompatResources.getDrawable(mCtx, R.drawable.ic_delete))
.setTitle(mCtx.getResources().getString(R.string.removeAccountPopupTitle))
.setMessage(mCtx.getResources().getString(R.string.removeAccountPopupMessage))
.setPositiveButton(mCtx.getResources().getString(R.string.removeButton), (dialog, which) -> {
new AlertDialog.Builder(context)
.setIcon(AppCompatResources.getDrawable(context, R.drawable.ic_delete))
.setTitle(context.getResources().getString(R.string.removeAccountPopupTitle))
.setMessage(context.getResources().getString(R.string.removeAccountPopupMessage))
.setPositiveButton(context.getResources().getString(R.string.removeButton), (dialog, which) -> {
updateLayoutByPosition(getAdapterPosition());
UserAccountsApi userAccountsApi = new UserAccountsApi(mCtx);
UserAccountsApi userAccountsApi = BaseApi.getInstance(context, UserAccountsApi.class);
assert userAccountsApi != null;
userAccountsApi.deleteAccount(Integer.parseInt(String.valueOf(accountId)));
}).setNeutralButton(mCtx.getResources().getString(R.string.cancelButton), null)
}).setNeutralButton(context.getResources().getString(R.string.cancelButton), null)
.show();
});
itemView.setOnClickListener(switchAccount -> {
UserAccountsApi userAccountsApi = new UserAccountsApi(mCtx);
UserAccount userAccount = userAccountsApi.getAccountData(accountName);
UserAccountsApi userAccountsApi = BaseApi.getInstance(context, UserAccountsApi.class);
assert userAccountsApi != null;
UserAccount userAccount = userAccountsApi.getAccountByName(accountName);
if(tinyDB.getInt("currentActiveAccountId") != userAccount.getAccountId()) {
if(AppUtil.switchToAccount(context, userAccount)) {
String url = UrlBuilder.fromString(userAccount.getInstanceUrl())
.withPath("/")
.toString();
tinyDB.putString("loginUid", userAccount.getUserName());
tinyDB.putString("userLogin", userAccount.getUserName());
tinyDB.putString(userAccount.getUserName() + "-token", userAccount.getToken());
tinyDB.putString("instanceUrl", userAccount.getInstanceUrl());
tinyDB.putInt("currentActiveAccountId", userAccount.getAccountId());
Toasty.success(context, context.getResources().getString(R.string.switchAccountSuccess, userAccount.getUserName(), url));
((Activity) context).recreate();
Toasty.success(mCtx, mCtx.getResources().getString(R.string.switchAccountSuccess, userAccount.getUserName(), url));
((Activity) mCtx).recreate();
}
});
}
}
public UserAccountsAdapter(Context mCtx, List<UserAccount> userAccountsListMain) {
public UserAccountsAdapter(Context ctx, List<UserAccount> userAccountsListMain) {
this.mCtx = mCtx;
this.context = ctx;
this.userAccountsList = userAccountsListMain;
}
@ -106,7 +104,7 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
userAccountsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, userAccountsList.size());
Toasty.success(mCtx, mCtx.getResources().getString(R.string.accountDeletedMessage));
Toasty.success(context, context.getResources().getString(R.string.accountDeletedMessage));
}
@NonNull
@ -122,7 +120,7 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
public void onBindViewHolder(@NonNull UserAccountsAdapter.UserAccountsViewHolder holder, int position) {
UserAccount currentItem = userAccountsList.get(position);
tinyDB = TinyDB.getInstance(mCtx);
tinyDB = TinyDB.getInstance(context);
String url = UrlBuilder.fromString(currentItem.getInstanceUrl())
.withPath("/")
@ -131,17 +129,23 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
holder.accountId = currentItem.getAccountId();
holder.accountName = currentItem.getAccountName();
holder.userId.setText(String.format("@%s", currentItem.getUserName()));
holder.userId.setText(currentItem.getUserName());
holder.accountUrl.setText(url);
PicassoService.getInstance(mCtx).get().load(url + "img/favicon.png").placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.repoAvatar);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context).get()
.load(url + "img/favicon.png")
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(holder.repoAvatar);
if(tinyDB.getInt("currentActiveAccountId") == currentItem.getAccountId()) {
holder.activeAccount.setVisibility(View.VISIBLE);
}
else {
holder.deleteAccount.setVisibility(View.VISIBLE);
}
}

View File

@ -12,6 +12,7 @@ import androidx.annotation.Nullable;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import java.util.List;
@ -23,18 +24,17 @@ import io.mikael.urlbuilder.UrlBuilder;
public class UserAccountsListDialogAdapter extends ArrayAdapter<UserAccount> {
private final Context mCtx;
private final Context context;
private final TinyDB tinyDB;
private final List<UserAccount> userAccounts;
public UserAccountsListDialogAdapter(@NonNull Context mCtx, int resource, @NonNull List<UserAccount> userAccounts) {
public UserAccountsListDialogAdapter(@NonNull Context ctx, int resource, @NonNull List<UserAccount> userAccounts) {
super(mCtx, resource, userAccounts);
super(ctx, resource, userAccounts);
tinyDB = TinyDB.getInstance(mCtx);
tinyDB = TinyDB.getInstance(ctx);
this.userAccounts = userAccounts;
this.mCtx = mCtx;
this.context = ctx;
}
@NonNull
@ -42,7 +42,7 @@ public class UserAccountsListDialogAdapter extends ArrayAdapter<UserAccount> {
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
if(convertView == null) {
convertView = LayoutInflater.from(mCtx).inflate(R.layout.custom_user_accounts_list, parent, false);
convertView = LayoutInflater.from(context).inflate(R.layout.custom_user_accounts_list, parent, false);
}
ImageView profileImage = convertView.findViewById(R.id.profileImage);
@ -51,6 +51,7 @@ public class UserAccountsListDialogAdapter extends ArrayAdapter<UserAccount> {
ImageView activeAccount = convertView.findViewById(R.id.activeAccount);
UserAccount currentItem = userAccounts.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
String url = UrlBuilder.fromString(currentItem.getInstanceUrl())
.withPath("/")
@ -67,7 +68,7 @@ public class UserAccountsListDialogAdapter extends ArrayAdapter<UserAccount> {
}
PicassoService
.getInstance(mCtx).get().load(url + "img/favicon.png").placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(profileImage);
.getInstance(context).get().load(url + "img/favicon.png").placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(profileImage);
return convertView;

View File

@ -18,11 +18,10 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.fragments.UserAccountsFragment;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.List;
import io.mikael.urlbuilder.UrlBuilder;
@ -34,13 +33,13 @@ import io.mikael.urlbuilder.UrlBuilder;
public class UserAccountsNavAdapter extends RecyclerView.Adapter<UserAccountsNavAdapter.UserAccountsViewHolder> {
private static DrawerLayout drawer;
private List<UserAccount> userAccountsList;
private Context mCtx;
private TextView toolbarTitle;
private final List<UserAccount> userAccountsList;
private final Context context;
private final TextView toolbarTitle;
public UserAccountsNavAdapter(Context mCtx, List<UserAccount> userAccountsListMain, DrawerLayout drawerLayout, TextView toolbarTitle) {
public UserAccountsNavAdapter(Context ctx, List<UserAccount> userAccountsListMain, DrawerLayout drawerLayout, TextView toolbarTitle) {
this.mCtx = mCtx;
this.context = ctx;
this.userAccountsList = userAccountsListMain;
drawer = drawerLayout;
this.toolbarTitle = toolbarTitle;
@ -48,7 +47,7 @@ public class UserAccountsNavAdapter extends RecyclerView.Adapter<UserAccountsNav
class UserAccountsViewHolder extends RecyclerView.ViewHolder {
private ImageView userAccountAvatar;
private final ImageView userAccountAvatar;
private UserAccountsViewHolder(View itemView) {
@ -57,7 +56,6 @@ public class UserAccountsNavAdapter extends RecyclerView.Adapter<UserAccountsNav
userAccountAvatar = itemView.findViewById(R.id.userAccountAvatar);
itemView.setOnClickListener(item -> {
customDialogUserAccountsList(userAccountsList);
drawer.closeDrawers();
});
@ -84,8 +82,15 @@ public class UserAccountsNavAdapter extends RecyclerView.Adapter<UserAccountsNav
.withPath("/")
.toString();
PicassoService
.getInstance(mCtx).get().load(url + "img/favicon.png").placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAccountAvatar);
int imageSize = AppUtil.getPixelsFromDensity(context, 35);
PicassoService.getInstance(context).get()
.load(url + "img/favicon.png")
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0))
.resize(imageSize, imageSize)
.centerCrop()
.into(holder.userAccountAvatar);
}
@Override
@ -96,8 +101,7 @@ public class UserAccountsNavAdapter extends RecyclerView.Adapter<UserAccountsNav
private void customDialogUserAccountsList(List<UserAccount> allAccountsList) {
TinyDB tinyDB = TinyDB.getInstance(mCtx);
Dialog dialog = new Dialog(mCtx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
Dialog dialog = new Dialog(context, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
dialog.setContentView(R.layout.custom_user_accounts_dialog);
ListView listView = dialog.findViewById(R.id.accountsList);
@ -109,38 +113,33 @@ public class UserAccountsNavAdapter extends RecyclerView.Adapter<UserAccountsNav
manageAccounts.setOnClickListener(item -> {
toolbarTitle.setText(mCtx.getResources().getString(R.string.pageTitleUserAccounts));
AppCompatActivity activity = (AppCompatActivity) mCtx;
toolbarTitle.setText(context.getResources().getString(R.string.pageTitleUserAccounts));
AppCompatActivity activity = (AppCompatActivity) context;
activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new UserAccountsFragment()).commit();
dialog.dismiss();
});
UserAccountsListDialogAdapter arrayAdapter = new UserAccountsListDialogAdapter(mCtx, R.layout.custom_user_accounts_list, allAccountsList);
UserAccountsListDialogAdapter arrayAdapter = new UserAccountsListDialogAdapter(context, R.layout.custom_user_accounts_list, allAccountsList);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener((adapterView, view, which, l) -> {
String accountNameSwitch = allAccountsList.get(which).getAccountName();
UserAccountsApi userAccountsApi = new UserAccountsApi(mCtx);
UserAccount userAccount = userAccountsApi.getAccountData(accountNameSwitch);
UserAccount userAccount = allAccountsList.get(which);
if(tinyDB.getInt("currentActiveAccountId") != userAccount.getAccountId()) {
if(AppUtil.switchToAccount(context, userAccount)) {
String url = UrlBuilder.fromString(userAccount.getInstanceUrl())
.withPath("/")
.toString();
tinyDB.putString("loginUid", userAccount.getUserName());
tinyDB.putString("userLogin", userAccount.getUserName());
tinyDB.putString(userAccount.getUserName() + "-token", userAccount.getToken());
tinyDB.putString("instanceUrl", userAccount.getInstanceUrl());
tinyDB.putInt("currentActiveAccountId", userAccount.getAccountId());
Toasty.success(mCtx, mCtx.getResources().getString(R.string.switchAccountSuccess, userAccount.getUserName(), url));
((Activity) mCtx).recreate();
Toasty.success(context, context.getResources().getString(R.string.switchAccountSuccess, userAccount.getUserName(), url));
((Activity) context).recreate();
dialog.dismiss();
}
});
dialog.show();
}

View File

@ -1,7 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
@ -17,9 +17,11 @@ import org.gitnex.tea4j.models.Collaborators;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.CollaboratorActions;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
@ -34,86 +36,75 @@ import retrofit2.Response;
public class UserSearchAdapter extends RecyclerView.Adapter<UserSearchAdapter.UserSearchViewHolder> {
private List<UserInfo> usersSearchList;
private Context mCtx;
private final List<UserInfo> usersSearchList;
private final Context context;
public UserSearchAdapter(List<UserInfo> dataList, Context mCtx) {
this.mCtx = mCtx;
public UserSearchAdapter(List<UserInfo> dataList, Context ctx) {
this.context = ctx;
this.usersSearchList = dataList;
}
static class UserSearchViewHolder extends RecyclerView.ViewHolder {
class UserSearchViewHolder extends RecyclerView.ViewHolder {
private ImageView userAvatar;
private TextView userFullName;
private TextView userName;
private TextView userNameMain;
private ImageView addCollaboratorButtonAdd;
private ImageView addCollaboratorButtonRemove;
private UserInfo userInfo;
private String[] permissionList = {"Read", "Write", "Admin"};
private final ImageView userAvatar;
private final TextView userFullName;
private final TextView userName;
private final ImageView addCollaboratorButtonAdd;
private final ImageView addCollaboratorButtonRemove;
private final String[] permissionList = {"Read", "Write", "Admin"};
final private int permissionSelectedChoice = 0;
private UserSearchViewHolder(View itemView) {
super(itemView);
userAvatar = itemView.findViewById(R.id.userAvatar);
userFullName = itemView.findViewById(R.id.userFullName);
userName = itemView.findViewById(R.id.userName);
userNameMain = itemView.findViewById(R.id.userNameMain);
addCollaboratorButtonAdd = itemView.findViewById(R.id.addCollaboratorButtonAdd);
addCollaboratorButtonRemove = itemView.findViewById(R.id.addCollaboratorButtonRemove);
addCollaboratorButtonAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addCollaboratorButtonAdd.setOnClickListener(v -> {
AlertDialog.Builder pBuilder = new AlertDialog.Builder(context);
final Context context = v.getContext();
pBuilder.setTitle(R.string.newTeamPermission);
pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, (dialogInterface, i) -> {
AlertDialog.Builder pBuilder = new AlertDialog.Builder(context);
})
.setCancelable(false)
.setNegativeButton(R.string.cancelButton, null)
.setPositiveButton(R.string.addButton, (dialog, which) -> {
pBuilder.setTitle(R.string.newTeamPermission);
pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ListView lw = ((AlertDialog)dialog).getListView();
Object checkedItem = lw.getAdapter().getItem(lw.getCheckedItemPosition());
}
})
.setCancelable(false)
.setNegativeButton(R.string.cancelButton, null)
.setPositiveButton(R.string.addButton, new DialogInterface.OnClickListener() {
CollaboratorActions.addCollaborator(context, String.valueOf(checkedItem).toLowerCase(), userInfo.getUsername());
});
@Override
public void onClick(DialogInterface dialog, int which) {
ListView lw = ((AlertDialog)dialog).getListView();
Object checkedItem = lw.getAdapter().getItem(lw.getCheckedItemPosition());
CollaboratorActions.addCollaborator(context, String.valueOf(checkedItem).toLowerCase(), userNameMain.getText().toString());
}
});
AlertDialog pDialog = pBuilder.create();
pDialog.show();
}
AlertDialog pDialog = pBuilder.create();
pDialog.show();
});
addCollaboratorButtonRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
AlertDialogs.collaboratorRemoveDialog(context, userNameMain.getText().toString(),
context.getResources().getString(R.string.removeCollaboratorTitle),
context.getResources().getString(R.string.removeCollaboratorMessage),
context.getResources().getString(R.string.removeButton),
context.getResources().getString(R.string.cancelButton), "fa");
}
addCollaboratorButtonRemove.setOnClickListener(v -> {
AlertDialogs.collaboratorRemoveDialog(context, userInfo.getUsername(),
context.getResources().getString(R.string.removeCollaboratorTitle),
context.getResources().getString(R.string.removeCollaboratorMessage),
context.getResources().getString(R.string.removeButton),
context.getResources().getString(R.string.cancelButton), "fa");
});
userAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userInfo.getLogin());
context.startActivity(intent);
});
userAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
return true;
});
}
}
@ -128,9 +119,9 @@ public class UserSearchAdapter extends RecyclerView.Adapter<UserSearchAdapter.Us
@Override
public void onBindViewHolder(@NonNull final UserSearchAdapter.UserSearchViewHolder holder, int position) {
final UserInfo currentItem = usersSearchList.get(position);
holder.userNameMain.setText(currentItem.getUsername());
UserInfo currentItem = usersSearchList.get(position);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
holder.userInfo = currentItem;
if (!currentItem.getFullname().equals("")) {
@ -138,18 +129,18 @@ public class UserSearchAdapter extends RecyclerView.Adapter<UserSearchAdapter.Us
}
else {
holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userFullName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
}
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
if (!currentItem.getAvatar().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
if(getItemCount() > 0) {
TinyDB tinyDb = TinyDB.getInstance(mCtx);
TinyDB tinyDb = TinyDB.getInstance(context);
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
@ -157,8 +148,8 @@ public class UserSearchAdapter extends RecyclerView.Adapter<UserSearchAdapter.Us
final String repoName = parts[1];
Call<Collaborators> call = RetrofitClient
.getApiInterface(mCtx)
.checkRepoCollaborator(Authorization.get(mCtx), repoOwner, repoName, currentItem.getUsername());
.getApiInterface(context)
.checkRepoCollaborator(Authorization.get(context), repoOwner, repoName, currentItem.getUsername());
call.enqueue(new Callback<Collaborators>() {

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@ -11,9 +12,11 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
@ -29,25 +32,25 @@ import retrofit2.Response;
public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter<UserSearchForTeamMemberAdapter.UserSearchViewHolder> {
private List<UserInfo> usersSearchList;
private Context mCtx;
private int teamId;
private final List<UserInfo> usersSearchList;
private final Context context;
private static int teamId;
public UserSearchForTeamMemberAdapter(List<UserInfo> dataList, Context mCtx, int teamId) {
this.mCtx = mCtx;
public UserSearchForTeamMemberAdapter(List<UserInfo> dataList, Context ctx, int teamId) {
this.context = ctx;
this.usersSearchList = dataList;
this.teamId = teamId;
UserSearchForTeamMemberAdapter.teamId = teamId;
}
static class UserSearchViewHolder extends RecyclerView.ViewHolder {
class UserSearchViewHolder extends RecyclerView.ViewHolder {
private ImageView userAvatar;
private TextView userFullName;
private TextView userName;
private TextView userNameMain;
private ImageView addMemberButtonAdd;
private ImageView addMemberButtonRemove;
private TextView teamId_;
private UserInfo userInfo;
private final ImageView userAvatar;
private final TextView userFullName;
private final TextView userName;
private final ImageView addMemberButtonAdd;
private final ImageView addMemberButtonRemove;
private UserSearchViewHolder(View itemView) {
@ -55,35 +58,35 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter<UserSea
userAvatar = itemView.findViewById(R.id.userAvatar);
userFullName = itemView.findViewById(R.id.userFullName);
userName = itemView.findViewById(R.id.userName);
userNameMain = itemView.findViewById(R.id.userNameMain);
addMemberButtonAdd = itemView.findViewById(R.id.addCollaboratorButtonAdd);
addMemberButtonRemove = itemView.findViewById(R.id.addCollaboratorButtonRemove);
teamId_ = itemView.findViewById(R.id.teamId);
addMemberButtonAdd.setOnClickListener(v -> {
Context context = v.getContext();
AlertDialogs.addMemberDialog(context, userNameMain.getText().toString(),
AlertDialogs.addMemberDialog(context, userInfo.getLogin(),
context.getResources().getString(R.string.addTeamMemberTitle),
context.getResources().getString(R.string.addTeamMemberMessage),
context.getResources().getString(R.string.addButton),
context.getResources().getString(R.string.cancelButton), Integer.parseInt(teamId_.getText().toString()));
context.getResources().getString(R.string.cancelButton), Integer.parseInt(String.valueOf(teamId)));
});
addMemberButtonRemove.setOnClickListener(v -> {
Context context = v.getContext();
AlertDialogs.removeMemberDialog(context, userNameMain.getText().toString(),
AlertDialogs.removeMemberDialog(context, userInfo.getLogin(),
context.getResources().getString(R.string.removeTeamMemberTitle),
context.getResources().getString(R.string.removeTeamMemberMessage),
context.getResources().getString(R.string.removeButton),
context.getResources().getString(R.string.cancelButton), Integer.parseInt(teamId_.getText().toString()));
context.getResources().getString(R.string.cancelButton), Integer.parseInt(String.valueOf(teamId)));
});
userAvatar.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userInfo.getLogin());
context.startActivity(intent);
});
userAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
return true;
});
}
}
@ -98,39 +101,36 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter<UserSea
@Override
public void onBindViewHolder(@NonNull final UserSearchForTeamMemberAdapter.UserSearchViewHolder holder, int position) {
final UserInfo currentItem = usersSearchList.get(position);
holder.userNameMain.setText(currentItem.getLogin());
holder.teamId_.setText(String.valueOf(teamId));
UserInfo currentItem = usersSearchList.get(position);
holder.userInfo = currentItem;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
if (!currentItem.getFullname().equals("")) {
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
}
else {
holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
holder.userFullName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
}
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
if (!currentItem.getAvatar().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
if(getItemCount() > 0) {
TinyDB tinyDb = TinyDB.getInstance(mCtx);
TinyDB tinyDb = TinyDB.getInstance(context);
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<UserInfo> call = RetrofitClient
.getApiInterface(mCtx)
.checkTeamMember(Authorization.get(mCtx), teamId, currentItem.getLogin());
.getApiInterface(context)
.checkTeamMember(Authorization.get(context), teamId, currentItem.getLogin());
call.enqueue(new Callback<UserInfo>() {
@ -167,8 +167,7 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter<UserSea
@Override
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Toasty.error(mCtx, mCtx.getResources().getString(R.string.genericServerResponseError));
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
}
});

View File

@ -0,0 +1,166 @@
package org.mian.gitnex.adapters.profile;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import java.util.List;
/**
* Author M M Arif
*/
public class FollowersAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final int TYPE_LOAD = 0;
private List<UserInfo> usersList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public FollowersAdapter(Context ctx, List<UserInfo> usersListMain) {
this.context = ctx;
this.usersList = usersListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new UsersHolder(inflater.inflate(R.layout.list_profile_followers_following, parent, false));
}
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((UsersHolder) holder).bindData(usersList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(usersList.get(position).getUsername() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return usersList.size();
}
class UsersHolder extends RecyclerView.ViewHolder {
private UserInfo userInfo;
private final ImageView userAvatar;
private final TextView userFullName;
private final TextView userName;
UsersHolder(View itemView) {
super(itemView);
Context context = itemView.getContext();
userAvatar = itemView.findViewById(R.id.userAvatar);
userFullName = itemView.findViewById(R.id.userFullName);
userName = itemView.findViewById(R.id.userName);
itemView.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userInfo.getLogin());
context.startActivity(intent);
});
itemView.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
return true;
});
}
@SuppressLint("SetTextI18n")
void bindData(UserInfo userInfo) {
this.userInfo = userInfo;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
//Locale locale = context.getResources().getConfiguration().locale;
if(!userInfo.getFullname().equals("")) {
userFullName.setText(Html.fromHtml(userInfo.getFullname()));
userName.setText(context.getResources().getString(R.string.usernameWithAt, userInfo.getUsername()));
}
else {
userFullName.setText(userInfo.getUsername());
userName.setVisibility(View.GONE);
}
PicassoService.getInstance(context)
.get()
.load(userInfo.getAvatar())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(userAvatar);
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<UserInfo> list) {
usersList = list;
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,166 @@
package org.mian.gitnex.adapters.profile;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import java.util.List;
/**
* Author M M Arif
*/
public class FollowingAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final int TYPE_LOAD = 0;
private List<UserInfo> usersList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public FollowingAdapter(Context ctx, List<UserInfo> usersListMain) {
this.context = ctx;
this.usersList = usersListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new UsersHolder(inflater.inflate(R.layout.list_profile_followers_following, parent, false));
}
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((UsersHolder) holder).bindData(usersList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(usersList.get(position).getUsername() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return usersList.size();
}
class UsersHolder extends RecyclerView.ViewHolder {
private UserInfo userInfo;
private final ImageView userAvatar;
private final TextView userFullName;
private final TextView userName;
UsersHolder(View itemView) {
super(itemView);
Context context = itemView.getContext();
userAvatar = itemView.findViewById(R.id.userAvatar);
userFullName = itemView.findViewById(R.id.userFullName);
userName = itemView.findViewById(R.id.userName);
itemView.setOnClickListener(loginId -> {
Intent intent = new Intent(context, ProfileActivity.class);
intent.putExtra("username", userInfo.getLogin());
context.startActivity(intent);
});
itemView.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
return true;
});
}
@SuppressLint("SetTextI18n")
void bindData(UserInfo userInfo) {
this.userInfo = userInfo;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
//Locale locale = context.getResources().getConfiguration().locale;
if(!userInfo.getFullname().equals("")) {
userFullName.setText(Html.fromHtml(userInfo.getFullname()));
userName.setText(context.getResources().getString(R.string.usernameWithAt, userInfo.getUsername()));
}
else {
userFullName.setText(userInfo.getUsername());
userName.setVisibility(View.GONE);
}
PicassoService
.getInstance(context)
.get()
.load(userInfo.getAvatar())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(imgRadius, 0))
.resize(120, 120)
.centerCrop()
.into(userAvatar);
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<UserInfo> list) {
usersList = list;
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,137 @@
package org.mian.gitnex.adapters.profile;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.UserOrganizations;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import java.util.List;
/**
* Author M M Arif
*/
public class OrganizationsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final int TYPE_LOAD = 0;
private List<UserOrganizations> organizationsList;
private RepositoriesAdapter.OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public OrganizationsAdapter(Context ctx, List<UserOrganizations> organizationsListMain) {
this.context = ctx;
this.organizationsList = organizationsListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new OrganizationsHolder(inflater.inflate(R.layout.list_organizations, parent, false));
}
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((OrganizationsHolder) holder).bindData(organizationsList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(organizationsList.get(position).getUsername() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return organizationsList.size();
}
class OrganizationsHolder extends RecyclerView.ViewHolder {
private UserOrganizations userOrganizations;
private final ImageView image;
private final TextView orgName;
private final TextView orgDescription;
OrganizationsHolder(View itemView) {
super(itemView);
orgName = itemView.findViewById(R.id.orgName);
orgDescription = itemView.findViewById(R.id.orgDescription);
image = itemView.findViewById(R.id.imageAvatar);
}
@SuppressLint("SetTextI18n")
void bindData(UserOrganizations userOrganizations) {
this.userOrganizations = userOrganizations;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
orgName.setText(userOrganizations.getUsername());
PicassoService.getInstance(context).get().load(userOrganizations.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(image);
if (!userOrganizations.getDescription().equals("")) {
orgDescription.setText(userOrganizations.getDescription());
}
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(RepositoriesAdapter.OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<UserOrganizations> list) {
organizationsList = list;
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,196 @@
package org.mian.gitnex.adapters.profile;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
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.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.R;
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 java.util.List;
import java.util.Locale;
/**
* Author M M Arif
*/
public class RepositoriesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final int TYPE_LOAD = 0;
private List<UserRepositories> reposList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public RepositoriesAdapter(Context ctx, List<UserRepositories> reposListMain) {
this.context = ctx;
this.reposList = reposListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new RepositoriesAdapter.RepositoriesHolder(inflater.inflate(R.layout.list_repositories, parent, false));
}
else {
return new RepositoriesAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((RepositoriesAdapter.RepositoriesHolder) holder).bindData(reposList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(reposList.get(position).getFullName() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return reposList.size();
}
class RepositoriesHolder extends RecyclerView.ViewHolder {
private UserRepositories userRepositories;
private final ImageView avatar;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private final TextView repoStars;
private final TextView repoLastUpdated;
RepositoriesHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
avatar = itemView.findViewById(R.id.imageAvatar);
repoStars = itemView.findViewById(R.id.repoStars);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
}
@SuppressLint("SetTextI18n")
void bindData(UserRepositories userRepositories) {
this.userRepositories = userRepositories;
TinyDB tinyDb = TinyDB.getInstance(context);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
orgName.setText(userRepositories.getFullName().split("/")[0]);
repoName.setText(userRepositories.getFullName().split("/")[1]);
repoStars.setText(userRepositories.getStars_count());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(userRepositories.getName());
String firstCharacter = String.valueOf(userRepositories.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
if(userRepositories.getAvatar_url() != null) {
if(!userRepositories.getAvatar_url().equals("")) {
PicassoService
.getInstance(context).get().load(userRepositories.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(avatar);
}
else {
avatar.setImageDrawable(drawable);
}
}
else {
avatar.setImageDrawable(drawable);
}
if(userRepositories.getUpdated_at() != null) {
repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, TimeHelper.formatTime(userRepositories.getUpdated_at(), locale, timeFormat, context)));
if(timeFormat.equals("pretty")) {
repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(userRepositories.getUpdated_at()), context));
}
}
else {
repoLastUpdated.setVisibility(View.GONE);
}
if(!userRepositories.getDescription().equals("")) {
repoDescription.setText(userRepositories.getDescription());
}
else {
repoDescription.setText(context.getString(R.string.noDataDescription));
}
if(isRepoAdmin == null) {
isRepoAdmin = new CheckBox(context);
}
isRepoAdmin.setChecked(userRepositories.getPermissions().isAdmin());
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<UserRepositories> list) {
reposList = list;
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,197 @@
package org.mian.gitnex.adapters.profile;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
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.gitnex.tea4j.models.UserRepositories;
import org.mian.gitnex.R;
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 java.util.List;
import java.util.Locale;
/**
* Author M M Arif
*/
public class StarredRepositoriesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final int TYPE_LOAD = 0;
private List<UserRepositories> reposList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public StarredRepositoriesAdapter(Context ctx, List<UserRepositories> reposListMain) {
this.context = ctx;
this.reposList = reposListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new StarredRepositoriesAdapter.StarredRepositoriesHolder(inflater.inflate(R.layout.list_repositories, parent, false));
}
else {
return new StarredRepositoriesAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((StarredRepositoriesAdapter.StarredRepositoriesHolder) holder).bindData(reposList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(reposList.get(position).getFullName() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return reposList.size();
}
class StarredRepositoriesHolder extends RecyclerView.ViewHolder {
private UserRepositories userRepositories;
private final ImageView avatar;
private final TextView repoName;
private final TextView orgName;
private final TextView repoDescription;
private CheckBox isRepoAdmin;
private final TextView repoStars;
private final TextView repoLastUpdated;
StarredRepositoriesHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
orgName = itemView.findViewById(R.id.orgName);
repoDescription = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
avatar = itemView.findViewById(R.id.imageAvatar);
repoStars = itemView.findViewById(R.id.repoStars);
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
}
@SuppressLint("SetTextI18n")
void bindData(UserRepositories userRepositories) {
this.userRepositories = userRepositories;
TinyDB tinyDb = TinyDB.getInstance(context);
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat");
orgName.setText(userRepositories.getFullName().split("/")[0]);
repoName.setText(userRepositories.getFullName().split("/")[1]);
repoStars.setText(userRepositories.getStars_count());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(userRepositories.getName());
String firstCharacter = String.valueOf(userRepositories.getFullName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
if(userRepositories.getAvatar_url() != null) {
if(!userRepositories.getAvatar_url().equals("")) {
PicassoService
.getInstance(context).get().load(userRepositories.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(avatar);
}
else {
avatar.setImageDrawable(drawable);
}
}
else {
avatar.setImageDrawable(drawable);
}
if(userRepositories.getUpdated_at() != null) {
repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, TimeHelper
.formatTime(userRepositories.getUpdated_at(), locale, timeFormat, context)));
if(timeFormat.equals("pretty")) {
repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(userRepositories.getUpdated_at()), context));
}
}
else {
repoLastUpdated.setVisibility(View.GONE);
}
if(!userRepositories.getDescription().equals("")) {
repoDescription.setText(userRepositories.getDescription());
}
else {
repoDescription.setText(context.getString(R.string.noDataDescription));
}
if(isRepoAdmin == null) {
isRepoAdmin = new CheckBox(context);
}
isRepoAdmin.setChecked(userRepositories.getPermissions().isAdmin());
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<UserRepositories> list) {
reposList = list;
notifyDataSetChanged();
}
}

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.core;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import androidx.core.content.res.ResourcesCompat;
import org.acra.ACRA;
import org.acra.BuildConfig;
import org.acra.ReportField;
@ -34,7 +35,6 @@ import org.mian.gitnex.notifications.Notifications;
public class MainApplication extends Application {
private Context appCtx;
private TinyDB tinyDB;
@Override
@ -42,9 +42,11 @@ public class MainApplication extends Application {
super.onCreate();
appCtx = getApplicationContext();
Context appCtx = getApplicationContext();
tinyDB = TinyDB.getInstance(appCtx);
tinyDB.putBoolean("biometricLifeCycle", false);
setDefaults();
switch(tinyDB.getInt("customFontId", -1)) {
@ -71,67 +73,101 @@ public class MainApplication extends Application {
}
Notifications.createChannels(appCtx);
}
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
tinyDB = TinyDB.getInstance(context);
if(tinyDB.getBoolean("crashReportingEnabled")) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);
ACRABuilder.setBuildConfigClass(BuildConfig.class).setReportFormat(StringFormat.KEY_VALUE_LIST);
ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class).setReportAsFile(true).setMailTo(getResources().getString(R.string.appEmail)).setSubject(getResources().getString(R.string.crashReportEmailSubject, AppUtil.getAppBuildNo(getApplicationContext()))).setEnabled(true);
ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class).setReportAsFile(true).setMailTo(getResources().getString(R.string.appEmail)).setSubject(getResources().getString(R.string.crashReportEmailSubject, AppUtil
.getAppBuildNo(context))).setEnabled(true);
ACRABuilder.getPluginConfigurationBuilder(LimiterConfigurationBuilder.class).setEnabled(true);
ACRA.init(this, ACRABuilder);
}
Notifications.createChannels(appCtx);
Notifications.startWorker(appCtx);
}
private void setDefaults() {
// enabling counter badges by default
if(tinyDB.getString("enableCounterBadgesInit").isEmpty()) {
tinyDB.putBoolean("enableCounterBadges", true);
tinyDB.putString("enableCounterBadgesInit", "yes");
}
// enable crash reports by default
if(tinyDB.getString("crashReportingEnabledInit").isEmpty()) {
tinyDB.putBoolean("crashReportingEnabled", true);
tinyDB.putString("crashReportingEnabledInit", "yes");
}
// default cache setter
if(tinyDB.getString("cacheSizeStr").isEmpty()) {
tinyDB.putString("cacheSizeStr", getResources().getString(R.string.cacheSizeDataSelectionSelectedText));
}
if(tinyDB.getString("cacheSizeImagesStr").isEmpty()) {
tinyDB.putString("cacheSizeImagesStr", getResources().getString(R.string.cacheSizeImagesSelectionSelectedText));
}
// enable comment drafts by default
if(tinyDB.getString("draftsCommentsDeletionEnabledInit").isEmpty()) {
tinyDB.putBoolean("draftsCommentsDeletionEnabled", true);
tinyDB.putString("draftsCommentsDeletionEnabledInit", "yes");
}
// setting default polling delay
if(tinyDB.getInt("pollingDelayMinutes", 0) <= 0) {
tinyDB.putInt("pollingDelayMinutes", Constants.defaultPollingDelay);
}
// disable biometric by default
if(tinyDB.getString("biometricStatusInit").isEmpty()) {
tinyDB.putBoolean("biometricStatus", false);
tinyDB.putString("biometricStatusInit", "yes");
}
// set default date format
if(tinyDB.getString("dateFormat").isEmpty()) {
tinyDB.putString("dateFormat", "pretty");
}
if(tinyDB.getString("codeBlockStr").isEmpty()) {
tinyDB.putInt("codeBlockColor", ResourcesCompat.getColor(getResources(), R.color.colorLightGreen, null));
tinyDB.putInt("codeBlockBackground", ResourcesCompat.getColor(getResources(), R.color.black, null));
}
if(tinyDB.getString("enableCounterIssueBadgeInit").isEmpty()) {
tinyDB.putBoolean("enableCounterIssueBadge", true);
}
if(tinyDB.getString("homeScreenStr").isEmpty()) {
tinyDB.putString("homeScreenStr", "yes");
tinyDB.putInt("homeScreenId", 0);
}
if(tinyDB.getString("localeStr").isEmpty()) {
tinyDB.putString("localeStr", getString(R.string.settingsLanguageSystem));
tinyDB.putInt("langId", 0);
}
if(tinyDB.getInt("darkThemeTimeHour", 100) == 100) {
tinyDB.putInt("lightThemeTimeHour", 6);
tinyDB.putInt("lightThemeTimeMinute", 0);
tinyDB.putInt("darkThemeTimeHour", 18);
tinyDB.putInt("darkThemeTimeMinute", 0);
}
if(tinyDB.getString("timeStr").isEmpty()) {
tinyDB.putString("timeStr", getString(R.string.settingsDateTimeHeaderDefault));
}
}
}

View File

@ -0,0 +1,57 @@
package org.mian.gitnex.database.api;
import android.content.Context;
import androidx.annotation.NonNull;
import org.mian.gitnex.database.db.GitnexDatabase;
import org.mian.gitnex.helpers.Constants;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author opyale
*/
public abstract class BaseApi {
private static final Map<Class<? extends BaseApi>, Object> instances = new HashMap<>();
protected static final ExecutorService executorService = Executors.newCachedThreadPool();
protected final GitnexDatabase gitnexDatabase;
protected BaseApi(Context context) {
gitnexDatabase = GitnexDatabase.getDatabaseInstance(context);
}
public static <T extends BaseApi> T getInstance(@NonNull Context context, @NonNull Class<T> clazz) {
try {
if(!instances.containsKey(clazz)) {
synchronized(BaseApi.class) {
if(!instances.containsKey(clazz)) {
T instance = clazz
.getDeclaredConstructor(Context.class)
.newInstance(context);
instances.put(clazz, instance);
return instance;
}
}
}
return (T) instances.get(clazz);
} catch(NoSuchMethodException | IllegalAccessException |
InvocationTargetException | InstantiationException ignored) {}
return null;
}
}

View File

@ -1,30 +1,23 @@
package org.mian.gitnex.database.api;
import android.content.Context;
import android.util.Log;
import androidx.lifecycle.LiveData;
import org.mian.gitnex.database.dao.DraftsDao;
import org.mian.gitnex.database.db.GitnexDatabase;
import org.mian.gitnex.database.models.Draft;
import org.mian.gitnex.database.models.DraftWithRepository;
import org.mian.gitnex.helpers.Constants;
import java.util.List;
/**
* Author M M Arif
*/
public class DraftsApi {
public class DraftsApi extends BaseApi {
private static DraftsDao draftsDao;
private static long draftId;
private static Integer checkDraftFlag;
private final DraftsDao draftsDao;
public DraftsApi(Context context) {
GitnexDatabase db;
db = GitnexDatabase.getDatabaseInstance(context);
draftsDao = db.draftsDao();
DraftsApi(Context context) {
super(context);
draftsDao = gitnexDatabase.draftsDao();
}
public long insertDraft(int repositoryId, int draftAccountId, int issueId, String draftText, String draftType, String commentId, String issueType) {
@ -41,87 +34,44 @@ public class DraftsApi {
return insertDraftAsyncTask(draft);
}
private static long insertDraftAsyncTask(final Draft draft) {
try {
Thread thread = new Thread(() -> draftId = draftsDao.insertDraft(draft));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.draftsApi, e.toString());
}
return draftId;
private long insertDraftAsyncTask(final Draft draft) {
return draftsDao.insertDraft(draft);
}
public long getDraftIdAsync(int issueId, int draftRepositoryId) {
try {
Thread thread = new Thread(() -> draftId = draftsDao.getDraftId(issueId, draftRepositoryId));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.draftsApi, e.toString());
}
return draftId;
return draftsDao.getDraftId(issueId, draftRepositoryId);
}
public Integer checkDraft(int issueId, int draftRepositoryId, String commentId) {
try {
Thread thread = new Thread(() -> checkDraftFlag = draftsDao.checkDraftDao(issueId, draftRepositoryId, commentId));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.draftsApi, e.toString());
}
return checkDraftFlag;
return draftsDao.checkDraftDao(issueId, draftRepositoryId, commentId);
}
public LiveData<List<DraftWithRepository>> getDrafts(int accountId) {
return draftsDao.fetchAllDrafts(accountId);
}
public LiveData<Draft> getDraftByIssueId(int issueId) {
return draftsDao.fetchDraftByIssueId(issueId);
}
public void deleteSingleDraft(final int draftId) {
final LiveData<Draft> draft = draftsDao.fetchDraftById(draftId);
if(draft != null) {
new Thread(() -> draftsDao.deleteByDraftId(draftId)).start();
executorService.execute(() -> draftsDao.deleteByDraftId(draftId));
}
}
public static void deleteAllDrafts(final int accountId) {
new Thread(() -> draftsDao.deleteAllDrafts(accountId)).start();
public void deleteAllDrafts(final int accountId) {
executorService.execute(() -> draftsDao.deleteAllDrafts(accountId));
}
public static void updateDraft(final String draftText, final int draftId, final String commentId) {
new Thread(() -> draftsDao.updateDraft(draftText, draftId, commentId)).start();
public void updateDraft(final String draftText, final int draftId, final String commentId) {
executorService.execute(() -> draftsDao.updateDraft(draftText, draftId, commentId));
}
public static void updateDraftByIssueIdAsyncTask(final String draftText, final int issueId, final int draftRepositoryId, final String commentId) {
new Thread(() -> draftsDao.updateDraftByIssueId(draftText, issueId, draftRepositoryId, commentId)).start();
public void updateDraftByIssueIdAsyncTask(final String draftText, final int issueId, final int draftRepositoryId, final String commentId) {
executorService.execute(() -> draftsDao.updateDraftByIssueId(draftText, issueId, draftRepositoryId, commentId));
}
}

View File

@ -1,30 +1,22 @@
package org.mian.gitnex.database.api;
import android.content.Context;
import android.util.Log;
import androidx.lifecycle.LiveData;
import org.mian.gitnex.database.dao.RepositoriesDao;
import org.mian.gitnex.database.db.GitnexDatabase;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.Constants;
import java.util.List;
/**
* Author M M Arif
*/
public class RepositoriesApi {
public class RepositoriesApi extends BaseApi {
private static RepositoriesDao repositoriesDao;
private static long repositoryId;
private static Repository repository;
private static Integer checkRepository;
private final RepositoriesDao repositoriesDao;
public RepositoriesApi(Context context) {
GitnexDatabase db;
db = GitnexDatabase.getDatabaseInstance(context);
repositoriesDao = db.repositoriesDao();
RepositoriesApi(Context context) {
super(context);
repositoriesDao = gitnexDatabase.repositoriesDao();
}
public long insertRepository(int repoAccountId, String repositoryOwner, String repositoryName) {
@ -38,108 +30,43 @@ public class RepositoriesApi {
}
public long insertRepositoryAsyncTask(Repository repository) {
try {
Thread thread = new Thread(() -> repositoryId = repositoriesDao.newRepository(repository));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.repositoriesApi, e.toString());
}
return repositoryId;
return repositoriesDao.newRepository(repository);
}
public Repository getRepository(int repoAccountId, String repositoryOwner, String repositoryName) {
try {
Thread thread = new Thread(() -> repository = repositoriesDao.getSingleRepositoryDao(repoAccountId, repositoryOwner, repositoryName));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.repositoriesApi, e.toString());
}
return repository;
return repositoriesDao.getSingleRepositoryDao(repoAccountId, repositoryOwner, repositoryName);
}
public LiveData<List<Repository>> getAllRepositories() {
return repositoriesDao.fetchAllRepositories();
}
public LiveData<List<Repository>> getAllRepositoriesByAccount(int repoAccountId) {
return repositoriesDao.getAllRepositoriesByAccountDao(repoAccountId);
}
public Integer checkRepository(int repoAccountId, String repositoryOwner, String repositoryName) {
try {
Thread thread = new Thread(() -> checkRepository = repositoriesDao.checkRepositoryDao(repoAccountId, repositoryOwner, repositoryName));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.repositoriesApi, e.toString());
}
return checkRepository;
return repositoriesDao.checkRepositoryDao(repoAccountId, repositoryOwner, repositoryName);
}
public Repository fetchRepositoryById(int repositoryId) {
try {
Thread thread = new Thread(() -> repository = repositoriesDao.fetchRepositoryByIdDao(repositoryId));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.repositoriesApi, e.toString());
}
return repository;
return repositoriesDao.fetchRepositoryByIdDao(repositoryId);
}
public Repository fetchRepositoryByAccountIdByRepositoryId(int repositoryId, int repoAccountId) {
try {
Thread thread = new Thread(() -> repository = repositoriesDao.fetchRepositoryByAccountIdByRepositoryIdDao(repositoryId, repoAccountId));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.repositoriesApi, e.toString());
}
return repository;
return repositoriesDao.fetchRepositoryByAccountIdByRepositoryIdDao(repositoryId, repoAccountId);
}
public static void updateRepositoryOwnerAndName(String repositoryOwner, String repositoryName, int repositoryId) {
new Thread(() -> repositoriesDao.updateRepositoryOwnerAndName(repositoryOwner, repositoryName, repositoryId)).start();
public void updateRepositoryOwnerAndName(String repositoryOwner, String repositoryName, int repositoryId) {
executorService.execute(() -> repositoriesDao.updateRepositoryOwnerAndName(repositoryOwner, repositoryName, repositoryId));
}
public static void deleteRepositoriesByAccount(final int repoAccountId) {
new Thread(() -> repositoriesDao.deleteRepositoriesByAccount(repoAccountId)).start();
public void deleteRepositoriesByAccount(final int repoAccountId) {
executorService.execute(() -> repositoriesDao.deleteRepositoriesByAccount(repoAccountId));
}
public static void deleteRepository(final int repositoryId) {
new Thread(() -> repositoriesDao.deleteRepository(repositoryId)).start();
public void deleteRepository(final int repositoryId) {
executorService.execute(() -> repositoriesDao.deleteRepository(repositoryId));
}
}

View File

@ -1,34 +1,25 @@
package org.mian.gitnex.database.api;
import android.content.Context;
import android.util.Log;
import androidx.lifecycle.LiveData;
import org.mian.gitnex.database.dao.UserAccountsDao;
import org.mian.gitnex.database.db.GitnexDatabase;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.Constants;
import java.util.List;
/**
* Author M M Arif
*/
public class UserAccountsApi {
public class UserAccountsApi extends BaseApi {
private static UserAccountsDao userAccountsDao;
private static UserAccount userAccount;
private static List<UserAccount> userAccounts;
private static Integer checkAccount;
private static long accountId;
private final UserAccountsDao userAccountsDao;
public UserAccountsApi(Context context) {
GitnexDatabase db;
db = GitnexDatabase.getDatabaseInstance(context);
userAccountsDao = db.userAccountsDao();
UserAccountsApi(Context context) {
super(context);
userAccountsDao = gitnexDatabase.userAccountsDao();
}
public long insertNewAccount(String accountName, String instanceUrl, String userName, String token, String serverVersion) {
public long createNewAccount(String accountName, String instanceUrl, String userName, String token, String serverVersion) {
UserAccount userAccount = new UserAccount();
userAccount.setAccountName(accountName);
@ -37,96 +28,48 @@ public class UserAccountsApi {
userAccount.setToken(token);
userAccount.setServerVersion(serverVersion);
return insertNewAccountAsync(userAccount);
return userAccountsDao.createAccount(userAccount);
}
private static long insertNewAccountAsync(final UserAccount userAccount) {
try {
Thread thread = new Thread(() -> accountId = userAccountsDao.newAccount(userAccount));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.userAccountsApi, e.toString());
}
return accountId;
}
public static void updateServerVersion(final String serverVersion, final int accountId) {
new Thread(() -> userAccountsDao.updateServerVersion(serverVersion, accountId)).start();
public void updateServerVersion(final String serverVersion, final int accountId) {
executorService.execute(() -> userAccountsDao.updateServerVersion(serverVersion, accountId));
}
public void updateToken(final int accountId, final String token) {
new Thread(() -> userAccountsDao.updateAccountToken(accountId, token)).start();
executorService.execute(() -> userAccountsDao.updateAccountToken(accountId, token));
}
public void updateTokenByAccountName(final String accountName, final String token) {
new Thread(() -> userAccountsDao.updateAccountTokenByAccountName(accountName, token)).start();
executorService.execute(() -> userAccountsDao.updateAccountTokenByAccountName(accountName, token));
}
public UserAccount getAccountData(String accountName) {
try {
Thread thread = new Thread(() -> userAccount = userAccountsDao.fetchRowByAccount_(accountName));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.userAccountsApi, e.toString());
}
return userAccount;
public UserAccount getAccountByName(String accountName) {
return userAccountsDao.getAccountByName(accountName);
}
public Integer getCount(String accountName) {
public UserAccount getAccountById(int accountId) {
return userAccountsDao.getAccountById(accountId);
}
try {
public Integer getCount() {
return userAccountsDao.getCount();
}
Thread thread = new Thread(() -> checkAccount = userAccountsDao.getCount(accountName));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.userAccountsApi, e.toString());
}
return checkAccount;
public Boolean userAccountExists(String accountName) {
return userAccountsDao.userAccountExists(accountName);
}
public LiveData<List<UserAccount>> getAllAccounts() {
return userAccountsDao.fetchAllAccounts();
return userAccountsDao.getAllAccounts();
}
public List<UserAccount> usersAccounts() {
try {
Thread thread = new Thread(() -> userAccounts = userAccountsDao.userAccounts());
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(Constants.userAccountsApi, e.toString());
}
return userAccounts;
return userAccountsDao.userAccounts();
}
public void deleteAccount(final int accountId) {
new Thread(() -> userAccountsDao.deleteAccount(accountId)).start();
executorService.execute(() -> userAccountsDao.deleteAccount(accountId));
}
}

View File

@ -15,22 +15,25 @@ import java.util.List;
public interface UserAccountsDao {
@Insert
long newAccount(UserAccount userAccounts);
long createAccount(UserAccount userAccounts);
@Query("SELECT * FROM UserAccounts ORDER BY accountId ASC")
LiveData<List<UserAccount>> fetchAllAccounts();
LiveData<List<UserAccount>> getAllAccounts();
@Query("SELECT * FROM UserAccounts ORDER BY accountId ASC")
List<UserAccount> userAccounts();
@Query("SELECT COUNT(accountId) FROM UserAccounts WHERE accountName = :accountName")
Integer getCount(String accountName);
@Query("SELECT COUNT(accountId) FROM UserAccounts")
Integer getCount();
@Query("SELECT * FROM UserAccounts WHERE accountName = :accountName")
UserAccount fetchRowByAccount_(String accountName);
@Query("SELECT COUNT(accountId) FROM UserAccounts WHERE accountName = :accountName LIMIT 1")
Boolean userAccountExists(String accountName);
@Query("SELECT * FROM UserAccounts WHERE accountId = :accountId")
UserAccount fetchRowByAccountId(int accountId);
@Query("SELECT * FROM UserAccounts WHERE accountName = :accountName LIMIT 1")
UserAccount getAccountByName(String accountName);
@Query("SELECT * FROM UserAccounts WHERE accountId = :accountId LIMIT 1")
UserAccount getAccountById(int accountId);
@Query("UPDATE UserAccounts SET serverVersion = :serverVersion WHERE accountId = :accountId")
void updateServerVersion(String serverVersion, int accountId);

View File

@ -22,32 +22,16 @@ import org.mian.gitnex.database.models.UserAccount;
version = 3, exportSchema = false)
public abstract class GitnexDatabase extends RoomDatabase {
private static final String DB_NAME = "gitnex";
private static GitnexDatabase gitnexDatabase;
public static GitnexDatabase getDatabaseInstance(Context context) {
if (gitnexDatabase == null) {
String DB_NAME = "gitnex";
gitnexDatabase = Room.databaseBuilder(context, GitnexDatabase.class, DB_NAME)
//.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build();
}
return gitnexDatabase;
}
public abstract DraftsDao draftsDao();
public abstract RepositoriesDao repositoriesDao();
public abstract UserAccountsDao userAccountsDao();
private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
//database.execSQL("DROP TABLE Drafts");
database.execSQL("ALTER TABLE 'Drafts' ADD COLUMN 'commentId' TEXT");
}
@ -56,8 +40,27 @@ public abstract class GitnexDatabase extends RoomDatabase {
private static final Migration MIGRATION_2_3 = new Migration(2, 3) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE 'Drafts' ADD COLUMN 'issueType' TEXT");
}
};
public static GitnexDatabase getDatabaseInstance(Context context) {
if (gitnexDatabase == null) {
synchronized(GitnexDatabase.class) {
if(gitnexDatabase == null) {
gitnexDatabase = Room.databaseBuilder(context, GitnexDatabase.class, DB_NAME)
// .fallbackToDestructiveMigration()
.allowMainThreadQueries()
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build();
}
}
}
return gitnexDatabase;
}
}

View File

@ -1,72 +0,0 @@
package org.mian.gitnex.fragments;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.databinding.FragmentAboutBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
/**
* Author M M Arif
*/
public class AboutFragment extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FragmentAboutBinding viewBinding = FragmentAboutBinding.inflate(inflater, container, false);
TinyDB tinyDb = TinyDB.getInstance(getContext());
viewBinding.appVersion.setText(AppUtil.getAppVersion(requireContext()));
viewBinding.userServerVersion.setText(tinyDb.getString("giteaVersion"));
viewBinding.appBuild.setText(String.valueOf(AppUtil.getAppBuildNo(requireContext())));
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.pageTitleAbout));
viewBinding.donationLinkPatreon.setOnClickListener(v12 -> {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse(getResources().getString(R.string.supportLinkPatreon)));
startActivity(intent);
});
viewBinding.translateLink.setOnClickListener(v13 -> {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse(getResources().getString(R.string.crowdInLink)));
startActivity(intent);
});
viewBinding.appWebsite.setOnClickListener(v14 -> {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse(getResources().getString(R.string.appWebsiteLink)));
startActivity(intent);
});
if(AppUtil.isPro(requireContext())) {
viewBinding.supportHeader.setVisibility(View.GONE);
viewBinding.dividerSupport.setVisibility(View.GONE);
viewBinding.donationLinkPatreon.setVisibility(View.GONE);
}
return viewBinding.getRoot();
}
}

View File

@ -40,6 +40,16 @@ public class AdministrationFragment extends Fragment {
fragmentAdministrationBinding.adminCron.setOnClickListener(v1 -> startActivity(new Intent(getContext(), AdminCronTasksActivity.class)));
String action = requireActivity().getIntent().getStringExtra("giteaAdminAction");
if(action != null) {
if(action.equals("users")) {
startActivity(new Intent(getContext(), AdminGetUsersActivity.class));
}
else if(action.equals("monitor")) {
startActivity(new Intent(getContext(), AdminCronTasksActivity.class));
}
}
return fragmentAdministrationBinding.getRoot();
}

View File

@ -8,14 +8,14 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.activities.ProfileEmailActivity;
import org.mian.gitnex.activities.MyProfileEmailActivity;
import org.mian.gitnex.databinding.BottomSheetProfileBinding;
/**
* Author M M Arif
*/
public class BottomSheetProfileFragment extends BottomSheetDialogFragment {
public class BottomSheetMyProfileFragment extends BottomSheetDialogFragment {
@Nullable
@Override
@ -25,7 +25,7 @@ public class BottomSheetProfileFragment extends BottomSheetDialogFragment {
bottomSheetProfileBinding.addNewEmailAddress.setOnClickListener(v1 -> {
startActivity(new Intent(getContext(), ProfileEmailActivity.class));
startActivity(new Intent(getContext(), MyProfileEmailActivity.class));
dismiss();
});

View File

@ -19,10 +19,12 @@ import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.ActionResult;
import org.mian.gitnex.actions.IssueActions;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.databinding.BottomSheetReplyLayoutBinding;
import org.mian.gitnex.helpers.Constants;
@ -56,12 +58,11 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
super.onAttach(context);
tinyDB = TinyDB.getInstance(context);
draftsApi = new DraftsApi(context);
draftsApi = BaseApi.getInstance(context, DraftsApi.class);
repositoryId = (int) tinyDB.getLong("repositoryId", 0);
currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
issueNumber = Integer.parseInt(tinyDB.getString("issueNumber"));
}
@SuppressLint("ClickableViewAccessibility")
@ -87,7 +88,6 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
send.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_save));
mode = Mode.EDIT;
}
if(arguments.getString("draftId") != null) {
@ -97,7 +97,7 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
if(!tinyDB.getString("issueTitle").isEmpty()) {
toolbarTitle.setText(tinyDB.getString("issueTitle"));
toolbarTitle.setText(EmojiParser.parseToUnicode(tinyDB.getString("issueTitle")));
}
else if(arguments.getString("draftTitle") != null) {
@ -134,7 +134,6 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
}
return false;
});
comment.addTextChangedListener(new TextWatcher() {
@ -283,7 +282,7 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
}
else {
DraftsApi.updateDraft(text, (int) draftId, "TODO");
draftsApi.updateDraft(text, (int) draftId, "TODO");
}
draftsHint.setVisibility(View.VISIBLE);

View File

@ -13,17 +13,24 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.google.gson.JsonElement;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.IssueActions;
import org.mian.gitnex.actions.PullRequestActions;
import org.mian.gitnex.activities.EditIssueActivity;
import org.mian.gitnex.activities.FileDiffActivity;
import org.mian.gitnex.activities.MergePullRequestActivity;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.BottomSheetSingleIssueBinding;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.views.ReactionSpinner;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
@ -50,6 +57,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
TextView copyIssueUrl = bottomSheetSingleIssueBinding.copyIssueUrl;
TextView openFilesDiff = bottomSheetSingleIssueBinding.openFilesDiff;
TextView mergePullRequest = bottomSheetSingleIssueBinding.mergePullRequest;
TextView deletePullRequestBranch = bottomSheetSingleIssueBinding.deletePrHeadBranch;
TextView shareIssue = bottomSheetSingleIssueBinding.shareIssue;
TextView subscribeIssue = bottomSheetSingleIssueBinding.subscribeIssue;
TextView unsubscribeIssue = bottomSheetSingleIssueBinding.unsubscribeIssue;
@ -85,9 +93,11 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
if(tinyDB.getBoolean("prMerged") || tinyDB.getString("repoPrState").equals("closed")) {
mergePullRequest.setVisibility(View.GONE);
deletePullRequestBranch.setVisibility(View.VISIBLE);
}
else {
mergePullRequest.setVisibility(View.VISIBLE);
deletePullRequestBranch.setVisibility(View.GONE);
}
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.13.0")) {
@ -104,6 +114,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
else {
mergePullRequest.setVisibility(View.GONE);
deletePullRequestBranch.setVisibility(View.GONE);
}
mergePullRequest.setOnClickListener(v13 -> {
@ -112,6 +123,12 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
dismiss();
});
deletePullRequestBranch.setOnClickListener(v -> {
PullRequestActions.deleteHeadBranch(ctx, parts[0], parts[1], tinyDB.getString("prHeadBranch"), true);
dismiss();
});
openFilesDiff.setOnClickListener(v14 -> {
startActivity(new Intent(ctx, FileDiffActivity.class));

View File

@ -22,6 +22,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.adapters.DraftsAdapter;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.database.models.DraftWithRepository;
import org.mian.gitnex.databinding.FragmentDraftsBinding;
@ -59,7 +60,7 @@ public class DraftsFragment extends Fragment {
TinyDB tinyDb = TinyDB.getInstance(ctx);
draftsList_ = new ArrayList<>();
draftsApi = new DraftsApi(ctx);
draftsApi = BaseApi.getInstance(ctx, DraftsApi.class);
noData = fragmentDraftsBinding.noData;
mRecyclerView = fragmentDraftsBinding.recyclerView;
@ -123,7 +124,7 @@ public class DraftsFragment extends Fragment {
if(draftsList_.size() > 0) {
DraftsApi.deleteAllDrafts(accountId);
BaseApi.getInstance(ctx, DraftsApi.class).deleteAllDrafts(accountId);
draftsList_.clear();
adapter.notifyDataSetChanged();
Toasty.success(ctx, getResources().getString(R.string.draftsDeleteSuccess));

View File

@ -24,9 +24,6 @@ import org.mian.gitnex.helpers.TinyDB;
public class ExploreFragment extends Fragment {
private Context ctx;
private TinyDB tinyDB;
private int tabsCount;
public ViewPager mViewPager;
@ -36,8 +33,8 @@ public class ExploreFragment extends Fragment {
View view = inflater.inflate(R.layout.fragment_explore, container, false);
ctx = getContext();
tinyDB = TinyDB.getInstance(ctx);
Context ctx = getContext();
TinyDB tinyDB = TinyDB.getInstance(ctx);
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navExplore));
@ -87,6 +84,10 @@ public class ExploreFragment extends Fragment {
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
if(requireActivity().getIntent().getBooleanExtra("exploreOrgs", false)) {
mViewPager.setCurrentItem(2);
}
return view;
}
@ -111,7 +112,11 @@ public class ExploreFragment extends Fragment {
break;
case 1: // Issues
fragment = new SearchIssuesFragment();
fragment = new ExploreIssuesFragment();
break;
case 2: // Organizations
fragment = new ExplorePublicOrganizationsFragment();
break;
}

View File

@ -13,13 +13,12 @@ import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.gitnex.tea4j.models.Issues;
import org.mian.gitnex.adapters.SearchIssuesAdapter;
import org.mian.gitnex.adapters.ExploreIssuesAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.FragmentSearchIssuesBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.InfiniteScrollListener;
import org.mian.gitnex.helpers.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -31,30 +30,25 @@ import retrofit2.Response;
* Author M M Arif
*/
public class SearchIssuesFragment extends Fragment {
public class ExploreIssuesFragment extends Fragment {
private Context ctx;
private TinyDB tinyDb;
private FragmentSearchIssuesBinding viewBinding;
private SearchIssuesAdapter adapter;
private ExploreIssuesAdapter adapter;
private List<Issues> dataList;
Context ctx;
private int apiCallCurrentValue = 10;
private int pageCurrentIndex = 1;
private String type = "issues";
private String state = "open";
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewBinding = FragmentSearchIssuesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
ctx = getContext();
tinyDb = TinyDB.getInstance(getContext());
dataList = new ArrayList<>();
adapter = new SearchIssuesAdapter(dataList, ctx);
adapter = new ExploreIssuesAdapter(dataList, ctx);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx);
@ -65,11 +59,8 @@ public class SearchIssuesFragment extends Fragment {
viewBinding.recyclerViewSearchIssues.setAdapter(adapter);
viewBinding.searchKeyword.setOnEditorActionListener((v1, actionId, event) -> {
if(actionId == EditorInfo.IME_ACTION_SEND) {
if(!Objects.requireNonNull(viewBinding.searchKeyword.getText()).toString().equals("")) {
InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(viewBinding.searchKeyword.getWindowToken(), 0);
@ -79,27 +70,21 @@ public class SearchIssuesFragment extends Fragment {
loadData(false, viewBinding.searchKeyword.getText().toString());
}
}
return false;
});
viewBinding.recyclerViewSearchIssues.addOnScrollListener(new InfiniteScrollListener(pageCurrentIndex, linearLayoutManager) {
@Override
public void onScrolledToEnd(int firstVisibleItemPosition) {
pageCurrentIndex++;
loadData(true, Objects.requireNonNull(viewBinding.searchKeyword.getText()).toString());
}
});
viewBinding.pullToRefresh.setOnRefreshListener(() -> {
pageCurrentIndex = 1;
apiCallCurrentValue = 10;
loadData(false, Objects.requireNonNull(viewBinding.searchKeyword.getText()).toString());
});
loadData(false, "");
@ -117,69 +102,50 @@ public class SearchIssuesFragment extends Fragment {
}
if(pageCurrentIndex == 1 || !append) {
dataList.clear();
adapter.notifyDataSetChanged();
viewBinding.pullToRefresh.setRefreshing(false);
viewBinding.progressBar.setVisibility(View.VISIBLE);
}
else {
viewBinding.loadingMoreView.setVisibility(View.VISIBLE);
}
Call<List<Issues>> call = RetrofitClient.getApiInterface(getContext())
.queryIssues(Authorization.get(getContext()), searchKeyword, type, state, pageCurrentIndex);
.queryIssues(Authorization.get(getContext()), searchKeyword, "issues", "open", pageCurrentIndex);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.code() == 200) {
assert response.body() != null;
apiCallCurrentValue = response.body().size();
if(!append) {
dataList.clear();
}
dataList.addAll(response.body());
adapter.notifyDataSetChanged();
}
else {
dataList.clear();
adapter.notifyDataChanged();
viewBinding.noData.setVisibility(View.VISIBLE);
}
onCleanup();
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e("onFailure", Objects.requireNonNull(t.getMessage()));
onCleanup();
}
private void onCleanup() {
AppUtil.setMultiVisibility(View.GONE, viewBinding.loadingMoreView, viewBinding.progressBar);
if(dataList.isEmpty()) {
viewBinding.noData.setVisibility(View.VISIBLE);
}
}
});
}
}

View File

@ -0,0 +1,160 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.gitnex.tea4j.models.Organization;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.ExplorePublicOrganizationsAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.FragmentOrganizationsBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Version;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class ExplorePublicOrganizationsFragment extends Fragment {
private FragmentOrganizationsBinding fragmentPublicOrgBinding;
private List<Organization> organizationsList;
private ExplorePublicOrganizationsAdapter adapter;
private Context context;
private int pageSize;
private final String TAG = Constants.publicOrganizations;
private int resultLimit = Constants.resultLimitOldGiteaInstances;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
fragmentPublicOrgBinding = FragmentOrganizationsBinding.inflate(inflater, container, false);
context = getContext();
TinyDB tinyDb = TinyDB.getInstance(getContext());
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
// if gitea is 1.12 or higher use the new limit
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = Constants.resultLimitNewGiteaInstances;
}
fragmentPublicOrgBinding.addNewOrganization.setVisibility(View.GONE);
organizationsList = new ArrayList<>();
fragmentPublicOrgBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
fragmentPublicOrgBinding.pullToRefresh.setRefreshing(false);
loadInitial(instanceToken, resultLimit);
adapter.notifyDataChanged();
}, 200));
adapter = new ExplorePublicOrganizationsAdapter(getContext(), organizationsList);
adapter.setLoadMoreListener(() -> fragmentPublicOrgBinding.recyclerView.post(() -> {
if(organizationsList.size() == resultLimit || pageSize == resultLimit) {
int page = (organizationsList.size() + resultLimit) / resultLimit;
loadMore(Authorization.get(getContext()), page, resultLimit);
}
}));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(fragmentPublicOrgBinding.recyclerView.getContext(), DividerItemDecoration.VERTICAL);
fragmentPublicOrgBinding.recyclerView.setHasFixedSize(true);
fragmentPublicOrgBinding.recyclerView.addItemDecoration(dividerItemDecoration);
fragmentPublicOrgBinding.recyclerView.setLayoutManager(new LinearLayoutManager(context));
fragmentPublicOrgBinding.recyclerView.setAdapter(adapter);
loadInitial(Authorization.get(getContext()), resultLimit);
return fragmentPublicOrgBinding.getRoot();
}
private void loadInitial(String token, int resultLimit) {
Call<List<Organization>> call = RetrofitClient
.getApiInterface(context).getAllOrgs(token, Constants.publicOrganizationsPageInit, resultLimit);
call.enqueue(new Callback<List<Organization>>() {
@Override
public void onResponse(@NonNull Call<List<Organization>> call, @NonNull Response<List<Organization>> response) {
if(response.isSuccessful()) {
if(response.body() != null && response.body().size() > 0) {
organizationsList.clear();
organizationsList.addAll(response.body());
adapter.notifyDataChanged();
fragmentPublicOrgBinding.noDataOrg.setVisibility(View.GONE);
}
else {
organizationsList.clear();
adapter.notifyDataChanged();
fragmentPublicOrgBinding.noDataOrg.setVisibility(View.VISIBLE);
}
fragmentPublicOrgBinding.progressBar.setVisibility(View.GONE);
}
else if(response.code() == 404) {
fragmentPublicOrgBinding.noDataOrg.setVisibility(View.VISIBLE);
fragmentPublicOrgBinding.progressBar.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Organization>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadMore(String token, int page, int resultLimit) {
fragmentPublicOrgBinding.progressLoadMore.setVisibility(View.VISIBLE);
Call<List<Organization>> call = RetrofitClient.getApiInterface(context).getAllOrgs(token, page, resultLimit);
call.enqueue(new Callback<List<Organization>>() {
@Override
public void onResponse(@NonNull Call<List<Organization>> call, @NonNull Response<List<Organization>> response) {
if(response.isSuccessful()) {
List<Organization> result = response.body();
if(result != null) {
if(result.size() > 0) {
pageSize = result.size();
organizationsList.addAll(result);
}
else {
SnackBar.info(context, fragmentPublicOrgBinding.getRoot(), getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}
}
adapter.notifyDataChanged();
fragmentPublicOrgBinding.progressLoadMore.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Organization>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
}

View File

@ -261,54 +261,21 @@ public class ExploreRepositoriesFragment extends Fragment {
dialogFilterOptions.setContentView(view);
filterBinding.includeTopic.setOnClickListener(includeTopic -> {
if(filterBinding.includeTopic.isChecked()) {
tinyDb.putBoolean("exploreRepoIncludeTopic", true);
}
else {
tinyDb.putBoolean("exploreRepoIncludeTopic", false);
}
tinyDb.putBoolean("exploreRepoIncludeTopic", filterBinding.includeTopic.isChecked());
});
filterBinding.includeDesc.setOnClickListener(includeDesc -> {
if(filterBinding.includeDesc.isChecked()) {
tinyDb.putBoolean("exploreRepoIncludeDescription", true);
}
else {
tinyDb.putBoolean("exploreRepoIncludeDescription", false);
}
tinyDb.putBoolean("exploreRepoIncludeDescription", filterBinding.includeDesc.isChecked());
});
filterBinding.includeTemplate.setOnClickListener(includeTemplate -> {
if(filterBinding.includeTemplate.isChecked()) {
tinyDb.putBoolean("exploreRepoIncludeTemplate", true);
}
else {
tinyDb.putBoolean("exploreRepoIncludeTemplate", false);
}
tinyDb.putBoolean("exploreRepoIncludeTemplate", filterBinding.includeTemplate.isChecked());
});
filterBinding.onlyArchived.setOnClickListener(onlyArchived -> {
if(filterBinding.onlyArchived.isChecked()) {
tinyDb.putBoolean("exploreRepoOnlyArchived", true);
}
else {
tinyDb.putBoolean("exploreRepoOnlyArchived", false);
}
tinyDb.putBoolean("exploreRepoOnlyArchived", filterBinding.onlyArchived.isChecked());
});
filterBinding.includeTopic.setChecked(tinyDb.getBoolean("exploreRepoIncludeTopic"));
filterBinding.includeDesc.setChecked(tinyDb.getBoolean("exploreRepoIncludeDescription"));
filterBinding.includeTemplate.setChecked(tinyDb.getBoolean("exploreRepoIncludeTemplate"));

View File

@ -130,7 +130,17 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
});
fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref);
String dir = requireActivity().getIntent().getStringExtra("dir");
if(dir != null) {
fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, dir, ref);
for(String segment: dir.split("/")) {
binding.breadcrumbsView.addItem(new BreadcrumbItem(Collections.singletonList(segment)));
path.add(segment);
}
}
else {
fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref);
}
return binding.getRoot();
}

View File

@ -29,8 +29,8 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.FragmentIssuesBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import java.util.ArrayList;
import java.util.List;
@ -44,6 +44,7 @@ import retrofit2.Response;
public class IssuesFragment extends Fragment {
private FragmentIssuesBinding fragmentIssuesBinding;
private Menu menu;
private RecyclerView recyclerView;
private List<Issues> issuesList;
@ -51,18 +52,17 @@ public class IssuesFragment extends Fragment {
private Context context;
private int pageSize = Constants.issuesPageInit;
private ProgressBar mProgressBar;
private String TAG = Constants.tagIssuesList;
private final String TAG = Constants.tagIssuesList;
private TextView noDataIssues;
private int resultLimit = Constants.resultLimitOldGiteaInstances;
private String requestType = Constants.issuesRequestType;
private final String requestType = Constants.issuesRequestType;
private ProgressBar progressLoadMore;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
FragmentIssuesBinding fragmentIssuesBinding = FragmentIssuesBinding.inflate(inflater, container, false);
fragmentIssuesBinding = FragmentIssuesBinding.inflate(inflater, container, false);
setHasOptionsMenu(true);
context = getContext();
@ -89,23 +89,17 @@ public class IssuesFragment extends Fragment {
noDataIssues = fragmentIssuesBinding.noDataIssues;
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
adapter.notifyDataChanged();
}, 200));
adapter = new IssuesAdapter(getContext(), issuesList);
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
if(issuesList.size() == resultLimit || pageSize == resultLimit) {
int page = (issuesList.size() + resultLimit) / resultLimit;
loadMore(Authorization.get(getContext()), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
}
}));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
@ -129,12 +123,9 @@ public class IssuesFragment extends Fragment {
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
if(issuesList.size() == resultLimit || pageSize == resultLimit) {
int page = (issuesList.size() + resultLimit) / resultLimit;
loadMore(Authorization.get(getContext()), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
}
}));
tinyDb.putString("repoIssuesState", issueState);
@ -144,13 +135,11 @@ public class IssuesFragment extends Fragment {
loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, issueState);
recyclerView.setAdapter(adapter);
});
loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
return fragmentIssuesBinding.getRoot();
}
@Override
@ -165,12 +154,9 @@ public class IssuesFragment extends Fragment {
final String repoName = parts[1];
if(tinyDb.getBoolean("resumeIssues")) {
loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
tinyDb.putBoolean("resumeIssues", false);
}
}
private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String requestType, String issueState) {
@ -178,52 +164,38 @@ public class IssuesFragment extends Fragment {
Call<List<Issues>> call = RetrofitClient.getApiInterface(context).getIssues(token, repoOwner, repoName, 1, resultLimit, requestType, issueState);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.code() == 200) {
assert response.body() != null;
if(response.body().size() > 0) {
issuesList.clear();
issuesList.addAll(response.body());
adapter.notifyDataChanged();
noDataIssues.setVisibility(View.GONE);
}
else {
issuesList.clear();
adapter.notifyDataChanged();
noDataIssues.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
else if(response.code() == 404) {
noDataIssues.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadMore(String token, String repoOwner, String repoName, int page, int resultLimit, String requestType, String issueState) {
@ -236,44 +208,29 @@ public class IssuesFragment extends Fragment {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.code() == 200) {
List<Issues> result = response.body();
assert result != null;
if(result.size() > 0) {
pageSize = result.size();
issuesList.addAll(result);
}
else {
Toasty.warning(context, getString(R.string.noMoreData));
SnackBar.info(context, fragmentIssuesBinding.getRoot(), getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}
adapter.notifyDataChanged();
progressLoadMore.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
@ -302,20 +259,15 @@ public class IssuesFragment extends Fragment {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
return false;
}
});
}
private void filter(String text) {
@ -333,5 +285,4 @@ public class IssuesFragment extends Fragment {
adapter.updateList(arr);
}
}

View File

@ -48,6 +48,8 @@ public class MilestonesFragment extends Fragment {
private String TAG = Constants.tagMilestonesFragment;
private int resultLimit = Constants.resultLimitOldGiteaInstances;
private String milestoneId;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -63,6 +65,9 @@ public class MilestonesFragment extends Fragment {
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
milestoneId = requireActivity().getIntent().getStringExtra("milestoneId");
requireActivity().getIntent().removeExtra("milestoneId");
viewBinding.recyclerView.setHasFixedSize(true);
viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
@ -188,6 +193,10 @@ public class MilestonesFragment extends Fragment {
adapter.notifyDataChanged();
viewBinding.noDataMilestone.setVisibility(View.GONE);
if(milestoneId != null) {
viewBinding.recyclerView.scrollToPosition(getMilestoneIndex(Integer.parseInt(milestoneId), response.body()));
}
}
else {
@ -216,6 +225,15 @@ public class MilestonesFragment extends Fragment {
}
private static int getMilestoneIndex(int milestoneId, List<Milestones> milestones) {
for (Milestones milestone : milestones) {
if(milestone.getId() == milestoneId) {
return milestones.indexOf(milestone);
}
}
return -1;
}
private void loadMore(String token, String repoOwner, String repoName, int page, int resultLimit, String milestoneState) {
viewBinding.progressLoadMore.setVisibility(View.VISIBLE);

View File

@ -18,7 +18,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.gitnex.tea4j.models.Emails;
import org.mian.gitnex.adapters.ProfileEmailsAdapter;
import org.mian.gitnex.adapters.MyProfileEmailsAdapter;
import org.mian.gitnex.databinding.FragmentProfileEmailsBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.viewmodels.ProfileEmailsViewModel;
@ -28,10 +28,10 @@ import java.util.List;
* Author M M Arif
*/
public class ProfileEmailsFragment extends Fragment {
public class MyProfileEmailsFragment extends Fragment {
private ProgressBar mProgressBar;
private ProfileEmailsAdapter adapter;
private MyProfileEmailsAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noDataEmails;
private static String repoNameF = "param2";
@ -42,11 +42,11 @@ public class ProfileEmailsFragment extends Fragment {
private OnFragmentInteractionListener mListener;
public ProfileEmailsFragment() {
public MyProfileEmailsFragment() {
}
public static ProfileEmailsFragment newInstance(String param1, String param2) {
ProfileEmailsFragment fragment = new ProfileEmailsFragment();
public static MyProfileEmailsFragment newInstance(String param1, String param2) {
MyProfileEmailsFragment fragment = new MyProfileEmailsFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
@ -74,11 +74,10 @@ public class ProfileEmailsFragment extends Fragment {
noDataEmails = fragmentProfileEmailsBinding.noDataEmails;
mRecyclerView = fragmentProfileEmailsBinding.recyclerView;
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
mProgressBar = fragmentProfileEmailsBinding.progressBar;
@ -103,7 +102,7 @@ public class ProfileEmailsFragment extends Fragment {
profileEmailModel.getEmailsList(instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer<List<Emails>>() {
@Override
public void onChanged(@Nullable List<Emails> emailsListMain) {
adapter = new ProfileEmailsAdapter(getContext(), emailsListMain);
adapter = new MyProfileEmailsAdapter(getContext(), emailsListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataEmails.setVisibility(View.GONE);

View File

@ -10,29 +10,25 @@ import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.adapters.ProfileFollowersAdapter;
import org.mian.gitnex.databinding.FragmentProfileFollowersBinding;
import org.mian.gitnex.adapters.MyProfileFollowersAdapter;
import org.mian.gitnex.databinding.FragmentProfileFollowersFollowingBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.viewmodels.ProfileFollowersViewModel;
import java.util.List;
/**
* Author M M Arif
*/
public class ProfileFollowersFragment extends Fragment {
public class MyProfileFollowersFragment extends Fragment {
private ProgressBar mProgressBar;
private ProfileFollowersAdapter adapter;
private MyProfileFollowersAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noDataFollowers;
private static String repoNameF = "param2";
@ -43,11 +39,11 @@ public class ProfileFollowersFragment extends Fragment {
private OnFragmentInteractionListener mListener;
public ProfileFollowersFragment() {
public MyProfileFollowersFragment() {
}
public static ProfileFollowersFragment newInstance(String param1, String param2) {
ProfileFollowersFragment fragment = new ProfileFollowersFragment();
public static MyProfileFollowersFragment newInstance(String param1, String param2) {
MyProfileFollowersFragment fragment = new MyProfileFollowersFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
@ -68,21 +64,20 @@ public class ProfileFollowersFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentProfileFollowersBinding fragmentProfileFollowersBinding = FragmentProfileFollowersBinding.inflate(inflater, container, false);
FragmentProfileFollowersFollowingBinding fragmentProfileFollowersFollowingBinding = FragmentProfileFollowersFollowingBinding.inflate(inflater, container, false);
final SwipeRefreshLayout swipeRefresh = fragmentProfileFollowersBinding.pullToRefresh;
final SwipeRefreshLayout swipeRefresh = fragmentProfileFollowersFollowingBinding.pullToRefresh;
noDataFollowers = fragmentProfileFollowersBinding.noDataFollowers;
mRecyclerView = fragmentProfileFollowersBinding.recyclerView;
noDataFollowers = fragmentProfileFollowersFollowingBinding.noData;
mRecyclerView = fragmentProfileFollowersFollowingBinding.recyclerView;
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.addItemDecoration(dividerItemDecoration);
mProgressBar = fragmentProfileFollowersBinding.progressBar;
mProgressBar = fragmentProfileFollowersFollowingBinding.progressBar;
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
@ -93,28 +88,28 @@ public class ProfileFollowersFragment extends Fragment {
fetchDataAsync(Authorization.get(getContext()));
return fragmentProfileFollowersBinding.getRoot();
return fragmentProfileFollowersFollowingBinding.getRoot();
}
private void fetchDataAsync(String instanceToken) {
ProfileFollowersViewModel pfModel = new ViewModelProvider(this).get(ProfileFollowersViewModel.class);
pfModel.getFollowersList(instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer<List<UserInfo>>() {
@Override
public void onChanged(@Nullable List<UserInfo> pfListMain) {
adapter = new ProfileFollowersAdapter(getContext(), pfListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataFollowers.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noDataFollowers.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
pfModel.getFollowersList(instanceToken, getContext()).observe(getViewLifecycleOwner(), pfListMain -> {
adapter = new MyProfileFollowersAdapter(getContext(), pfListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataFollowers.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noDataFollowers.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
});
}

View File

@ -10,45 +10,41 @@ import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.adapters.ProfileFollowingAdapter;
import org.mian.gitnex.databinding.FragmentProfileFollowingBinding;
import org.mian.gitnex.adapters.MyProfileFollowingAdapter;
import org.mian.gitnex.databinding.FragmentProfileFollowersFollowingBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.viewmodels.ProfileFollowingViewModel;
import java.util.List;
/**
* Author M M Arif
*/
public class ProfileFollowingFragment extends Fragment {
public class MyProfileFollowingFragment extends Fragment {
private ProgressBar mProgressBar;
private ProfileFollowingAdapter adapter;
private MyProfileFollowingAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noDataFollowing;
private static String repoNameF = "param2";
private static String repoOwnerF = "param1";
private static final String repoNameF = "param2";
private static final String repoOwnerF = "param1";
private String repoName;
private String repoOwner;
private OnFragmentInteractionListener mListener;
public ProfileFollowingFragment() {
public MyProfileFollowingFragment() {
}
public static ProfileFollowingFragment newInstance(String param1, String param2) {
ProfileFollowingFragment fragment = new ProfileFollowingFragment();
public static MyProfileFollowingFragment newInstance(String param1, String param2) {
MyProfileFollowingFragment fragment = new MyProfileFollowingFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
@ -69,23 +65,22 @@ public class ProfileFollowingFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentProfileFollowingBinding fragmentProfileFollowingBinding = FragmentProfileFollowingBinding.inflate(inflater, container, false);
FragmentProfileFollowersFollowingBinding fragmentProfileFollowersFollowingBinding = FragmentProfileFollowersFollowingBinding.inflate(inflater, container, false);
TinyDB tinyDb = TinyDB.getInstance(getContext());
final SwipeRefreshLayout swipeRefresh = fragmentProfileFollowingBinding.pullToRefresh;
final SwipeRefreshLayout swipeRefresh = fragmentProfileFollowersFollowingBinding.pullToRefresh;
noDataFollowing = fragmentProfileFollowingBinding.noDataFollowing;
mRecyclerView = fragmentProfileFollowingBinding.recyclerView;
noDataFollowing = fragmentProfileFollowersFollowingBinding.noData;
mRecyclerView = fragmentProfileFollowersFollowingBinding.recyclerView;
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.addItemDecoration(dividerItemDecoration);
mProgressBar = fragmentProfileFollowingBinding.progressBar;
mProgressBar = fragmentProfileFollowersFollowingBinding.progressBar;
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
@ -96,28 +91,28 @@ public class ProfileFollowingFragment extends Fragment {
fetchDataAsync(Authorization.get(getContext()));
return fragmentProfileFollowingBinding.getRoot();
return fragmentProfileFollowersFollowingBinding.getRoot();
}
private void fetchDataAsync(String instanceToken) {
ProfileFollowingViewModel pfModel = new ViewModelProvider(this).get(ProfileFollowingViewModel.class);
pfModel.getFollowingList(instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer<List<UserInfo>>() {
@Override
public void onChanged(@Nullable List<UserInfo> pfListMain) {
adapter = new ProfileFollowingAdapter(getContext(), pfListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataFollowing.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noDataFollowing.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
pfModel.getFollowingList(instanceToken, getContext()).observe(getViewLifecycleOwner(), pfListMain -> {
adapter = new MyProfileFollowingAdapter(getContext(), pfListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataFollowing.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
noDataFollowing.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
});
}

View File

@ -36,7 +36,7 @@ import jp.wasabeef.picasso.transformations.BlurTransformation;
* Author M M Arif
*/
public class ProfileFragment extends Fragment {
public class MyProfileFragment extends Fragment {
private Context ctx;
@ -61,18 +61,14 @@ public class ProfileFragment extends Fragment {
TextView userLanguage = v.findViewById(R.id.userLanguage);
ImageView userLanguageIcon = v.findViewById(R.id.userLanguageIcon);
ViewGroup aboutFrame = v.findViewById(R.id.aboutFrame);
String[] userLanguageCodes = tinyDb.getString("userLang").split("-");
if(userLanguageCodes.length >= 2) {
Locale locale = new Locale(userLanguageCodes[0], userLanguageCodes[1]);
userLanguage.setText(locale.getDisplayLanguage());
}
else {
userLanguage.setText(R.string.notSupported);
userLanguage.setText(getResources().getConfiguration().locale.getDisplayLanguage());
}
userAvatar.setOnClickListener(loginId ->
@ -83,9 +79,11 @@ public class ProfileFragment extends Fragment {
userFullName.setText(Html.fromHtml(tinyDb.getString("userFullname")));
userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin")));
int avatarRadius = AppUtil.getPixelsFromDensity(ctx, 3);
PicassoService.getInstance(ctx).get()
.load(tinyDb.getString("userAvatar"))
.transform(new RoundedTransformation(8, 0))
.transform(new RoundedTransformation(avatarRadius, 0))
.placeholder(R.drawable.loader_animated)
.resize(120, 120)
.centerCrop().into(userAvatar);
@ -97,7 +95,7 @@ public class ProfileFragment extends Fragment {
@Override
public void onSuccess() {
int invertedColor = new ColorInverter().getImageViewContrastColor(userAvatar);
int invertedColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground);
userFullName.setTextColor(invertedColor);
divider.setBackgroundColor(invertedColor);
@ -110,7 +108,7 @@ public class ProfileFragment extends Fragment {
@Override public void onError(Exception e) {}
});
ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
MyProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
ViewPager mViewPager = v.findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
@ -157,7 +155,6 @@ public class ProfileFragment extends Fragment {
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
return v;
}
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter {
@ -173,25 +170,23 @@ public class ProfileFragment extends Fragment {
switch (position) {
case 0: // followers
return ProfileFollowersFragment.newInstance("repoOwner", "repoName");
return MyProfileFollowersFragment.newInstance("repoOwner", "repoName");
case 1: // following
return ProfileFollowingFragment.newInstance("repoOwner", "repoName");
return MyProfileFollowingFragment.newInstance("repoOwner", "repoName");
case 2: // emails
return ProfileEmailsFragment.newInstance("repoOwner", "repoName");
return MyProfileEmailsFragment.newInstance("repoOwner", "repoName");
}
return null;
}
@Override
public int getCount() {
return 3;
}
}
@Override
@ -200,7 +195,6 @@ public class ProfileFragment extends Fragment {
menu.clear();
requireActivity().getMenuInflater().inflate(R.menu.profile_dotted_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
@ -208,21 +202,18 @@ public class ProfileFragment extends Fragment {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
((MainActivity)ctx).finish();
return true;
case R.id.profileMenu:
BottomSheetProfileFragment bottomSheet = new BottomSheetProfileFragment();
bottomSheet.show(getChildFragmentManager(), "profileBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
if(id == android.R.id.home) {
((MainActivity)ctx).finish();
return true;
}
else if(id == R.id.profileMenu) {
BottomSheetMyProfileFragment bottomSheet = new BottomSheetMyProfileFragment();
bottomSheet.show(getChildFragmentManager(), "profileBottomSheet");
return true;
}
else {
return super.onOptionsItemSelected(item);
}
}
}

View File

@ -16,6 +16,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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;
@ -95,12 +96,15 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
notificationsActions = new NotificationsActions(context);
notificationsAdapter = new NotificationsAdapter(context, notificationThreads, this, this);
RecyclerView recyclerView = fragmentNotificationsBinding.notifications;
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
RecyclerView recyclerView = fragmentNotificationsBinding.notifications;
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(notificationsAdapter);
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.addOnScrollListener(new InfiniteScrollListener(pageResultLimit, linearLayoutManager) {
@Override
@ -249,6 +253,10 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
if(notificationThreads.isEmpty()) {
noDataNotifications.setVisibility(View.VISIBLE);
markAllAsRead.setVisibility(View.GONE);
}
else {
markAllAsRead.setVisibility(View.VISIBLE);
}
}
});

Some files were not shown because too many files have changed in this diff Show More