Compare commits

...

58 Commits

Author SHA1 Message Date
8b1c79c0c3 Merge pull request 'Prepare release 3.0.0 rc1' (#520) from prepare-release into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/520
2020-05-31 13:39:25 +00:00
bf26a44376 Prepare release 3.0.0 rc1 2020-05-31 18:36:42 +05:00
6721b09de9 Improve single issue UI (#518)
Merge branch 'master' into single-issue-ui

Add progressbar, match the ui to other ui for views(lines etc). And other refactors.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/518
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-30 16:59:52 +00:00
0f9e130cf4 Using more recent docker image for eclint. (#516)
Using more recent docker image for eclint.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/516
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-29 21:31:55 +00:00
014b06cc46 Fix org repos layout bug, cleanup layouts and adapters (#514)
Merge branch 'extra-space' into fix-extra-space

# Conflicts:
#	app/src/main/res/layout/list_repositories.xml

fix margins and clean up

Adjusting margin to be consistent.

remove association

Fix org repos layout bug, cleanup layouts and adapters

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/514
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-29 19:30:04 +00:00
6654b6fb48 [CI] Use enviroment variables again (#511)
[CI] Hopefully fixing upload now.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/511
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-28 10:19:14 +00:00
f1eb632d9b CI: Adding basic formatting tests (#509)
better names

Using dedicated eclint image

Reconfiguring editorconfig

Removing intellij-specific configuration and making adjustments.

Final improvements

Minor improvements.

end_of_line = lf

Adding basic formatting tests.

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/509
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-27 18:09:55 +00:00
34f8f82b63 Fix infined load on Issues/Pulls if they dont exist (#507)
404 fix for issues

add 404 for pr

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/507
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-23 18:30:33 +00:00
b30e2da387 Milestones filter(open/close) + refactor (#506)
remove strings

translation: generic but with contecxt

Merge branch 'milestones-filter' of gitea.com:gitnex/GitNex into milestones-filter

Clean up strings

Merge branch 'master' into milestones-filter

clean up and add missing parts

enhance and refactor milestone, added filter for closed and open ms

change to viewbinding

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/506
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-23 17:54:16 +00:00
6b3ac84113 Decreasing upload time to 3 minutes, increasing attempts and removing proxy. (#504)
CI: Decreasing upload time to 3 minutes, increasing attempts and removing proxy.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/504
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-23 08:38:09 +00:00
9541ef7dbc Merge pull request 'Enhance profile screen' (#505) from enhance-profile into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/505
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-22 15:46:48 +00:00
6a6bbef63d Enhance profile screen 2020-05-22 17:02:16 +05:00
dc168a732b Update Crowdin 2020-05-21 (#503)
Update Crowdin 2020-05-21

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/503
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-21 23:08:40 +00:00
d06f5353c6 Delete branch after merge (#496)
delete branch API call

Add fork repo info for branch

Check if pr is mergeable, show message if not.

Use checkbox instead of button

make ripple effects work for buttons with enable/disable

introduce viewbinding

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/496
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-21 22:49:09 +00:00
1b213783bc New file saving (#502)
New file saving

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/502
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-21 20:16:31 +00:00
e83b9eb736 Check Issue Subscription and display button based on that (#445)
update string names

Update strings

Merge branch 'master' into imprufe-issue-subscription-checking

switch icon as per @mmarif

Migrate to new Version Check & disable IssueSubscription function for gitea < 1.12.0

Merge branch 'master' into imprufe-issue-subscription-checking

Merge branch 'master' into imprufe-issue-subscription-checking

Merge branch 'master' into imprufe-issue-subscription-checking

refactor  & use dismiss()

realy check If issue is subscribed

add 200 http Status check and handle it

Rename WatchRepository to WatchInfo & add checkIssueWatchStatus

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/445
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-21 18:58:00 +00:00
ad7c3696d5 [BugFix] Version Compare (#500)
BugFix of Version

add new TestCase

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/500
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-21 14:13:14 +00:00
7bfdfa3223 Add/Remove new member to team (#483)
Search as user type, fix datalist.

Code Format

Fix users search theme

add and remove user from team

Add interface and user search and check for being team member or not

bottom sheet menu and few refactors

Co-authored-by: 6543 <6543@noreply.gitea.io>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/483
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-20 18:21:09 +00:00
0f38d81cd0 Minor improvements concerning CI. (#498)
Minor improvements concerning CI

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/498
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-19 17:56:38 +00:00
dd92ef9732 Merge pull request 'Adding additional functionality to build upload.' (#497) from opyale/GitNex:ci-upload-reloaded into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/497
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-18 23:20:47 +00:00
408fd9627b Adding additional functionality. 2020-05-19 01:09:56 +02:00
3de4dd9463 Refactor Version Checks (#472)
Merge branch 'master' into refactor-versionCheck

Merge branch 'master' into refactor-versionCheck

Revert "test CI"

This reverts commit b56eff0920.

test CI

Reformat LoginActivity.java

cleanup

migrate

Working + Tests

add first UnitTest

wip ...

enum2class

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/472
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-17 16:14:06 +00:00
7f0689524f Merge pull request 'Add corners to popup dialogs' (#495) from ui-enhancements into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/495
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-15 22:08:29 +00:00
a4afa5fbc2 Add corners to popup dialogs 2020-05-16 02:09:49 +05:00
29756511f3 Merge pull request 'Small layout adjustments and correcting typos.' (#493) from opyale/GitNex:settings-design-typo-adj into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/493
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-14 15:09:48 +00:00
56d8cd0fac Small layout adjustments and correcting typos. 2020-05-14 12:46:49 +02:00
4e6057171b Adding deprecation dialog. (#492)
Additional improvements.

Final improvements.

Adding deprecation dialog.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/492
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-09 19:07:55 +00:00
ab8a5ed505 Clear cache, configure cache size (#482)
decrease the compression to have better results

Move cache size outside of maxsize method. fix progress bar alignment for files

Add cache size to picasso

Use getAbsolutePath

Merge branch 'app-cache' of gitea.com:gitnex/GitNex into app-cache

Few imprvoements

Merge branch 'master' into app-cache

small improvement

Implement configure cache size and clear it

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/482
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-09 14:50:45 +00:00
a6b424f5ff Fix files layout bug (#485)
Fix files layout bug

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/485
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-04 17:16:36 +00:00
e5d6fd3b41 [New] Delete own comment (#478)
Code Reformat

Use return from 6543 commit

Fix typo

Move delete method to adapter to update the recyclerview

make it work

add to bottomsheet entry

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/478
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-30 10:42:22 +00:00
5d1efe0f3f Moving HighlightJS into app. (#477)
Final fixes and improvements.

Fixing crash of app in Android 5.0

Removing unused theme.

Moving HighlightJS to app.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/477
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-30 06:28:27 +00:00
c41ab845fd Refactor Context (#469)
Merge branch 'master' into fix-refactor-context

reorder + space

fix

R E F A C T O R

set ctx and appCtx in LoginActivity

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/469
Reviewed-by: M M Arif <mmarif@swatian.com>
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-04-28 13:47:25 +00:00
e45dc4b311 Increasing usability and design of files diff. (#413)
Applying sizes.

Additional changes.

First changes.

Merge branch 'master' into diff-cleaner

Fixing formatting.

Merge branch 'master' into diff-cleaner

Final changes for working with custom themes.

Merge remote-tracking branch 'remotes/main/master' into diff-cleaner

First changes for working with custom themes.

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Adding custom COLOR_FONT.

Even smaller cleanups.

Merge remote-tracking branch 'remotes/main/master' into diff-cleaner

Small cleanups.

Fixing bug and adding maximum line limit.

Adding option to set cursor to end and small cleanup.

First aid.

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Few improvements.

Performance improvements and cleanups.

Minor improvements (code in order) and many bug fixes

Bug fix.

Combining cited code.

Adding code commenting option.

Renaming list_files_diffs_new to list_files_diffs

Moving ProcessBar into center

Increasing performance.

Applying size to all icons globally.

Removing another unused file.

Merge remote-tracking branch 'remotes/main/master' into diff-cleaner

Removing unused files.

Changing size of 'close'-button.

Major changes concerning design and bug fixes.

Temporary save point.

2

1

Co-authored-by: opyale <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/413
Reviewed-by: 6543 <6543@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-28 12:39:41 +00:00
7c53de363d Fix the context bug (#470)
Fix the context bug. done in activities

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/470
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-28 10:36:07 +00:00
f352f175dd Merge pull request 'Add phone os version and model' (#468) from add-phone-os-section into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/468
2020-04-28 06:34:43 +00:00
d1a5c9c897 Add phone os version and model 2020-04-28 06:33:39 +00:00
51a7bca889 Merge pull request 'Small refactor and cleanup' (#467) from refactor-cleanup into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/467
2020-04-28 06:20:35 +00:00
03528f653a small refactor and cleanup 2020-04-28 11:18:58 +05:00
9d182821d2 Hide new branch when current is selected (#451)
Hide is best approach here

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/451
Reviewed-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-28 02:08:12 +00:00
195bfc8fe2 Refactor commits (#452)
code reformat

check for same gitea version

change link to button `view in browser`

add search by commit hash

Fix crash for custom attr caused by context and clean up

Refactor commits, remove fastadapter

Co-authored-by: 6543 <6543@noreply.gitea.io>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/452
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-26 22:59:09 +00:00
2e89fb0054 Fix load more after using filter (#463)
Fix load more after using filter

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/463
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-04-26 21:21:15 +00:00
48abe71645 Split settings screen into different sections (#457)
add reports section

Add translation, fix change lang bug not taking affect

Add security section

Add file viewer section

Change settings screen into different sections

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/457
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-26 13:36:33 +00:00
eca46b7913 Notification icons (#458)
New notification icon with transparent background

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/458
Reviewed-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-26 11:13:56 +00:00
6736fa2f5d Fix repo url (#455)
Fix repo url

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/455
Reviewed-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-26 11:02:03 +00:00
bbf41988d5 Merge pull request 'Enhance statusbar color for light theme' (#453) from enhance-statusbar-color-in-light-theme into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/453
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-04-26 09:54:30 +00:00
aa3288e889 Enhance statusbar color for light theme 2020-04-25 20:41:17 +05:00
92a0d06b75 Merge pull request 'Fix newlines in Readme' (#447) from fix-readme-newlines into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/447
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-24 04:59:21 +00:00
4e7fd6295e Fix newlines in Readme
because of new Render rouls - linebreaks have to be fixed
2020-04-24 00:28:44 +00:00
0ee5b43996 Optimize fragments, add filters, fix search and clean up (#439)
Code Reformat

hide not found message

Refactor issues, remove fastadapter.

fix swipe back filter icon issue, fix crash on issues with faster swiping

Change filter icon based on selection, empty the list for progress bar, check for gitea version to pass limit and other improvements

Separate menu and interface for pr

Add filter bottom sheet to PRs, issues

Fix search/filter pull requests

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/439
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-04-23 20:40:13 +00:00
625e60f2e2 Merge pull request 'Create new screen for administration' (#442) from 438-admin-nav into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/442
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-23 16:11:06 +00:00
3fb063b0b1 Display Admin Menue Only If you are Admin 2020-04-23 18:04:32 +02:00
d7ef368f0b Create new screen for administration 2020-04-23 17:05:50 +05:00
dd1fce892a Replace textview with button for view commits in branches (#437)
Replace textview with button for view commits in branches

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/437
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-22 10:12:56 +00:00
f39357f596 update master (#436)
update changelog

update master

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/436
2020-04-22 05:05:35 +00:00
3bfc6b94a4 Merge pull request 'Crowdin [2020-04-21]' (#431) from 6543/GitNex:update-crowdin into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/431
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-21 13:52:51 +00:00
996d5d5fea Update from Crowdin 2020-04-21 10:40:54 +02:00
af6cbfdb66 [FrontPort #429] Dismiss bottom sheet on subscribe/unsubscribe to issue & Fix (#428)
Merge branch 'master' into 427-dismiss-bottom-sheet

Does not really fix the issue as there is way to handle this without a proper call.
And dismiss does not work properly either.

But added few improvements and fixed close/reopen issue along the way.

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/428
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-18 14:29:42 +00:00
01e451556e README: Add download for CI build apk (#424)
Merge branch 'master' into update-readme-add-ci-build

apply suggestions

Change "Download APK" option to gitnex.com download page

add download for CI build apk

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/424
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-18 13:58:38 +00:00
219 changed files with 11323 additions and 7563 deletions

View File

@ -1,21 +1,59 @@
--- ---
kind: pipeline kind: pipeline
name: gitnex-ci-test type: docker
name: tests
steps: steps:
- name: test - name: unit-tests
image: nextcloudci/android:android-49 image: nextcloudci/android:android-49
depends_on: [ clone ]
commands: commands:
- ./gradlew test - ./gradlew test
- name: check-formatting
image: zosiab/eclint:latest
depends_on: [ clone ]
commands:
- git pull origin master
- eclint check $(git diff --name-only origin/master)
# 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
#
# - name: do-or-check-formatting
# image: dlsniper/docker-intellij
# depends_on: [ clone ]
# commands:
# - /opt/intellij/bin/idea.sh inspect/format ...
trigger: trigger:
event: event:
- pull_request - pull_request
--- ---
kind: pipeline kind: pipeline
name: gitnex-ci-build type: docker
name: code-analysis
steps:
- name: check-global-formatting
image: zosiab/eclint:latest
depends_on: [ clone ]
commands:
- eclint check $(git ls-files)
trigger:
event:
- push
branch:
- master
---
kind: pipeline
type: docker
name: build
steps: steps:
@ -47,8 +85,11 @@ steps:
WEBDAV_USERNAME: GitNexBot WEBDAV_USERNAME: GitNexBot
WEBDAV_PASSWORD: WEBDAV_PASSWORD:
from_secret: NC_TOKEN from_secret: NC_TOKEN
PLUGIN_FILE: signed.apk PLUGIN_FILE: 'signed.apk'
PLUGIN_DESTINATION: https://cloud.swatian.com/remote.php/dav/files/GitNexBot/GitNex-Builds/latest.apk PLUGIN_TIMEOUT: 180
PLUGIN_ATTEMPTS: 5
PLUGIN_DESTINATION: 'https://cloud.swatian.com/remote.php/dav/files/GitNexBot/GitNex-Builds/latest.apk'
PLUGIN_CUSTOM_ARGUMENTS: '--progress-bar'
trigger: trigger:
event: event:

17
.editorconfig Normal file
View File

@ -0,0 +1,17 @@
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 150
[*.java]
indent_style = tab
max_line_length = 220
[*.json]
indent_size = 2
[{*.yml,*.yaml}]
indent_size = 2

View File

@ -20,6 +20,7 @@ _(This step is optional; an example is shown below)_
* The version of **Gitea** you are using: * The version of **Gitea** you are using:
* The version of **GitNex** you are using: * The version of **GitNex** you are using:
* Phone **OS** version and model:
* The type of certificate you are using (self-signed, signed): * The type of certificate you are using (self-signed, signed):
* How you used to log in (via password or token): * How you used to log in (via password or token):

View File

@ -1,23 +1,19 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://gitea.com/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://gitea.com/gitnex/GitNex/releases) [![Build Status](https://drone.gitea.com/api/badges/gitnex/GitNex/status.svg)](https://drone.gitea.com/gitnex/GitNex) [![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)
[![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://gitea.com/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://gitea.com/gitnex/GitNex/releases)
[![Build Status](https://drone.gitea.com/api/badges/gitnex/GitNex/status.svg)](https://drone.gitea.com/gitnex/GitNex)
[![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) [<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) [<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate)
[<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate)
# GitNex - Android client for Gitea # GitNex - Android client for Gitea
GitNex is a free, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go. GitNex is a free, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go.
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. No trackers are used and source code is available here for anyone to audit.
No trackers are used and source code is available here for anyone to audit.
## Downloads ## 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 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) [<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)
[<img alt='Download APK' src='https://gitnex.com/img/download-apk.png' height="80"/>](https://gitea.com/gitnex/GitNex/releases) [<img alt='Download APK' src='https://gitnex.com/img/download-apk.png' height="80"/>](https://cloud.swatian.com/s/QoDFzMxmnf2FfYw)
Download latest build from master: [https://cloud.swatian.com/s/Cq592xGEfnsGAAW](https://cloud.swatian.com/s/Cq592xGEfnsGAAW)
## Note about Gitea version ## Note about Gitea version
Please make sure that you are on latest stable release or later for better app experience. Please make sure that you are on latest stable release or later for better app experience.
@ -44,8 +40,7 @@ Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew build`
## Translation ## Translation
Help us translate GitNex to your native language. Help us translate GitNex to your native language.
We use [Crowdin](https://crowdin.com/project/gitnex) for translation. We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your language is not listed, please request [here](https://gitea.com/gitnex/GitNex/issues) to add it to the project.
If your language is not listed, please request [here](https://gitea.com/gitnex/GitNex/issues) to add it to the project.
**Link: https://crowdin.com/project/GitNex** **Link: https://crowdin.com/project/GitNex**
@ -91,7 +86,6 @@ Open source libraries
- Caverock/androidsvg - Caverock/androidsvg
- Droidsonroids.gif/android-gif-drawable - Droidsonroids.gif/android-gif-drawable
- Barteksc/AndroidPdfViewer - Barteksc/AndroidPdfViewer
- Mikepenz/fastadapter
- Ge0rg/MemorizingTrustManager - Ge0rg/MemorizingTrustManager
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif) [Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)

View File

@ -6,10 +6,13 @@ android {
applicationId "org.mian.gitnex" applicationId "org.mian.gitnex"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 29
versionCode 104 versionCode 295
versionName "2.5.0-rc4" versionName "3.0.0-rc1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
viewBinding {
enabled = true
}
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
@ -35,27 +38,26 @@ configurations {
dependencies { dependencies {
def lifecycle_version = "2.2.0" def lifecycle_version = "2.2.0"
def markwon_version = '4.3.1' def markwon_version = '4.3.1'
def fastadapter = "3.3.1"
def acra = "5.5.0" def acra = "5.5.0"
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:1.1.0" implementation "androidx.appcompat:appcompat:1.2.0-rc01"
implementation "com.google.android.material:material:1.2.0-alpha06" implementation "com.google.android.material:material:1.2.0-beta01"
implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.legacy:legacy-support-v4:1.0.0"
testImplementation "junit:junit:4.13" testImplementation "junit:junit:4.13"
androidTestImplementation "androidx.test:runner:1.2.0" androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0" androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
implementation "com.github.vihtarb:tooltip:0.2.0" implementation "com.github.vihtarb:tooltip:0.2.0"
implementation 'com.squareup.okhttp3:okhttp:4.5.0' implementation 'com.squareup.okhttp3:okhttp:4.7.0'
implementation "com.google.code.gson:gson:2.8.6" implementation "com.google.code.gson:gson:2.8.6"
implementation "com.squareup.picasso:picasso:2.71828" implementation "com.squareup.picasso:picasso:2.71828"
implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1" implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1"
implementation 'com.squareup.retrofit2:retrofit:2.8.1' implementation 'com.squareup.retrofit2:retrofit:2.8.1'
implementation 'com.squareup.retrofit2:converter-gson:2.8.1' implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
implementation 'com.squareup.retrofit2:converter-scalars:2.8.1' implementation 'com.squareup.retrofit2:converter-scalars:2.8.1'
implementation 'com.squareup.okhttp3:logging-interceptor:4.5.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.7.0'
implementation 'org.ocpsoft.prettytime:prettytime:4.0.4.Final' implementation 'org.ocpsoft.prettytime:prettytime:4.0.5.Final'
implementation "com.vdurmont:emoji-java:5.1.1" implementation "com.vdurmont:emoji-java:5.1.1"
implementation "com.pes.materialcolorpicker:library:1.2.5" implementation "com.pes.materialcolorpicker:library:1.2.5"
implementation "io.noties.markwon:core:$markwon_version" implementation "io.noties.markwon:core:$markwon_version"
@ -80,12 +82,7 @@ dependencies {
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9" implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
implementation "commons-io:commons-io:20030203.000550" implementation "commons-io:commons-io:20030203.000550"
implementation "com.github.chrisbanes:PhotoView:2.3.0" implementation "com.github.chrisbanes:PhotoView:2.3.0"
implementation "com.pddstudio:highlightjs-android:1.5.0"
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1" implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
//noinspection GradleDependency
implementation "com.mikepenz:fastadapter:$fastadapter"
implementation "com.mikepenz:fastadapter-commons:$fastadapter"
implementation "com.mikepenz:fastadapter-extensions:$fastadapter"
implementation "ch.acra:acra-mail:$acra" implementation "ch.acra:acra-mail:$acra"
implementation "ch.acra:acra-limiter:$acra" implementation "ch.acra:acra-limiter:$acra"
implementation "ch.acra:acra-notification:$acra" implementation "ch.acra:acra-notification:$acra"

View File

@ -5,7 +5,6 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@ -75,6 +74,12 @@
<activity android:name=".activities.FileDiffActivity" /> <activity android:name=".activities.FileDiffActivity" />
<activity android:name=".activities.CommitsActivity" /> <activity android:name=".activities.CommitsActivity" />
<activity android:name=".helpers.ssl.MemorizingActivity" android:theme="@android:style/Theme.Material.Dialog" /> <activity android:name=".helpers.ssl.MemorizingActivity" android:theme="@android:style/Theme.Material.Dialog" />
<activity android:name=".activities.SettingsAppearanceActivity" />
<activity android:name=".activities.SettingsFileViewerActivity" />
<activity android:name=".activities.SettingsSecurityActivity" />
<activity android:name=".activities.SettingsTranslationActivity" />
<activity android:name=".activities.SettingsReportsActivity" />
<activity android:name=".activities.AddNewTeamMemberActivity" />
</application> </application>
</manifest> </manifest>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
!function(e){"use strict";function t(){"complete"===document.readyState?n():e.addEventListener("DOMContentLoaded",n)}function n(){try{var e=document.querySelectorAll("code.hljs");for(var t in e)e.hasOwnProperty(t)&&r(e[t])}catch(n){console.error("LineNumbers error: ",n)}}function r(e){if("object"==typeof e){var t=e.parentNode,n=o(t.textContent);if(n>1){for(var r="",c=0;n>c;c++)r+=c+1+"\n";var l=document.createElement("code");l.className="hljs hljs-line-numbers",l.style["float"]="left",l.textContent=r,t.insertBefore(l,e)}}}function o(e){if(0===e.length)return 0;var t=/\r\n|\r|\n/g,n=e.match(t);return n=n?n.length:0,e[e.length-1].match(t)||(n+=1),n}"undefined"==typeof e.hljs?console.error("highlight.js not detected!"):(e.hljs.initLineNumbersOnLoad=t,e.hljs.lineNumbersBlock=r)}(window);

View File

@ -0,0 +1,66 @@
/*
Date: 24 Fev 2015
Author: Pedro Oliveira <kanytu@gmail . com>
*/
.hljs {
color: #a9b7c6;
background: #282b2e;
display: block;
overflow-x: auto;
padding: 0.5em;
}
.hljs-number,
.hljs-literal,
.hljs-symbol,
.hljs-bullet {
color: #6897BB;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-deletion {
color: #cc7832;
}
.hljs-variable,
.hljs-template-variable,
.hljs-link {
color: #629755;
}
.hljs-comment,
.hljs-quote {
color: #808080;
}
.hljs-meta {
color: #bbb529;
}
.hljs-string,
.hljs-attribute,
.hljs-addition {
color: #6A8759;
}
.hljs-section,
.hljs-title,
.hljs-type {
color: #ffc66d;
}
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #e8bf6a;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View File

@ -0,0 +1,87 @@
/*
Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #FFFFFF;
}
.hljs,
.hljs-subst {
color: #434f54;
}
.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-doctag,
.hljs-name {
color: #00979D;
}
.hljs-built_in,
.hljs-literal,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #D35400;
}
.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #00979D;
}
.hljs-type,
.hljs-string,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
color: #005C5F;
}
.hljs-title,
.hljs-section {
color: #880000;
font-weight: bold;
}
.hljs-comment {
color: rgba(149,165,166,.8);
}
.hljs-meta-keyword {
color: #728E00;
}
.hljs-meta {
color: #434f54;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-function {
color: #728E00;
}
.hljs-number {
color: #8A7B52;
}

View File

@ -0,0 +1,71 @@
/*
FAR Style (c) MajestiC <majestic2k@gmail.com>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #000080;
}
.hljs,
.hljs-subst {
color: #0ff;
}
.hljs-string,
.hljs-attribute,
.hljs-symbol,
.hljs-bullet,
.hljs-built_in,
.hljs-builtin-name,
.hljs-template-tag,
.hljs-template-variable,
.hljs-addition {
color: #ff0;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-section,
.hljs-type,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-variable {
color: #fff;
}
.hljs-comment,
.hljs-quote,
.hljs-doctag,
.hljs-deletion {
color: #888;
}
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-link {
color: #0f0;
}
.hljs-meta {
color: #008080;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-title,
.hljs-section,
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

View File

@ -0,0 +1,99 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View File

@ -0,0 +1,73 @@
/*
IR_Black style (c) Vasily Mikhailitchenko <vaskas@programica.ru>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #000;
color: #f8f8f8;
}
.hljs-comment,
.hljs-quote,
.hljs-meta {
color: #7c7c7c;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-tag,
.hljs-name {
color: #96cbfe;
}
.hljs-attribute,
.hljs-selector-id {
color: #ffffb6;
}
.hljs-string,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition {
color: #a8ff60;
}
.hljs-subst {
color: #daefa3;
}
.hljs-regexp,
.hljs-link {
color: #e9c062;
}
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-doctag {
color: #ffffb6;
}
.hljs-symbol,
.hljs-bullet,
.hljs-variable,
.hljs-template-variable,
.hljs-literal {
color: #c6c5fe;
}
.hljs-number,
.hljs-deletion {
color:#ff73fd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View File

@ -0,0 +1,83 @@
/*
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #23241f;
}
.hljs,
.hljs-tag,
.hljs-subst {
color: #f8f8f2;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2;
}
.hljs-bullet,
.hljs-quote,
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-link {
color: #ae81ff;
}
.hljs-code,
.hljs-title,
.hljs-section,
.hljs-selector-class {
color: #a6e22e;
}
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-name,
.hljs-attr {
color: #f92672;
}
.hljs-symbol,
.hljs-attribute {
color: #66d9ef;
}
.hljs-params,
.hljs-class .hljs-title {
color: #f8f8f2;
}
.hljs-string,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-variable {
color: #e6db74;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #75715e;
}

View File

@ -2,8 +2,7 @@ package org.mian.gitnex.actions;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import android.view.View; import androidx.annotation.NonNull;
import android.widget.TextView;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity; import org.mian.gitnex.activities.ReplyToIssueActivity;
@ -11,10 +10,9 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UpdateIssueState;
import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.models.IssueComments;
import org.mian.gitnex.models.UpdateIssueState;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import androidx.annotation.NonNull;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -24,256 +22,259 @@ import retrofit2.Callback;
public class IssueActions { public class IssueActions {
public static void editIssueComment(final Context ctx, final int commentId, final String commentBody) { public static void editIssueComment(final Context ctx, final int commentId, final String commentBody) {
final TinyDB tinyDb = new TinyDB(ctx); final TinyDB tinyDb = new TinyDB(ctx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
final String repoName = parts[1]; final String repoName = parts[1];
IssueComments commentBodyJson = new IssueComments(commentBody); IssueComments commentBodyJson = new IssueComments(commentBody);
Call<IssueComments> call; Call<IssueComments> call;
call = RetrofitClient call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().patchIssueComment(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, commentId, commentBodyJson);
.getInstance(instanceUrl, ctx)
.getApiInterface()
.patchIssueComment(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, commentId, commentBodyJson);
call.enqueue(new Callback<IssueComments>() { call.enqueue(new Callback<IssueComments>() {
@Override @Override
public void onResponse(@NonNull Call<IssueComments> call, @NonNull retrofit2.Response<IssueComments> response) { public void onResponse(@NonNull Call<IssueComments> call, @NonNull retrofit2.Response<IssueComments> response) {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 200) { if(response.code() == 200) {
tinyDb.putBoolean("commentEdited", true); tinyDb.putBoolean("commentEdited", true);
Toasty.info(ctx, ctx.getString(R.string.editCommentUpdatedText)); Toasty.info(ctx, ctx.getString(R.string.editCommentUpdatedText));
((ReplyToIssueActivity)ctx).finish(); ((ReplyToIssueActivity) ctx).finish();
} }
} }
else if(response.code() == 401) { else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else { else {
Toasty.info(ctx, ctx.getString(R.string.genericError)); Toasty.info(ctx, ctx.getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<IssueComments> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<IssueComments> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
} Log.e("onFailure", t.toString());
}
});
public static void closeReopenIssue(final Context ctx, final int issueIndex, final String issueState) { }
final TinyDB tinyDb = new TinyDB(ctx); public static void closeReopenIssue(final Context ctx, final int issueIndex, final String issueState) {
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
UpdateIssueState issueStatJson = new UpdateIssueState(issueState); final TinyDB tinyDb = new TinyDB(ctx);
Call<JsonElement> call; final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
call = RetrofitClient UpdateIssueState issueStatJson = new UpdateIssueState(issueState);
.getInstance(instanceUrl, ctx) Call<JsonElement> call;
.getApiInterface()
.closeReopenIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson);
call.enqueue(new Callback<JsonElement>() { call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().closeReopenIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson);
@Override call.enqueue(new Callback<JsonElement>() {
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()) { @Override
if(response.code() == 201) { public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
tinyDb.putBoolean("resumeIssues", true); if(response.isSuccessful()) {
tinyDb.putBoolean("resumeClosedIssues", true); if(response.code() == 201) {
if(issueState.equals("closed")) {
Toasty.info(ctx, ctx.getString(R.string.issueStateClosed));
}
else if(issueState.equals("open")) {
Toasty.info(ctx, ctx.getString(R.string.issueStateReopened));
}
} tinyDb.putBoolean("resumeIssues", true);
} tinyDb.putBoolean("resumeClosedIssues", true);
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), if(issueState.equals("closed")) {
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} Toasty.info(ctx, ctx.getString(R.string.issueStateClosed));
else if(response.code() == 403) { tinyDb.putString("issueState", "closed");
Toasty.info(ctx, ctx.getString(R.string.authorizeError)); }
else if(issueState.equals("open")) {
} Toasty.info(ctx, ctx.getString(R.string.issueStateReopened));
else if(response.code() == 404) { tinyDb.putString("issueState", "open");
Toasty.info(ctx, ctx.getString(R.string.apiNotFound)); }
} }
else { }
else if(response.code() == 401) {
Toasty.info(ctx, ctx.getString(R.string.genericError)); AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else if(response.code() == 403) {
} Toasty.info(ctx, ctx.getString(R.string.authorizeError));
@Override }
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { else if(response.code() == 404) {
Log.e("onFailure", t.toString());
}
});
} Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
public static void subscribe(final Context ctx, final TextView subscribeIssue, final TextView unsubscribeIssue) { }
else {
final TinyDB tinyDB = new TinyDB(ctx); Toasty.info(ctx, ctx.getString(R.string.genericError));
final String instanceUrl = tinyDB.getString("instanceUrl"); }
String repoFullName = tinyDB.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String loginUid = tinyDB.getString("loginUid");
final String userLogin = tinyDB.getString("userLogin");
final String token = "token " + tinyDB.getString(loginUid + "-token");
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
Call<Void> call; }
call = RetrofitClient @Override
.getInstance(instanceUrl, ctx) public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
.getApiInterface()
.addIssueSubscriber(token, repoOwner, repoName, issueNr, userLogin);
call.enqueue(new Callback<Void>() { Log.e("onFailure", t.toString());
}
});
@Override }
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
if(response.isSuccessful()) { public static void subscribe(final Context ctx) {
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtion)); final TinyDB tinyDB = new TinyDB(ctx);
subscribeIssue.setVisibility(View.GONE);
unsubscribeIssue.setVisibility(View.VISIBLE);
} final String instanceUrl = tinyDB.getString("instanceUrl");
else if(response.code() == 401) { String[] repoFullName = tinyDB.getString("repoFullName").split("/");
if(repoFullName.length != 2) {
return;
}
final String userLogin = tinyDB.getString("userLogin");
final String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), Call<Void> call;
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().addIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin);
else {
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtionError)); call.enqueue(new Callback<Void>() {
} @Override
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
} if(response.isSuccessful()) {
@Override if(response.code() == 201) {
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtionError));
}
});
} Toasty.info(ctx, ctx.getString(R.string.subscribedSuccessfully));
tinyDB.putBoolean("issueSubscribed", true);
public static void unsubscribe(final Context ctx, final TextView subscribeIssue, final TextView unsubscribeIssue) { }
else if(response.code() == 200) {
final TinyDB tinyDB = new TinyDB(ctx); tinyDB.putBoolean("issueSubscribed", true);
Toasty.info(ctx, ctx.getString(R.string.alreadySubscribed));
final String instanceUrl = tinyDB.getString("instanceUrl"); }
String repoFullName = tinyDB.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String loginUid = tinyDB.getString("loginUid");
final String userLogin = tinyDB.getString("userLogin");
final String token = "token " + tinyDB.getString(loginUid + "-token");
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
Call<Void> call; }
else if(response.code() == 401) {
call = RetrofitClient AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
.getInstance(instanceUrl, ctx)
.getApiInterface()
.delIssueSubscriber(token, repoOwner, repoName, issueNr, userLogin);
call.enqueue(new Callback<Void>() { }
else {
@Override Toasty.info(ctx, ctx.getString(R.string.subscribtionError));
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
if(response.isSuccessful()) { }
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtion)); }
unsubscribeIssue.setVisibility(View.GONE);
subscribeIssue.setVisibility(View.VISIBLE);
} @Override
else if(response.code() == 401) { public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), Toasty.info(ctx, ctx.getString(R.string.unsubscribedSuccessfully));
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), }
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), });
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else {
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtionError)); public static void unsubscribe(final Context ctx) {
} final TinyDB tinyDB = new TinyDB(ctx);
} final String instanceUrl = tinyDB.getString("instanceUrl");
String[] repoFullName = tinyDB.getString("repoFullName").split("/");
if(repoFullName.length != 2) {
return;
}
final String userLogin = tinyDB.getString("userLogin");
final String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
@Override Call<Void> call;
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtionError)); call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().delIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin);
}
}); call.enqueue(new Callback<Void>() {
}
@Override
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
if(response.isSuccessful()) {
if(response.code() == 201) {
Toasty.info(ctx, ctx.getString(R.string.unsubscribedSuccessfully));
tinyDB.putBoolean("issueSubscribed", false);
}
else if(response.code() == 200) {
tinyDB.putBoolean("issueSubscribed", false);
Toasty.info(ctx, ctx.getString(R.string.alreadyUnsubscribed));
}
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
Toasty.info(ctx, ctx.getString(R.string.unsubscribtionError));
}
}
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.info(ctx, ctx.getString(R.string.unsubscribtionError));
}
});
}
} }

View File

@ -7,11 +7,9 @@ import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.MilestonesViewModel;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -51,7 +49,6 @@ public class MilestoneActions {
if(response.isSuccessful()) { if(response.isSuccessful()) {
Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate)); Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate));
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, token), repoOwner, repoName, "all", ctx);
} }
else if(response.code() == 401) { else if(response.code() == 401) {
@ -110,7 +107,6 @@ public class MilestoneActions {
if(response.isSuccessful()) { if(response.isSuccessful()) {
Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate)); Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate));
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, token), repoOwner, repoName, "all", ctx);
} }
else if(response.code() == 401) { else if(response.code() == 401) {

View File

@ -0,0 +1,154 @@
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.activities.AddNewTeamMemberActivity;
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 org.mian.gitnex.util.TinyDB;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class TeamActions {
public static void removeTeamMember(final Context context, String userName, int teamId) {
final TinyDB tinyDb = new TinyDB(context);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl, context)
.getApiInterface()
.removeTeamMember(Authorization.returnAuthentication(context, loginUid, instanceToken), teamId, userName);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()) {
if(response.code() == 204) {
tinyDb.putBoolean("teamActionFlag", true);
Toasty.info(context, context.getString(R.string.memberRemovedMessage));
((AddNewTeamMemberActivity)context).finish();
}
}
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) {
Toasty.info(context, context.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(context, context.getString(R.string.apiNotFound));
}
else {
Toasty.info(context, context.getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
}
});
}
public static void addTeamMember(final Context context, String userName, int teamId) {
final TinyDB tinyDb = new TinyDB(context);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl, context)
.getApiInterface()
.addTeamMember(Authorization.returnAuthentication(context, loginUid, instanceToken), teamId, userName);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()) {
if(response.code() == 204) {
tinyDb.putBoolean("teamActionFlag", true);
Toasty.info(context, context.getString(R.string.memberAddedMessage));
((AddNewTeamMemberActivity)context).finish();
}
}
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) {
Toasty.info(context, context.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(context, context.getString(R.string.apiNotFound));
}
else {
Toasty.info(context, context.getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
}
});
}
}

View File

@ -34,6 +34,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private TextView addCollaboratorSearch; private TextView addCollaboratorSearch;
private TextView noData; private TextView noData;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
@ -47,11 +48,13 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -71,26 +74,26 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
addCollaboratorSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() { addCollaboratorSearch.setOnEditorActionListener((v, actionId, event) -> {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEND) {
if (actionId == EditorInfo.IME_ACTION_SEND) { if(!addCollaboratorSearch.getText().toString().equals("")) {
if(!addCollaboratorSearch.getText().toString().equals("")) { loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), loginUid);
loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), getApplicationContext(), loginUid);
}
} }
return false;
} }
return false;
}); });
} }
public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, final Context context, String loginUid) { public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, String loginUid) {
Call<UserSearch> call = RetrofitClient Call<UserSearch> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getUserBySearch(Authorization.returnAuthentication(getApplicationContext(), loginUid, token), searchKeyword, 10); .getUserBySearch(Authorization.returnAuthentication(ctx, loginUid, token), searchKeyword, 10);
call.enqueue(new Callback<UserSearch>() { call.enqueue(new Callback<UserSearch>() {
@ -99,7 +102,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
if (response.isSuccessful()) { if (response.isSuccessful()) {
assert response.body() != null; assert response.body() != null;
getUsersList(response.body().getData(), context); getUsersList(response.body().getData(), ctx);
} else { } else {
Log.i("onResponse", String.valueOf(response.code())); Log.i("onResponse", String.valueOf(response.code()));
} }
@ -119,7 +122,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
UserSearchAdapter adapter = new UserSearchAdapter(dataList, context); UserSearchAdapter adapter = new UserSearchAdapter(dataList, context);
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL); DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
@ -139,12 +142,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() { onClickListener = view -> finish();
@Override
public void onClick(View view) {
finish();
}
};
} }

View File

@ -0,0 +1,164 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.UserSearchForTeamMemberAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.models.UserSearch;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class AddNewTeamMemberActivity extends BaseActivity {
private View.OnClickListener onClickListener;
final Context ctx = this;
private Context appCtx;
private TextView addNewTeamMember;
private TextView noData;
private ProgressBar mProgressBar;
private RecyclerView mRecyclerView;
private List<UserInfo> dataList;
private UserSearchForTeamMemberAdapter adapter;
private String teamId;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_add_new_team_member;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
ImageView closeActivity = findViewById(R.id.close);
addNewTeamMember = findViewById(R.id.addNewTeamMeber);
mRecyclerView = findViewById(R.id.recyclerViewUserSearch);
mProgressBar = findViewById(R.id.progress_bar);
noData = findViewById(R.id.noData);
addNewTeamMember.requestFocus();
assert imm != null;
imm.showSoftInput(addNewTeamMember, InputMethodManager.SHOW_IMPLICIT);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")) {
teamId = getIntent().getStringExtra("teamId");
}
else {
teamId = "0";
}
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
dataList = new ArrayList<>();
addNewTeamMember.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(!addNewTeamMember.getText().toString().equals("")) {
adapter = new UserSearchForTeamMemberAdapter(dataList, ctx, Integer.parseInt(teamId));
loadUserSearchList(instanceUrl, instanceToken, addNewTeamMember.getText().toString(), loginUid, teamId);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, String loginUid, String teamId) {
Call<UserSearch> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserBySearch(Authorization.returnAuthentication(ctx, loginUid, token), searchKeyword, 10);
call.enqueue(new Callback<UserSearch>() {
@Override
public void onResponse(@NonNull Call<UserSearch> call, @NonNull Response<UserSearch> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().getData().size() > 0) {
dataList.clear();
dataList.addAll(response.body().getData());
mRecyclerView.setAdapter(adapter);
noData.setVisibility(View.GONE);
mProgressBar.setVisibility(View.GONE);
}
else {
noData.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
}
}
@Override
public void onFailure(@NonNull Call<UserSearch> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void initCloseListener() {
onClickListener = view -> finish();
}
}

View File

@ -34,6 +34,7 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
private Boolean assigneesFlag = false; private Boolean assigneesFlag = false;
private MultiSelectDialog multiSelectDialogAssignees; private MultiSelectDialog multiSelectDialogAssignees;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -44,11 +45,12 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE); //supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT)); getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -64,12 +66,12 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) { private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -92,9 +94,9 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
// get current issue assignees // get current issue assignees
Call<Issues> callSingleIssueAssignees = RetrofitClient Call<Issues> callSingleIssueAssignees = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex); .getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueAssignees.enqueue(new Callback<Issues>() { callSingleIssueAssignees.enqueue(new Callback<Issues>() {
@ -141,7 +143,7 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
Log.i("selectedNames", String.valueOf(selectedNames)); Log.i("selectedNames", String.valueOf(selectedNames));
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames); updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
tinyDb.putBoolean("singleIssueUpdate", true); tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity(); CloseActivity();
} }
@ -167,7 +169,7 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
@Override @Override
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) { public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames); updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
tinyDb.putBoolean("singleIssueUpdate", true); tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity(); CloseActivity();
@ -215,7 +217,7 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }
} }
@ -241,9 +243,9 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
Call<JsonElement> call3; Call<JsonElement> call3;
call3 = RetrofitClient call3 = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.patchIssueAssignees(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson); .patchIssueAssignees(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson);
call3.enqueue(new Callback<JsonElement>() { call3.enqueue(new Callback<JsonElement>() {
@ -275,7 +277,7 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }

View File

@ -32,6 +32,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
private Boolean labelsFlag = false; private Boolean labelsFlag = false;
private MultiSelectDialog multiSelectDialogLabels; private MultiSelectDialog multiSelectDialogLabels;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -40,12 +41,14 @@ public class AddRemoveLabelsActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE); //supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT)); getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -61,12 +64,12 @@ public class AddRemoveLabelsActivity extends BaseActivity {
private void getLabels(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) { private void getLabels(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<List<Labels>> call = RetrofitClient Call<List<Labels>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); .getlabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Labels>>() { call.enqueue(new Callback<List<Labels>>() {
@ -89,9 +92,9 @@ public class AddRemoveLabelsActivity extends BaseActivity {
// get current issue labels // get current issue labels
Call<List<Labels>> callSingleIssueLabels = RetrofitClient Call<List<Labels>> callSingleIssueLabels = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getIssueLabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex); .getIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueLabels.enqueue(new Callback<List<Labels>>() { callSingleIssueLabels.enqueue(new Callback<List<Labels>>() {
@ -142,7 +145,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
integers = new int[0]; integers = new int[0];
} }
updateIssueLabels(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid); updateIssueLabels(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
tinyDb.putBoolean("singleIssueUpdate", true); tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity(); CloseActivity();
} }
@ -183,7 +186,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
integers = new int[0]; integers = new int[0];
} }
updateIssueLabels(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid); updateIssueLabels(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
tinyDb.putBoolean("singleIssueUpdate", true); tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity(); CloseActivity();
@ -231,7 +234,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }
} }
@ -251,9 +254,9 @@ public class AddRemoveLabelsActivity extends BaseActivity {
Labels patchIssueLabels = new Labels(issueLabels); Labels patchIssueLabels = new Labels(issueLabels);
Call<JsonElement> call = RetrofitClient Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.updateIssueLabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels); .updateIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels);
call.enqueue(new Callback<JsonElement>() { call.enqueue(new Callback<JsonElement>() {
@ -285,7 +288,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }

View File

@ -38,6 +38,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private AdminGetUsersAdapter adapter; private AdminGetUsersAdapter adapter;
private RecyclerView mRecyclerView; private RecyclerView mRecyclerView;
private TextView noDataUsers; private TextView noDataUsers;
@ -52,8 +53,9 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -71,7 +73,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL); DividerItemDecoration.VERTICAL);
@ -84,13 +86,13 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
@Override @Override
public void run() { public void run() {
swipeRefresh.setRefreshing(false); swipeRefresh.setRefreshing(false);
AdminGetUsersViewModel.loadUsersList(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken)); AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
} }
}, 500); }, 500);
} }
}); });
fetchDataAsync(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken)); fetchDataAsync(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
} }
@ -101,7 +103,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() { usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
@Override @Override
public void onChanged(@Nullable List<UserInfo> usersListMain) { public void onChanged(@Nullable List<UserInfo> usersListMain) {
adapter = new AdminGetUsersAdapter(getApplicationContext(), usersListMain); adapter = new AdminGetUsersAdapter(ctx, usersListMain);
if(adapter.getItemCount() > 0) { if(adapter.getItemCount() > 0) {
mRecyclerView.setVisibility(View.VISIBLE); mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(adapter); mRecyclerView.setAdapter(adapter);
@ -130,7 +132,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
public void run() { public void run() {
if(searchFilter) { if(searchFilter) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getApplicationContext())); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
inflater.inflate(R.menu.search_menu, menu); inflater.inflate(R.menu.search_menu, menu);

View File

@ -19,7 +19,7 @@ import org.mian.gitnex.util.TinyDB;
* Author M M Arif * Author M M Arif
*/ */
@AcraNotification(resIcon = R.mipmap.app_logo, @AcraNotification(resIcon = R.drawable.gitnex_transparent,
resTitle = R.string.crashTitle, resTitle = R.string.crashTitle,
resChannelName = R.string.setCrashReports, resChannelName = R.string.setCrashReports,
resText = R.string.crashMessage) resText = R.string.crashMessage)
@ -31,24 +31,29 @@ public abstract class BaseActivity extends AppCompatActivity {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(getApplicationContext());
if(tinyDb.getInt("themeId") == 1) { switch(tinyDb.getInt("themeId")) {
setTheme(R.style.AppThemeLight);
}
else if(tinyDb.getInt("themeId") == 2) {
boolean timeSetterFlag = TimeHelper.timeBetweenHours(18, 6); // 6pm to 6am case 1:
if(timeSetterFlag) {
setTheme(R.style.AppTheme);
}
else {
setTheme(R.style.AppThemeLight); setTheme(R.style.AppThemeLight);
} break;
case 2:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
setTheme(R.style.AppTheme);
}
else {
setTheme(R.style.AppThemeLight);
}
break;
default:
setTheme(R.style.AppTheme);
break;
} }
else {
setTheme(R.style.AppTheme); String appLocale = tinyDb.getString("locale");
} AppUtil.setAppLocale(getResources(), appLocale);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId()); setContentView(getLayoutResourceId());
@ -90,6 +95,14 @@ public abstract class BaseActivity extends AppCompatActivity {
tinyDb.putString("crashReportingEnabledInit", "yes"); 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));
}
if (tinyDb.getBoolean("crashReportingEnabled")) { if (tinyDb.getBoolean("crashReportingEnabled")) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this); CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);

View File

@ -1,5 +1,6 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
@ -13,312 +14,274 @@ import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.mikepenz.fastadapter.IItemAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.adapters.CommitsAdapter; import org.mian.gitnex.adapters.CommitsAdapter;
import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Commits; import org.mian.gitnex.models.Commits;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class CommitsActivity extends BaseActivity implements ItemFilterListener<CommitsAdapter> { public class CommitsActivity extends BaseActivity {
private View.OnClickListener onClickListener; final Context ctx = this;
private TextView noData; private Context appCtx;
private ProgressBar progressBar; private View.OnClickListener onClickListener;
private SwipeRefreshLayout swipeRefreshLayout; private TextView noData;
private String TAG = "CommitsActivity - "; private ProgressBar progressBar;
private int resultLimit = 50; private String TAG = "CommitsActivity";
private boolean loadNextFlag = false; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private int pageSize = 1;
private List<CommitsAdapter> items = new ArrayList<>(); private RecyclerView recyclerView;
private FastItemAdapter<CommitsAdapter> fastItemAdapter; private List<Commits> commitsList;
private ItemAdapter footerAdapter; private CommitsAdapter adapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener; private ApiInterface api;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId() {
return R.layout.activity_commits;
}
@Override return R.layout.activity_commits;
public void onCreate(Bundle savedInstanceState) { }
super.onCreate(savedInstanceState); @Override
Toolbar toolbar = findViewById(R.id.toolbar); public void onCreate(Bundle savedInstanceState) {
setSupportActionBar(toolbar);
TinyDB tinyDb = new TinyDB(getApplicationContext()); super.onCreate(savedInstanceState);
final String instanceUrl = tinyDb.getString("instanceUrl"); appCtx = getApplicationContext();
final String loginUid = tinyDb.getString("loginUid"); Toolbar toolbar = findViewById(R.id.toolbar);
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); setSupportActionBar(toolbar);
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
String branchName = getIntent().getStringExtra("branchName"); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
TextView toolbar_title = findViewById(R.id.toolbar_title); String branchName = getIntent().getStringExtra("branchName");
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
toolbar_title.setText(branchName);
ImageView closeActivity = findViewById(R.id.close); TextView toolbar_title = findViewById(R.id.toolbar_title);
noData = findViewById(R.id.noDataCommits); toolbar_title.setMovementMethod(new ScrollingMovementMethod());
progressBar = findViewById(R.id.progress_bar); toolbar_title.setText(branchName);
swipeRefreshLayout = findViewById(R.id.pullToRefresh);
RecyclerView recyclerView = findViewById(R.id.recyclerView); ImageView closeActivity = findViewById(R.id.close);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); noData = findViewById(R.id.noDataCommits);
recyclerView.setHasFixedSize(true); progressBar = findViewById(R.id.progress_bar);
SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
fastItemAdapter = new FastItemAdapter<>(); // if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances)
fastItemAdapter.withSelectable(true); if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
footerAdapter = items(); recyclerView = findViewById(R.id.recyclerView);
//noinspection unchecked commitsList = new ArrayList<>();
fastItemAdapter.addAdapter(1, footerAdapter);
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<CommitsAdapter>) (item, constraint) -> item.getCommitTitle().toLowerCase().contains(Objects.requireNonNull(constraint).toString().toLowerCase())); swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
fastItemAdapter.getItemFilter().withItemFilterListener(this); swipeRefresh.setRefreshing(false);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName);
adapter.notifyDataChanged();
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); }, 200));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(fastItemAdapter);
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) { adapter = new CommitsAdapter(ctx, commitsList);
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
@Override if(commitsList.size() == resultLimit || pageSize == resultLimit) {
public void onLoadMore(final int currentPage) {
loadNext(instanceUrl, instanceToken, repoOwner, repoName, currentPage, branchName); int page = (commitsList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, branchName);
} }
}; }));
swipeRefreshLayout.setOnRefreshListener(() -> { recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
recyclerView.setAdapter(adapter);
progressBar.setVisibility(View.VISIBLE); api = AppApiService.createService(ApiInterface.class, instanceUrl, ctx);
fastItemAdapter.clear(); loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName);
endlessRecyclerOnScrollListener.resetPageCount();
swipeRefreshLayout.setRefreshing(false);
}); }
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener); private void loadInitial(String token, String repoOwner, String repoName, String branchName) {
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, branchName); Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, 1, branchName);
assert savedInstanceState != null; call.enqueue(new Callback<List<Commits>>() {
fastItemAdapter.withSavedInstanceState(savedInstanceState);
} @Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String branchName) { if(response.isSuccessful()) {
Call<List<Commits>> call = RetrofitClient assert response.body() != null;
.getInstance(instanceUrl, getApplicationContext()) if(response.body().size() > 0) {
.getApiInterface()
.getRepositoryCommits(token, repoOwner, repoName, 1, branchName);
call.enqueue(new Callback<List<Commits>>() { commitsList.clear();
commitsList.addAll(response.body());
adapter.notifyDataChanged();
noData.setVisibility(View.GONE);
@Override }
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) { else {
commitsList.clear();
adapter.notifyDataChanged();
noData.setVisibility(View.VISIBLE);
}
if (response.isSuccessful()) { progressBar.setVisibility(View.GONE);
assert response.body() != null; }
else {
if(response.body().size() > 0) { Log.e(TAG, String.valueOf(response.code()));
if(response.body().size() == resultLimit) { }
loadNextFlag = true;
}
for (int i = 0; i < response.body().size(); i++) { }
items.add(new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(), response.body().get(i).getHtml_url(), @Override
response.body().get(i).getCommit().getCommitter().getName(), response.body().get(i).getCommit().getCommitter().getDate())); public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
} Log.e(TAG, t.toString());
}
fastItemAdapter.add(items); });
} }
else {
noData.setVisibility(View.VISIBLE); private void loadMore(String token, String repoOwner, String repoName, final int page, String branchName) {
} //add loading progress view
commitsList.add(new Commits("load"));
adapter.notifyItemInserted((commitsList.size() - 1));
progressBar.setVisibility(View.GONE); Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, page, branchName);
} call.enqueue(new Callback<List<Commits>>() {
else {
Log.e(TAG, String.valueOf(response.code())); @Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
} if(response.isSuccessful()) {
} //remove loading view
commitsList.remove(commitsList.size() - 1);
@Override List<Commits> result = response.body();
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString()); assert result != null;
if(result.size() > 0) {
} pageSize = result.size();
commitsList.addAll(result);
}); }
else {
} Toasty.info(ctx, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, final int currentPage, String branchName) { }
footerAdapter.clear(); adapter.notifyDataChanged();
//noinspection unchecked
footerAdapter.add(new ProgressItem().withEnabled(false));
Handler handler = new Handler();
handler.postDelayed(() -> { }
else {
Call<List<Commits>> call = RetrofitClient Log.e(TAG, String.valueOf(response.code()));
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getRepositoryCommits(token, repoOwner, repoName, currentPage + 1, branchName);
call.enqueue(new Callback<List<Commits>>() { }
@Override }
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
if (response.isSuccessful()) { @Override
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
assert response.body() != null; Log.e(TAG, t.toString());
if (response.body().size() > 0) { }
loadNextFlag = response.body().size() == resultLimit; });
for (int i = 0; i < response.body().size(); i++) { }
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(), @Override
response.body().get(i).getHtml_url(), response.body().get(i).getCommit().getCommitter().getName(), public boolean onCreateOptionsMenu(Menu menu) {
response.body().get(i).getCommit().getCommitter().getDate()));
} MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
footerAdapter.clear(); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
} searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
else {
footerAdapter.clear(); @Override
} public boolean onQueryTextSubmit(String query) {
progressBar.setVisibility(View.GONE); return false;
}
} @Override
else { public boolean onQueryTextChange(String newText) {
Log.e(TAG, String.valueOf(response.code())); filter(newText);
return true;
}
} });
} return super.onCreateOptionsMenu(menu);
@Override }
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString()); private void filter(String text) {
} List<Commits> arr = new ArrayList<>();
}); for(Commits d : commitsList) {
if(d.getCommit().getMessage().toLowerCase().contains(text) || d.getSha().toLowerCase().contains(text)) {
arr.add(d);
}
}
}, 1000); adapter.updateList(arr);
}
if(!loadNextFlag) { private void initCloseListener() {
footerAdapter.clear(); onClickListener = view -> {
getIntent().removeExtra("branchName");
} finish();
};
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
fastItemAdapter.filter(newText);
return true;
}
});
endlessRecyclerOnScrollListener.enable();
return super.onCreateOptionsMenu(menu);
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<CommitsAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}
@Override
public void onReset() {
endlessRecyclerOnScrollListener.enable();
}
private void initCloseListener() {
onClickListener = view -> {
getIntent().removeExtra("branchName");
finish();
};
}
} }

View File

@ -13,6 +13,7 @@ import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
@ -45,6 +46,7 @@ public class CreateFileActivity extends BaseActivity {
private EditText newFileCommitMessage; private EditText newFileCommitMessage;
private Spinner newFileBranchesSpinner; private Spinner newFileBranchesSpinner;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
List<Branches> branchesList = new ArrayList<>(); List<Branches> branchesList = new ArrayList<>();
@ -57,12 +59,13 @@ public class CreateFileActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -76,6 +79,8 @@ public class CreateFileActivity extends BaseActivity {
newFileContent = findViewById(R.id.newFileContent); newFileContent = findViewById(R.id.newFileContent);
newFileBranchName = findViewById(R.id.newFileBranchName); newFileBranchName = findViewById(R.id.newFileBranchName);
newFileCommitMessage = findViewById(R.id.newFileCommitMessage); newFileCommitMessage = findViewById(R.id.newFileCommitMessage);
TextView branchNameId = findViewById(R.id.branchNameId);
TextView branchNameHintText = findViewById(R.id.branchNameHintText);
newFileName.requestFocus(); newFileName.requestFocus();
assert imm != null; assert imm != null;
@ -99,13 +104,18 @@ public class CreateFileActivity extends BaseActivity {
View arg1, int arg2, long arg3) View arg1, int arg2, long arg3)
{ {
Branches bModelValue = (Branches) newFileBranchesSpinner.getSelectedItem(); Branches bModelValue = (Branches) newFileBranchesSpinner.getSelectedItem();
Log.i("bModelSelected", bModelValue.toString());
if(bModelValue.toString().equals("No branch")) { if(bModelValue.toString().equals("No branch")) {
newFileBranchName.setEnabled(true); newFileBranchName.setEnabled(true);
newFileBranchName.setVisibility(View.VISIBLE);
branchNameId.setVisibility(View.VISIBLE);
branchNameHintText.setVisibility(View.VISIBLE);
} }
else { else {
newFileBranchName.setEnabled(false); newFileBranchName.setEnabled(false);
newFileBranchName.setVisibility(View.GONE);
branchNameId.setVisibility(View.GONE);
branchNameHintText.setVisibility(View.GONE);
newFileBranchName.setText(""); newFileBranchName.setText("");
} }
@ -132,17 +142,13 @@ public class CreateFileActivity extends BaseActivity {
} }
private View.OnClickListener createFileListener = new View.OnClickListener() { private View.OnClickListener createFileListener = v -> processNewFile();
public void onClick(View v) {
processNewFile();
}
};
private void processNewFile() { private void processNewFile() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -160,14 +166,14 @@ public class CreateFileActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) { if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.newFileRequiredFields)); Toasty.info(ctx, getString(R.string.newFileRequiredFields));
return; return;
} }
@ -175,13 +181,13 @@ public class CreateFileActivity extends BaseActivity {
if(currentBranch.toString().equals("No branch")) { if(currentBranch.toString().equals("No branch")) {
if(newFileBranchName_.equals("")) { if(newFileBranchName_.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.newFileRequiredFieldNewBranchName)); Toasty.info(ctx, getString(R.string.newFileRequiredFieldNewBranchName));
return; return;
} }
else { else {
if(!appUtil.checkStringsWithDash(newFileBranchName_)) { if(!appUtil.checkStringsWithDash(newFileBranchName_)) {
Toasty.info(getApplicationContext(), getString(R.string.newFileInvalidBranchName)); Toasty.info(ctx, getString(R.string.newFileInvalidBranchName));
return; return;
} }
@ -191,13 +197,13 @@ public class CreateFileActivity extends BaseActivity {
if(appUtil.charactersLength(newFileCommitMessage_) > 255) { if(appUtil.charactersLength(newFileCommitMessage_) > 255) {
Toasty.info(getApplicationContext(), getString(R.string.newFileCommitMessageError)); Toasty.info(ctx, getString(R.string.newFileCommitMessageError));
} }
else { else {
disableProcessButton(); disableProcessButton();
createNewFile(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newFileName_, appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString()); createNewFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newFileName_, appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString());
} }
@ -214,7 +220,7 @@ public class CreateFileActivity extends BaseActivity {
} }
Call<JsonElement> call = RetrofitClient Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr); .createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr);
@ -226,7 +232,7 @@ public class CreateFileActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.newFileSuccessMessage)); Toasty.info(ctx, getString(R.string.newFileSuccessMessage));
finish(); finish();
} }
@ -243,11 +249,11 @@ public class CreateFileActivity extends BaseActivity {
if(response.code() == 404) { if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.apiNotFound)); Toasty.info(ctx, getString(R.string.apiNotFound));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.orgCreatedError)); Toasty.info(ctx, getString(R.string.orgCreatedError));
} }
} }
@ -266,9 +272,9 @@ public class CreateFileActivity extends BaseActivity {
private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
Call<List<Branches>> call = RetrofitClient Call<List<Branches>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getBranches(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); .getBranches(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Branches>>() { call.enqueue(new Callback<List<Branches>>() {
@ -293,7 +299,7 @@ public class CreateFileActivity extends BaseActivity {
} }
} }
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(getApplicationContext(), ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateFileActivity.this,
R.layout.spinner_item, branchesList); R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
@ -314,12 +320,7 @@ public class CreateFileActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() { onClickListener = view -> finish();
@Override
public void onClick(View view) {
finish();
}
};
} }
private void disableProcessButton() { private void disableProcessButton() {

View File

@ -28,6 +28,8 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.MultiSelectDialog; import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.Labels; import org.mian.gitnex.models.Labels;
@ -61,6 +63,8 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private boolean assigneesFlag; private boolean assigneesFlag;
private boolean labelsFlag; private boolean labelsFlag;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
List<Milestones> milestonesList = new ArrayList<>(); List<Milestones> milestonesList = new ArrayList<>();
ArrayList<MultiSelectModel> listOfAssignees = new ArrayList<>(); ArrayList<MultiSelectModel> listOfAssignees = new ArrayList<>();
@ -74,13 +78,15 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String loginFullName = tinyDb.getString("userFullname"); final String loginFullName = tinyDb.getString("userFullname");
@ -90,6 +96,11 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
final String repoName = parts[1]; final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); 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 = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
assigneesList = findViewById(R.id.newIssueAssigneesList); assigneesList = findViewById(R.id.newIssueAssigneesList);
newIssueLabels = findViewById(R.id.newIssueLabels); newIssueLabels = findViewById(R.id.newIssueLabels);
@ -117,7 +128,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner); newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner);
newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP); newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid); getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit);
getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid); getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName); getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName);
@ -142,8 +153,8 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private void processNewIssue() { private void processNewIssue() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -164,21 +175,21 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (newIssueTitleForm.equals("")) { if (newIssueTitleForm.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty)); Toasty.info(ctx, getString(R.string.issueTitleEmpty));
return; return;
} }
/*if (newIssueDescriptionForm.equals("")) { /*if (newIssueDescriptionForm.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty)); Toasty.info(ctx, getString(R.string.issueDescriptionEmpty));
return; return;
}*/ }*/
@ -217,7 +228,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
public void loadCollaboratorsList() { public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -228,9 +239,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
final String repoName = parts[1]; final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -272,9 +283,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
Call<JsonElement> call3; Call<JsonElement> call3;
call3 = RetrofitClient call3 = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createNewIssueJson); .createNewIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, createNewIssueJson);
call3.enqueue(new Callback<JsonElement>() { call3.enqueue(new Callback<JsonElement>() {
@ -285,10 +296,10 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
if(response2.code() == 201) { if(response2.code() == 201) {
//Log.i("isSuccessful1", String.valueOf(response2.body())); //Log.i("isSuccessful1", String.valueOf(response2.body()));
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
Toasty.info(getApplicationContext(), getString(R.string.issueCreated)); Toasty.info(ctx, getString(R.string.issueCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -306,7 +317,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.issueCreatedError)); Toasty.info(ctx, getString(R.string.issueCreatedError));
enableProcessButton(); enableProcessButton();
//Log.i("isSuccessful2", String.valueOf(response2.body())); //Log.i("isSuccessful2", String.valueOf(response2.body()));
@ -332,13 +343,13 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
}; };
} }
private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) {
String msState = "open"; String msState = "open";
Call<List<Milestones>> call = RetrofitClient Call<List<Milestones>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState); .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState);
call.enqueue(new Callback<List<Milestones>>() { call.enqueue(new Callback<List<Milestones>>() {
@ -367,7 +378,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
} }
} }
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(getApplicationContext(), ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreateIssueActivity.this,
R.layout.spinner_item, milestonesList); R.layout.spinner_item, milestonesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
@ -390,9 +401,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, String loginFullName) { private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, String loginFullName) {
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
listOfAssignees.add(new MultiSelectModel(-1, loginFullName)); listOfAssignees.add(new MultiSelectModel(-1, loginFullName));
@ -462,9 +473,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
Call<List<Labels>> call = RetrofitClient Call<List<Labels>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); .getlabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Labels>>() { call.enqueue(new Callback<List<Labels>>() {
@ -530,7 +541,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog"); multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog");
} }
else { else {
Toasty.info(getApplicationContext(), getResources().getString(R.string.noAssigneesFound)); Toasty.info(ctx, getResources().getString(R.string.noAssigneesFound));
} }
} }
else if (v == newIssueLabels) { else if (v == newIssueLabels) {
@ -538,7 +549,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels"); multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels");
} }
else { else {
Toasty.info(getApplicationContext(), getResources().getString(R.string.noLabelsFound)); Toasty.info(ctx, getResources().getString(R.string.noLabelsFound));
} }
} }
else if (v == newIssueDueDate) { else if (v == newIssueDueDate) {

View File

@ -41,6 +41,7 @@ public class CreateLabelActivity extends BaseActivity {
private EditText labelName; private EditText labelName;
private Button createLabelButton; private Button createLabelButton;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -49,11 +50,13 @@ public class CreateLabelActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -70,7 +73,7 @@ public class CreateLabelActivity extends BaseActivity {
} }
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
colorPicker = findViewById(R.id.colorPicker); colorPicker = findViewById(R.id.colorPicker);
@ -150,8 +153,8 @@ public class CreateLabelActivity extends BaseActivity {
private void processUpdateLabel() { private void processUpdateLabel() {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
@ -173,21 +176,21 @@ public class CreateLabelActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(updateLabelName.equals("")) { if(updateLabelName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError)); Toasty.info(ctx, getString(R.string.labelEmptyError));
return; return;
} }
if(!appUtil.checkStrings(updateLabelName)) { if(!appUtil.checkStrings(updateLabelName)) {
Toasty.info(getApplicationContext(), getString(R.string.labelNameError)); Toasty.info(ctx, getString(R.string.labelNameError));
return; return;
} }
@ -199,9 +202,9 @@ public class CreateLabelActivity extends BaseActivity {
private void processCreateLabel() { private void processCreateLabel() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -213,7 +216,7 @@ public class CreateLabelActivity extends BaseActivity {
String newLabelName = labelName.getText().toString(); String newLabelName = labelName.getText().toString();
String newLabelColor; String newLabelColor;
if(tinyDb.getString("labelColor").isEmpty()) { if(tinyDb.getString("labelColor").isEmpty()) {
newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(getApplicationContext(), R.color.releasePre))); newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(ctx, R.color.releasePre)));
} }
else { else {
newLabelColor = tinyDb.getString("labelColor"); newLabelColor = tinyDb.getString("labelColor");
@ -221,21 +224,21 @@ public class CreateLabelActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newLabelName.equals("")) { if(newLabelName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError)); Toasty.info(ctx, getString(R.string.labelEmptyError));
return; return;
} }
if(!appUtil.checkStrings(newLabelName)) { if(!appUtil.checkStrings(newLabelName)) {
Toasty.info(getApplicationContext(), getString(R.string.labelNameError)); Toasty.info(ctx, getString(R.string.labelNameError));
return; return;
} }
@ -248,14 +251,14 @@ public class CreateLabelActivity extends BaseActivity {
private void createNewLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String newLabelName, String newLabelColor, String loginUid) { private void createNewLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String newLabelName, String newLabelColor, String loginUid) {
CreateLabel createLabelFunc = new CreateLabel(newLabelName, newLabelColor); CreateLabel createLabelFunc = new CreateLabel(newLabelName, newLabelColor);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<CreateLabel> call; Call<CreateLabel> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createLabelFunc); .createLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, createLabelFunc);
call.enqueue(new Callback<CreateLabel>() { call.enqueue(new Callback<CreateLabel>() {
@ -264,7 +267,7 @@ public class CreateLabelActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.info(getApplicationContext(), getString(R.string.labelCreated)); Toasty.info(ctx, getString(R.string.labelCreated));
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putBoolean("labelsRefresh", true); tinyDb.putBoolean("labelsRefresh", true);
finish(); finish();
@ -283,7 +286,7 @@ public class CreateLabelActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }
@ -302,14 +305,14 @@ public class CreateLabelActivity extends BaseActivity {
private void patchLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId, String loginUid) { private void patchLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId, String loginUid) {
CreateLabel createLabelFunc = new CreateLabel(updateLabelName, updateLabelColor); CreateLabel createLabelFunc = new CreateLabel(updateLabelName, updateLabelColor);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<CreateLabel> call; Call<CreateLabel> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.patchLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc); .patchLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc);
call.enqueue(new Callback<CreateLabel>() { call.enqueue(new Callback<CreateLabel>() {
@ -319,7 +322,7 @@ public class CreateLabelActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 200) { if(response.code() == 200) {
Toasty.info(getApplicationContext(), getString(R.string.labelUpdated)); Toasty.info(ctx, getString(R.string.labelUpdated));
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putBoolean("labelsRefresh", true); tinyDb.putBoolean("labelsRefresh", true);
tinyDb.putString("labelColorDefault", ""); tinyDb.putString("labelColorDefault", "");
@ -345,7 +348,7 @@ public class CreateLabelActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putString("labelColorDefault", ""); tinyDb.putString("labelColorDefault", "");
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }
@ -380,9 +383,9 @@ public class CreateLabelActivity extends BaseActivity {
Call<Labels> call; Call<Labels> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.deleteLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId); .deleteLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, labelId);
call.enqueue(new Callback<Labels>() { call.enqueue(new Callback<Labels>() {
@ -392,8 +395,8 @@ public class CreateLabelActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 204) { if(response.code() == 204) {
Toasty.info(getApplicationContext(), getString(R.string.labelDeleteText)); Toasty.info(ctx, getString(R.string.labelDeleteText));
LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, getApplicationContext()); LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, ctx);
getIntent().removeExtra("labelAction"); getIntent().removeExtra("labelAction");
getIntent().removeExtra("labelId"); getIntent().removeExtra("labelId");
@ -409,7 +412,7 @@ public class CreateLabelActivity extends BaseActivity {
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.labelDeleteErrorText)); Toasty.info(ctx, getString(R.string.labelDeleteErrorText));
} }

View File

@ -18,7 +18,7 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.VersionCheck; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
@ -37,6 +37,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
private EditText milestoneDescription; private EditText milestoneDescription;
private Button createNewMilestoneButton; private Button createNewMilestoneButton;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -45,9 +46,11 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -89,9 +92,9 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
private void processNewMilestone() { private void processNewMilestone() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -107,14 +110,14 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newMilestoneTitle.equals("")) { if(newMilestoneTitle.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.milestoneNameErrorEmpty)); Toasty.info(ctx, getString(R.string.milestoneNameErrorEmpty));
return; return;
} }
@ -122,7 +125,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(!newMilestoneDescription.equals("")) { if(!newMilestoneDescription.equals("")) {
if (appUtil.charactersLength(newMilestoneDescription) > 255) { if (appUtil.charactersLength(newMilestoneDescription) > 255) {
Toasty.info(getApplicationContext(), getString(R.string.milestoneDescError)); Toasty.info(ctx, getString(R.string.milestoneDescError));
return; return;
} }
@ -131,14 +134,14 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
String finalMilestoneDueDate = null; String finalMilestoneDueDate = null;
if(!newMilestoneDueDate.isEmpty()) { if(!newMilestoneDueDate.isEmpty()) {
finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate))); finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate)));
} else if (VersionCheck.compareVersion("1.10.0", tinyDb.getString("giteaVersion")) > 1) { } else if (new Version(tinyDb.getString("giteaVersion")).less("1.10.0")) {
// if Gitea version is less than 1.10.0 DueDate is required // if Gitea version is less than 1.10.0 DueDate is required
Toasty.info(getApplicationContext(), getString(R.string.milestoneDateEmpty)); Toasty.info(ctx, getString(R.string.milestoneDateEmpty));
return; return;
} }
disableProcessButton(); disableProcessButton();
createNewMilestone(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate); createNewMilestone(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate);
} }
@ -149,7 +152,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
Call<Milestones> call; Call<Milestones> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createMilestone(token, repoOwner, repoName, createMilestone); .createMilestone(token, repoOwner, repoName, createMilestone);
@ -161,9 +164,9 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 201) { if(response.code() == 201) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("milestoneCreated", true); tinyDb.putBoolean("milestoneCreated", true);
Toasty.info(getApplicationContext(), getString(R.string.milestoneCreated)); Toasty.info(ctx, getString(R.string.milestoneCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -181,7 +184,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.milestoneCreatedError)); Toasty.info(ctx, getString(R.string.milestoneCreatedError));
} }

View File

@ -35,6 +35,7 @@ public class CreateNewUserActivity extends BaseActivity {
private EditText userPassword; private EditText userPassword;
private Button createUserButton; private Button createUserButton;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -45,8 +46,9 @@ public class CreateNewUserActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -78,9 +80,9 @@ public class CreateNewUserActivity extends BaseActivity {
private void processCreateNewUser() { private void processCreateNewUser() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -92,41 +94,41 @@ public class CreateNewUserActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) { if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.emptyFields)); Toasty.info(ctx, getString(R.string.emptyFields));
return; return;
} }
if(!appUtil.checkStrings(newFullName)) { if(!appUtil.checkStrings(newFullName)) {
Toasty.info(getApplicationContext(), getString(R.string.userInvalidFullName)); Toasty.info(ctx, getString(R.string.userInvalidFullName));
return; return;
} }
if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) { if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) {
Toasty.info(getApplicationContext(), getString(R.string.userInvalidUserName)); Toasty.info(ctx, getString(R.string.userInvalidUserName));
return; return;
} }
if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
Toasty.info(getApplicationContext(), getString(R.string.userInvalidEmail)); Toasty.info(ctx, getString(R.string.userInvalidEmail));
return; return;
} }
disableProcessButton(); disableProcessButton();
createNewUser(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newFullName, newUserName, newUserEmail, newUserPassword); createNewUser(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newFullName, newUserName, newUserEmail, newUserPassword);
} }
@ -137,7 +139,7 @@ public class CreateNewUserActivity extends BaseActivity {
Call<UserInfo> call; Call<UserInfo> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewUser(instanceToken, createUser); .createNewUser(instanceToken, createUser);
@ -148,7 +150,7 @@ public class CreateNewUserActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.info(getApplicationContext(), getString(R.string.userCreatedText)); Toasty.info(ctx, getString(R.string.userCreatedText));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -183,7 +185,7 @@ public class CreateNewUserActivity extends BaseActivity {
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }

View File

@ -34,6 +34,7 @@ public class CreateOrganizationActivity extends BaseActivity {
private EditText orgName; private EditText orgName;
private EditText orgDesc; private EditText orgDesc;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -42,9 +43,11 @@ public class CreateOrganizationActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -94,9 +97,9 @@ public class CreateOrganizationActivity extends BaseActivity {
private void processNewOrganization() { private void processNewOrganization() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -106,7 +109,7 @@ public class CreateOrganizationActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
@ -114,7 +117,7 @@ public class CreateOrganizationActivity extends BaseActivity {
if(!newOrgDesc.equals("")) { if(!newOrgDesc.equals("")) {
if (appUtil.charactersLength(newOrgDesc) > 255) { if (appUtil.charactersLength(newOrgDesc) > 255) {
Toasty.info(getApplicationContext(), getString(R.string.orgDescError)); Toasty.info(ctx, getString(R.string.orgDescError));
return; return;
} }
@ -122,18 +125,18 @@ public class CreateOrganizationActivity extends BaseActivity {
if(newOrgName.equals("")) { if(newOrgName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.orgNameErrorEmpty)); Toasty.info(ctx, getString(R.string.orgNameErrorEmpty));
} }
else if(!appUtil.checkStrings(newOrgName)) { else if(!appUtil.checkStrings(newOrgName)) {
Toasty.info(getApplicationContext(), getString(R.string.orgNameErrorInvalid)); Toasty.info(ctx, getString(R.string.orgNameErrorInvalid));
} }
else { else {
disableProcessButton(); disableProcessButton();
createNewOrganization(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newOrgName, newOrgDesc); createNewOrganization(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newOrgName, newOrgDesc);
} }
@ -144,7 +147,7 @@ public class CreateOrganizationActivity extends BaseActivity {
UserOrganizations createOrganization = new UserOrganizations(orgName, null, orgDesc, null, null); UserOrganizations createOrganization = new UserOrganizations(orgName, null, orgDesc, null, null);
Call<UserOrganizations> call = RetrofitClient Call<UserOrganizations> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewOrganization(token, createOrganization); .createNewOrganization(token, createOrganization);
@ -155,10 +158,10 @@ public class CreateOrganizationActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("orgCreated", true); tinyDb.putBoolean("orgCreated", true);
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.orgCreated)); Toasty.info(ctx, getString(R.string.orgCreated));
finish(); finish();
} }
@ -174,24 +177,24 @@ public class CreateOrganizationActivity extends BaseActivity {
else if(response.code() == 409) { else if(response.code() == 409) {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.orgExistsError)); Toasty.info(ctx, getString(R.string.orgExistsError));
} }
else if(response.code() == 422) { else if(response.code() == 422) {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.orgExistsError)); Toasty.info(ctx, getString(R.string.orgExistsError));
} }
else { else {
if(response.code() == 404) { if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.apiNotFound)); Toasty.info(ctx, getString(R.string.apiNotFound));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.orgCreatedError)); Toasty.info(ctx, getString(R.string.orgCreatedError));
} }
} }

View File

@ -45,6 +45,7 @@ public class CreateReleaseActivity extends BaseActivity {
private CheckBox releaseDraft; private CheckBox releaseDraft;
private Button createNewRelease; private Button createNewRelease;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
List<Branches> branchesList = new ArrayList<>(); List<Branches> branchesList = new ArrayList<>();
@ -57,12 +58,13 @@ public class CreateReleaseActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -87,7 +89,7 @@ public class CreateReleaseActivity extends BaseActivity {
releaseBranch = findViewById(R.id.releaseBranch); releaseBranch = findViewById(R.id.releaseBranch);
releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP); releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getBranches(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); getBranches(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
@ -123,9 +125,9 @@ public class CreateReleaseActivity extends BaseActivity {
private void processNewRelease() { private void processNewRelease() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -143,27 +145,27 @@ public class CreateReleaseActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newReleaseTagName.equals("")) { if(newReleaseTagName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.tagNameErrorEmpty)); Toasty.info(ctx, getString(R.string.tagNameErrorEmpty));
return; return;
} }
if(newReleaseTitle.equals("")) { if(newReleaseTitle.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.titleErrorEmpty)); Toasty.info(ctx, getString(R.string.titleErrorEmpty));
return; return;
} }
disableProcessButton(); disableProcessButton();
createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, newReleaseBranch, newReleaseType, newReleaseDraft); createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, newReleaseBranch, newReleaseType, newReleaseDraft);
} }
@ -174,7 +176,7 @@ public class CreateReleaseActivity extends BaseActivity {
Call<Releases> call; Call<Releases> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewRelease(token, repoOwner, repoName, createReleaseJson); .createNewRelease(token, repoOwner, repoName, createReleaseJson);
@ -185,9 +187,9 @@ public class CreateReleaseActivity extends BaseActivity {
if (response.code() == 201) { if (response.code() == 201) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("updateReleases", true); tinyDb.putBoolean("updateReleases", true);
Toasty.info(getApplicationContext(), getString(R.string.releaseCreatedText)); Toasty.info(ctx, getString(R.string.releaseCreatedText));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -234,7 +236,7 @@ public class CreateReleaseActivity extends BaseActivity {
private void getBranches(String instanceUrl, String instanceToken, final String repoOwner, final String repoName) { private void getBranches(String instanceUrl, String instanceToken, final String repoOwner, final String repoName) {
Call<List<Branches>> call = RetrofitClient Call<List<Branches>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getBranches(instanceToken, repoOwner, repoName); .getBranches(instanceToken, repoOwner, repoName);
@ -260,7 +262,7 @@ public class CreateReleaseActivity extends BaseActivity {
} }
} }
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(getApplicationContext(), ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateReleaseActivity.this,
R.layout.spinner_item, branchesList); R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);

View File

@ -45,6 +45,7 @@ public class CreateRepoActivity extends BaseActivity {
private EditText repoDesc; private EditText repoDesc;
private CheckBox repoAccess; private CheckBox repoAccess;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
List<OrgOwner> organizationsList = new ArrayList<>(); List<OrgOwner> organizationsList = new ArrayList<>();
@ -59,11 +60,13 @@ public class CreateRepoActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(ctx);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String userLogin = tinyDb.getString("userLogin"); final String userLogin = tinyDb.getString("userLogin");
@ -85,7 +88,7 @@ public class CreateRepoActivity extends BaseActivity {
spinner = findViewById(R.id.ownerSpinner); spinner = findViewById(R.id.ownerSpinner);
spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP); spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getOrganizations(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), userLogin); getOrganizations(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), userLogin);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
@ -121,9 +124,9 @@ public class CreateRepoActivity extends BaseActivity {
private void processNewRepo() { private void processNewRepo() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -135,7 +138,7 @@ public class CreateRepoActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
@ -143,7 +146,7 @@ public class CreateRepoActivity extends BaseActivity {
if(!newRepoDesc.equals("")) { if(!newRepoDesc.equals("")) {
if (appUtil.charactersLength(newRepoDesc) > 255) { if (appUtil.charactersLength(newRepoDesc) > 255) {
Toasty.info(getApplicationContext(), getString(R.string.repoDescError)); Toasty.info(ctx, getString(R.string.repoDescError));
return; return;
} }
@ -151,28 +154,28 @@ public class CreateRepoActivity extends BaseActivity {
if(newRepoName.equals("")) { if(newRepoName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorEmpty)); Toasty.info(ctx, getString(R.string.repoNameErrorEmpty));
} }
else if(!appUtil.checkStrings(newRepoName)) { else if(!appUtil.checkStrings(newRepoName)) {
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorInvalid)); Toasty.info(ctx, getString(R.string.repoNameErrorInvalid));
} }
else if (reservedRepoNames.contains(newRepoName)) { else if (reservedRepoNames.contains(newRepoName)) {
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorReservedName)); Toasty.info(ctx, getString(R.string.repoNameErrorReservedName));
} }
else if (reservedRepoPatterns.matcher(newRepoName).find()) { else if (reservedRepoPatterns.matcher(newRepoName).find()) {
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorReservedPatterns)); Toasty.info(ctx, getString(R.string.repoNameErrorReservedPatterns));
} }
else { else {
disableProcessButton(); disableProcessButton();
createNewRepository(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess); createNewRepository(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess);
} }
} }
@ -185,7 +188,7 @@ public class CreateRepoActivity extends BaseActivity {
if(repoOwner.equals(loginUid)) { if(repoOwner.equals(loginUid)) {
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewUserRepository(token, createRepository); .createNewUserRepository(token, createRepository);
@ -193,7 +196,7 @@ public class CreateRepoActivity extends BaseActivity {
else { else {
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewUserOrgRepository(token, repoOwner, createRepository); .createNewUserOrgRepository(token, repoOwner, createRepository);
@ -206,9 +209,9 @@ public class CreateRepoActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("repoCreated", true); tinyDb.putBoolean("repoCreated", true);
Toasty.info(getApplicationContext(), getString(R.string.repoCreated)); Toasty.info(ctx, getString(R.string.repoCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
} }
@ -224,13 +227,13 @@ public class CreateRepoActivity extends BaseActivity {
else if(response.code() == 409) { else if(response.code() == 409) {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.repoExistsError)); Toasty.info(ctx, getString(R.string.repoExistsError));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.repoCreatedError)); Toasty.info(ctx, getString(R.string.repoCreatedError));
} }
@ -246,10 +249,10 @@ public class CreateRepoActivity extends BaseActivity {
private void getOrganizations(String instanceUrl, String instanceToken, final String userLogin) { private void getOrganizations(String instanceUrl, String instanceToken, final String userLogin) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
Call<List<OrgOwner>> call = RetrofitClient Call<List<OrgOwner>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getOrgOwners(instanceToken); .getOrgOwners(instanceToken);
@ -283,7 +286,7 @@ public class CreateRepoActivity extends BaseActivity {
} }
} }
ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(getApplicationContext(), ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(CreateRepoActivity.this,
R.layout.spinner_item, organizationsList); R.layout.spinner_item, organizationsList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);

View File

@ -33,6 +33,7 @@ import android.util.Log;
public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClickListener { public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClickListener {
final Context ctx = CreateTeamByOrgActivity.this; final Context ctx = CreateTeamByOrgActivity.this;
private Context appCtx;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TextView teamName; private TextView teamName;
private TextView teamDesc; private TextView teamDesc;
@ -73,9 +74,11 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -247,13 +250,13 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
private void processCreateTeam() { private void processCreateTeam() {
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String orgName = tinyDb.getString("orgName");; final String orgName = tinyDb.getString("orgName");;
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
String newTeamName = teamName.getText().toString(); String newTeamName = teamName.getText().toString();
String newTeamDesc = teamDesc.getText().toString(); String newTeamDesc = teamDesc.getText().toString();
String newTeamPermission = teamPermission.getText().toString().toLowerCase(); String newTeamPermission = teamPermission.getText().toString().toLowerCase();
@ -261,21 +264,21 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (newTeamName.equals("")) { if (newTeamName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.teamNameEmpty)); Toasty.info(ctx, getString(R.string.teamNameEmpty));
return; return;
} }
if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) { if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
Toasty.info(getApplicationContext(), getString(R.string.teamNameError)); Toasty.info(ctx, getString(R.string.teamNameError));
return; return;
} }
@ -283,12 +286,12 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(!newTeamDesc.equals("")) { if(!newTeamDesc.equals("")) {
if(!appUtil.checkStrings(newTeamDesc)) { if(!appUtil.checkStrings(newTeamDesc)) {
Toasty.info(getApplicationContext(), getString(R.string.teamDescError)); Toasty.info(ctx, getString(R.string.teamDescError));
return; return;
} }
if(newTeamDesc.length() > 100) { if(newTeamDesc.length() > 100) {
Toasty.info(getApplicationContext(), getString(R.string.teamDescLimit)); Toasty.info(ctx, getString(R.string.teamDescLimit));
return; return;
} }
@ -296,7 +299,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if (newTeamPermission.equals("")) { if (newTeamPermission.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.teamPermissionEmpty)); Toasty.info(ctx, getString(R.string.teamPermissionEmpty));
return; return;
} }
@ -318,9 +321,9 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
Call<Teams> call3; Call<Teams> call3;
call3 = RetrofitClient call3 = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createTeamsByOrg(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), orgName, createNewTeamJson); .createTeamsByOrg(Authorization.returnAuthentication(ctx, loginUid, instanceToken), orgName, createNewTeamJson);
call3.enqueue(new Callback<Teams>() { call3.enqueue(new Callback<Teams>() {
@ -330,10 +333,10 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(response2.isSuccessful()) { if(response2.isSuccessful()) {
if(response2.code() == 201) { if(response2.code() == 201) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("resumeTeams", true); tinyDb.putBoolean("resumeTeams", true);
Toasty.info(getApplicationContext(), getString(R.string.teamCreated)); Toasty.info(ctx, getString(R.string.teamCreated));
finish(); finish();
} }
@ -341,7 +344,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
} }
else if(response2.code() == 404) { else if(response2.code() == 404) {
Toasty.info(getApplicationContext(), getString(R.string.apiNotFound)); Toasty.info(ctx, getString(R.string.apiNotFound));
} }
else if(response2.code() == 401) { else if(response2.code() == 401) {
@ -354,7 +357,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.teamCreatedError)); Toasty.info(ctx, getString(R.string.teamCreatedError));
} }

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.activities;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
@ -20,6 +21,7 @@ import java.util.List;
public class CreditsActivity extends BaseActivity { public class CreditsActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -44,7 +46,7 @@ public class CreditsActivity extends BaseActivity {
RecyclerView mRecyclerView = findViewById(R.id.recyclerView); RecyclerView mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL); DividerItemDecoration.VERTICAL);

View File

@ -28,7 +28,9 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
@ -48,7 +50,9 @@ import java.util.List;
public class EditIssueActivity extends BaseActivity implements View.OnClickListener { public class EditIssueActivity extends BaseActivity implements View.OnClickListener {
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private EditText editIssueTitle; private EditText editIssueTitle;
private SocialAutoCompleteTextView editIssueDescription; private SocialAutoCompleteTextView editIssueDescription;
@ -70,10 +74,11 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -91,6 +96,11 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
editIssueDescription = findViewById(R.id.editIssueDescription); editIssueDescription = findViewById(R.id.editIssueDescription);
editIssueDueDate = findViewById(R.id.editIssueDueDate); editIssueDueDate = findViewById(R.id.editIssueDueDate);
// if gitea is 1.12 or higher use the new limit
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
editIssueTitle.requestFocus(); editIssueTitle.requestFocus();
assert imm != null; assert imm != null;
imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT); imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT);
@ -120,14 +130,14 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
disableProcessButton(); disableProcessButton();
getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex); getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit);
} }
public void loadCollaboratorsList() { public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -138,9 +148,9 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
final String repoName = parts[1]; final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -186,8 +196,8 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
private void processEditIssue() { private void processEditIssue() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -207,21 +217,21 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (editIssueTitleForm.equals("")) { if (editIssueTitleForm.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty)); Toasty.info(ctx, getString(R.string.issueTitleEmpty));
return; return;
} }
/*if (editIssueDescriptionForm.equals("")) { /*if (editIssueDescriptionForm.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty)); Toasty.info(ctx, getString(R.string.issueDescriptionEmpty));
return; return;
}*/ }*/
@ -240,14 +250,14 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int editIssueMilestoneId) { private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int editIssueMilestoneId) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
CreateIssue issueData = new CreateIssue(title, description, dueDate, editIssueMilestoneId); CreateIssue issueData = new CreateIssue(title, description, dueDate, editIssueMilestoneId);
Call<JsonElement> call = RetrofitClient Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.patchIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData); .patchIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData);
call.enqueue(new Callback<JsonElement>() { call.enqueue(new Callback<JsonElement>() {
@ -257,10 +267,10 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if(response.code() == 201) { if(response.code() == 201) {
if(tinyDb.getString("issueType").equals("pr")) { if(tinyDb.getString("issueType").equals("pr")) {
Toasty.info(getApplicationContext(), getString(R.string.editPrSuccessMessage)); Toasty.info(ctx, getString(R.string.editPrSuccessMessage));
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.editIssueSuccessMessage)); Toasty.info(ctx, getString(R.string.editIssueSuccessMessage));
} }
tinyDb.putBoolean("issueEdited", true); tinyDb.putBoolean("issueEdited", true);
@ -280,7 +290,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }
@ -326,12 +336,12 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex) { private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex, int resultLimit) {
Call<Issues> call = RetrofitClient Call<Issues> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex); .getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
call.enqueue(new Callback<Issues>() { call.enqueue(new Callback<Issues>() {
@ -353,9 +363,9 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if(response.body().getId() > 0) { if(response.body().getId() > 0) {
Call<List<Milestones>> call_ = RetrofitClient Call<List<Milestones>> call_ = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState); .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState);
final int finalMsId = msId; final int finalMsId = msId;
@ -388,7 +398,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
} }
ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(getApplicationContext(), ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(EditIssueActivity.this,
R.layout.spinner_item, milestonesList); R.layout.spinner_item, milestonesList);
adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item);
@ -432,7 +442,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }

View File

@ -1,15 +1,15 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.adapters.FilesDiffAdapter; import org.mian.gitnex.adapters.FilesDiffAdapter;
@ -34,8 +34,10 @@ public class FileDiffActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TextView toolbar_title; private TextView toolbar_title;
private RecyclerView mRecyclerView; private ListView mListView;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -46,10 +48,12 @@ public class FileDiffActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -60,11 +64,10 @@ public class FileDiffActivity extends BaseActivity {
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
toolbar_title = findViewById(R.id.toolbar_title); toolbar_title = findViewById(R.id.toolbar_title);
mRecyclerView = findViewById(R.id.recyclerView); mListView = findViewById(R.id.listView);
mProgressBar = findViewById(R.id.progress_bar); mProgressBar = findViewById(R.id.progress_bar);
mRecyclerView.setHasFixedSize(true); mListView.setDivider(null);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
toolbar_title.setText(R.string.processingText); toolbar_title.setText(R.string.processingText);
initCloseListener(); initCloseListener();
@ -81,7 +84,7 @@ public class FileDiffActivity extends BaseActivity {
private void getPullDiffContent(String instanceUrl, String owner, String repo, String filename) { private void getPullDiffContent(String instanceUrl, String owner, String repo, String filename) {
Call<ResponseBody> call = RetrofitClient Call<ResponseBody> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getWebInterface() .getWebInterface()
.getPullDiffContent(owner, repo, filename); .getPullDiffContent(owner, repo, filename);
@ -113,18 +116,18 @@ public class FileDiffActivity extends BaseActivity {
String[] fileContents_ = level2nd[1].split("@@"); // file info / content part String[] fileContents_ = level2nd[1].split("@@"); // file info / content part
String fileInfoFinal = fileContents_[0]; String fileInfoFinal = fileContents_[0];
String fileContentsFinal = (fileContents_[1]); StringBuilder fileContentsFinal = new StringBuilder(fileContents_[1]);
if(level2nd.length > 2) { if(level2nd.length > 2) {
for (int j = 2; j < level2nd.length; j++) { for (int j = 2; j < level2nd.length; j++) {
fileContentsFinal += (level2nd[j]); fileContentsFinal.append(level2nd[j]);
} }
} }
String fileExtension = FileUtils.getExtension(fileNameFinal); String fileExtension = FileUtils.getExtension(fileNameFinal);
String fileContentsFinalWithBlankLines = fileContentsFinal.replaceAll( ".*@@.*", "" ); String fileContentsFinalWithBlankLines = fileContentsFinal.toString().replaceAll( ".*@@.*", "" );
String fileContentsFinalWithoutBlankLines = fileContentsFinal.replaceAll( ".*@@.*(\r?\n|\r)?", "" ); String fileContentsFinalWithoutBlankLines = fileContentsFinal.toString().replaceAll( ".*@@.*(\r?\n|\r)?", "" );
fileContentsFinalWithoutBlankLines = fileContentsFinalWithoutBlankLines.replaceAll( ".*\\ No newline at end of file.*(\r?\n|\r)?", "" ); fileContentsFinalWithoutBlankLines = fileContentsFinalWithoutBlankLines.replaceAll( ".*\\ No newline at end of file.*(\r?\n|\r)?", "" );
fileContentsArray.add(new FileDiffView(fileNameFinal, appUtil.imageExtension(fileExtension), fileInfoFinal, fileContentsFinalWithoutBlankLines)); fileContentsArray.add(new FileDiffView(fileNameFinal, appUtil.imageExtension(fileExtension), fileInfoFinal, fileContentsFinalWithoutBlankLines));
@ -161,8 +164,8 @@ public class FileDiffActivity extends BaseActivity {
toolbar_title.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount))); toolbar_title.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount)));
} }
FilesDiffAdapter adapter = new FilesDiffAdapter(fileContentsArray, getApplicationContext()); FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, fileContentsArray);
mRecyclerView.setAdapter(adapter); mListView.setAdapter(adapter);
mProgressBar.setVisibility(View.GONE); mProgressBar.setVisibility(View.GONE);
@ -173,7 +176,7 @@ public class FileDiffActivity extends BaseActivity {
} }
else if(response.code() == 401) { else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(getApplicationContext(), getResources().getString(R.string.alertDialogTokenRevokedTitle), AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
@ -181,17 +184,17 @@ public class FileDiffActivity extends BaseActivity {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.info(getApplicationContext(), getApplicationContext().getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.info(getApplicationContext(), getApplicationContext().getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }

View File

@ -1,14 +1,13 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.Intent;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
@ -22,26 +21,25 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.github.barteksc.pdfviewer.PDFView; import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.util.FitPolicy; import com.github.barteksc.pdfviewer.util.FitPolicy;
import com.github.chrisbanes.photoview.PhotoView; import com.github.chrisbanes.photoview.PhotoView;
import com.pddstudio.highlightjs.HighlightJsView;
import com.pddstudio.highlightjs.models.Theme;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetFileViewerFragment; import org.mian.gitnex.fragments.BottomSheetFileViewerFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.highlightjs.HighlightJsView;
import org.mian.gitnex.helpers.highlightjs.models.Theme;
import org.mian.gitnex.models.Files; import org.mian.gitnex.models.Files;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Objects; import java.util.Objects;
@ -60,13 +58,13 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private HighlightJsView singleCodeContents; private HighlightJsView singleCodeContents;
private PhotoView imageView; private PhotoView imageView;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
private byte[] imageData; private byte[] imageData;
private PDFView pdfView; private PDFView pdfView;
private LinearLayout pdfViewFrame; private LinearLayout pdfViewFrame;
private byte[] decodedPdf; private byte[] decodedPdf;
private Boolean pdfNightMode; private Boolean pdfNightMode;
private static final int PERMISSION_REQUEST_CODE = 1;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId() {
@ -78,10 +76,12 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -131,9 +131,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) { private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<Files> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getSingleFileContents(token, owner, repo, filename); Call<Files> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getSingleFileContents(token, owner, repo, filename);
call.enqueue(new Callback<Files>() { call.enqueue(new Callback<Files>() {
@ -193,7 +193,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
singleCodeContents.setTheme(Theme.MONOKAI_SUBLIME); singleCodeContents.setTheme(Theme.MONOKAI_SUBLIME);
} }
singleCodeContents.setShowLineNumbers(true);
singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent())); singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent()));
} }
@ -257,7 +256,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
else { else {
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }
@ -302,21 +301,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
@Override @Override
public void onButtonClicked(String text) { public void onButtonClicked(String text) {
switch(text) { if("downloadFile".equals(text)) {
case "downloadFile":
if(Build.VERSION.SDK_INT >= 23) { requestFileDownload();
if(checkPermission()) {
requestFileDownload();
}
else {
requestPermission();
}
}
else {
requestFileDownload();
}
break;
} }
@ -324,72 +311,70 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private void requestFileDownload() { private void requestFileDownload() {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
if(!tinyDb.getString("downloadFileContents").isEmpty()) { if(!tinyDb.getString("downloadFileContents").isEmpty()) {
File outputFileName = new File(tinyDb.getString("downloadFileName")); int CREATE_REQUEST_CODE = 40;
final File downloadFilePath = new File(Environment.getExternalStorageDirectory().getPath() + "/Download/" + outputFileName.getName());
byte[] pdfAsBytes = Base64.decode(tinyDb.getString("downloadFileContents"), 0); File outputFileName = new File(tinyDb.getString("downloadFileName"));
FileOutputStream fileOutputStream = null;
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, outputFileName.getName());
startActivityForResult(intent, CREATE_REQUEST_CODE);
}
else {
Toasty.error(ctx, getString(R.string.waitLoadingDownloadFile));
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
final TinyDB tinyDb = new TinyDB(appCtx);
if (requestCode == 40 && resultCode == RESULT_OK) {
try { try {
fileOutputStream = new FileOutputStream(downloadFilePath, false); assert data != null;
Objects.requireNonNull(fileOutputStream).write(pdfAsBytes); Uri uri = data.getData();
fileOutputStream.flush();
fileOutputStream.close(); assert uri != null;
Toasty.info(getApplicationContext(), getString(R.string.downloadFileSaved)); OutputStream outputStream = getContentResolver().openOutputStream(uri);
byte[] dataAsBytes = Base64.decode(tinyDb.getString("downloadFileContents"), 0);
assert outputStream != null;
outputStream.write(dataAsBytes);
outputStream.close();
Toasty.info(ctx, getString(R.string.downloadFileSaved));
} }
catch(IOException e) { catch (IOException e) {
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage())); Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
} }
} }
else {
Toasty.error(getApplicationContext(), getString(R.string.waitLoadingDownloadFile));
}
} }
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch(requestCode) {
case PERMISSION_REQUEST_CODE:
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i("PermissionsCheck", "Permission Granted");
}
else {
Log.e("PermissionsCheck", "Permission Denied");
}
break;
}
}
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() { onClickListener = view -> {
@Override getIntent().removeExtra("singleFileName");
public void onClick(View view) { finish();
getIntent().removeExtra("singleFileName");
finish();
}
}; };
} }

File diff suppressed because it is too large Load Diff

View File

@ -2,28 +2,23 @@ package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import com.hendraanggrian.appcompat.socialview.Mention; import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter; import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityMergePullRequestBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.VersionCheck; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.MergePullRequest; import org.mian.gitnex.models.MergePullRequest;
import org.mian.gitnex.models.MergePullRequestSpinner; import org.mian.gitnex.models.MergePullRequestSpinner;
@ -42,16 +37,12 @@ import retrofit2.Response;
public class MergePullRequestActivity extends BaseActivity { public class MergePullRequestActivity extends BaseActivity {
public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private ActivityMergePullRequestBinding viewBinding;
private SocialAutoCompleteTextView mergeDescription;
private EditText mergeTitle;
private Spinner mergeModeSpinner;
private ArrayAdapter<Mention> defaultMentionAdapter; private ArrayAdapter<Mention> defaultMentionAdapter;
private Button mergeButton;
private String Do; private String Do;
@Override @Override
@ -65,23 +56,24 @@ public class MergePullRequestActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); viewBinding = ActivityMergePullRequestBinding.inflate(getLayoutInflater());
TinyDB tinyDb = new TinyDB(getApplicationContext()); View view = viewBinding.getRoot();
setContentView(view);
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mergeModeSpinner = findViewById(R.id.mergeSpinner); viewBinding.mergeTitle.requestFocus();
mergeDescription = findViewById(R.id.mergeDescription);
mergeTitle = findViewById(R.id.mergeTitle);
mergeTitle.requestFocus();
assert imm != null; assert imm != null;
imm.showSoftInput(mergeTitle, InputMethodManager.SHOW_IMPLICIT); imm.showSoftInput(viewBinding.mergeTitle, InputMethodManager.SHOW_IMPLICIT);
setMergeAdapter(); setMergeAdapter();
mergeModeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { viewBinding.mergeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
@ -101,20 +93,35 @@ public class MergePullRequestActivity extends BaseActivity {
defaultMentionAdapter = new MentionArrayAdapter<>(this); defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList(); loadCollaboratorsList();
mergeDescription.setMentionAdapter(defaultMentionAdapter); viewBinding.mergeDescription.setMentionAdapter(defaultMentionAdapter);
closeActivity = findViewById(R.id.close);
TextView toolbar_title = findViewById(R.id.toolbar_title);
if(!tinyDb.getString("issueTitle").isEmpty()) { if(!tinyDb.getString("issueTitle").isEmpty()) {
toolbar_title.setText(tinyDb.getString("issueTitle")); viewBinding.toolbarTitle.setText(tinyDb.getString("issueTitle"));
mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber")+ ")"); viewBinding.mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber") + ")");
} }
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); viewBinding.close.setOnClickListener(onClickListener);
mergeButton = findViewById(R.id.mergeButton); // if gitea version is greater/equal(1.12.0) than user installed version (installed.higherOrEqual(compareVer))
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
viewBinding.deleteBranch.setVisibility(View.VISIBLE);
}
if(tinyDb.getString("prMergeable").equals("false")) {
disableProcessButton();
viewBinding.mergeInfoDisabledMessage.setVisibility(View.VISIBLE);
}
else {
viewBinding.mergeInfoDisabledMessage.setVisibility(View.GONE);
}
if(tinyDb.getString("prIsFork").equals("true")) {
viewBinding.deleteBranchForkInfo.setVisibility(View.VISIBLE);
}
else {
viewBinding.deleteBranchForkInfo.setVisibility(View.GONE);
}
if(!connToInternet) { if(!connToInternet) {
@ -123,7 +130,7 @@ public class MergePullRequestActivity extends BaseActivity {
} }
else { else {
mergeButton.setOnClickListener(mergePullRequest); viewBinding.mergeButton.setOnClickListener(mergePullRequest);
} }
@ -131,27 +138,27 @@ public class MergePullRequestActivity extends BaseActivity {
private void setMergeAdapter() { private void setMergeAdapter() {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
ArrayList<MergePullRequestSpinner> mergeList = new ArrayList<>(); ArrayList<MergePullRequestSpinner> mergeList = new ArrayList<>();
mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge))); mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge)));
mergeList.add(new MergePullRequestSpinner("rebase", getResources().getString(R.string.mergeOptionRebase))); mergeList.add(new MergePullRequestSpinner("rebase", getResources().getString(R.string.mergeOptionRebase)));
mergeList.add(new MergePullRequestSpinner("rebase-merge", getResources().getString(R.string.mergeOptionRebaseCommit))); mergeList.add(new MergePullRequestSpinner("rebase-merge", getResources().getString(R.string.mergeOptionRebaseCommit)));
//squash merge works only on gitea v1.11.5 and higher due to a bug // squash merge works only on gitea > v1.11.4 due to a bug
if(VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) { if(new Version(tinyDb.getString("giteaVersion")).higher("1.11.4")) {
mergeList.add(new MergePullRequestSpinner("squash", getResources().getString(R.string.mergeOptionSquash))); mergeList.add(new MergePullRequestSpinner("squash", getResources().getString(R.string.mergeOptionSquash)));
} }
ArrayAdapter<MergePullRequestSpinner> adapter = new ArrayAdapter<>(ctx, R.layout.spinner_item, mergeList); ArrayAdapter<MergePullRequestSpinner> adapter = new ArrayAdapter<>(MergePullRequestActivity.this, R.layout.spinner_item, mergeList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
mergeModeSpinner.setAdapter(adapter); viewBinding.mergeSpinner.setAdapter(adapter);
} }
public void loadCollaboratorsList() { public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -161,7 +168,7 @@ public class MergePullRequestActivity extends BaseActivity {
final String repoOwner = parts[0]; final String repoOwner = parts[0];
final String repoName = parts[1]; final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); Call<List<Collaborators>> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -206,26 +213,27 @@ public class MergePullRequestActivity extends BaseActivity {
private void processMergePullRequest() { private void processMergePullRequest() {
String mergePRDesc = mergeDescription.getText().toString(); String mergePRDesc = viewBinding.mergeDescription.getText().toString();
String mergePRTitle = mergeTitle.getText().toString(); String mergePRTitle = viewBinding.mergeTitle.getText().toString();
boolean deleteBranch = viewBinding.deleteBranch.isChecked();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
disableProcessButton(); disableProcessButton();
mergeFunction(Do, mergePRDesc, mergePRTitle); mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch);
} }
private void mergeFunction(String Do, String mergePRDT, String mergeTitle) { private void mergeFunction(String Do, String mergePRDT, String mergeTitle, boolean deleteBranch) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -238,7 +246,7 @@ public class MergePullRequestActivity extends BaseActivity {
MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle); MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle);
Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().mergePullRequest(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR); Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().mergePullRequest(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR);
call.enqueue(new Callback<ResponseBody>() { call.enqueue(new Callback<ResponseBody>() {
@ -247,10 +255,48 @@ public class MergePullRequestActivity extends BaseActivity {
if(response.code() == 200) { if(response.code() == 200) {
Toasty.info(getApplicationContext(), getString(R.string.mergePRSuccessMsg)); if(deleteBranch) {
tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true); if(tinyDb.getString("prIsFork").equals("true")) {
finish();
String repoFullName = tinyDb.getString("prForkFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
deleteBranchFunction(repoOwner, repoName);
Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true);
finish();
}
else {
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
deleteBranchFunction(repoOwner, repoName);
Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true);
finish();
}
}
else {
Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true);
finish();
}
} }
else if(response.code() == 401) { else if(response.code() == 401) {
@ -262,13 +308,13 @@ public class MergePullRequestActivity extends BaseActivity {
else if(response.code() == 404) { else if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.mergePR404ErrorMsg)); Toasty.info(ctx, getString(R.string.mergePR404ErrorMsg));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }
@ -285,23 +331,56 @@ public class MergePullRequestActivity extends BaseActivity {
} }
private void deleteBranchFunction(String repoOwner, String repoName) {
TinyDB tinyDb = new TinyDB(appCtx);
String instanceUrl = tinyDb.getString("instanceUrl");
String loginUid = tinyDb.getString("loginUid");
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String branchName = tinyDb.getString("prHeadBranch");
Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.deleteBranch(Authorization.returnAuthentication(ctx, loginUid, instanceToken), 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() { private void disableProcessButton() {
mergeButton.setEnabled(false); viewBinding.mergeButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable(); viewBinding.mergeButton.setBackground(getResources().getDrawable(R.drawable.shape_buttons_disabled));
shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.hintColor));
mergeButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
mergeButton.setEnabled(true); viewBinding.mergeButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable(); viewBinding.mergeButton.setBackground(getResources().getDrawable(R.drawable.shape_buttons));
shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.btnBackground));
mergeButton.setBackground(shape);
} }

View File

@ -1,5 +1,6 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -12,13 +13,15 @@ import org.mian.gitnex.util.TinyDB;
public class OpenRepoInBrowserActivity extends AppCompatActivity { public class OpenRepoInBrowserActivity extends AppCompatActivity {
private Context appCtx;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw"); String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw");
if (!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) { if (!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol"); instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol");

View File

@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter; import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
@ -31,6 +32,9 @@ import java.util.Objects;
public class OrganizationDetailActivity extends BaseActivity implements BottomSheetOrganizationFragment.BottomSheetListener { public class OrganizationDetailActivity extends BaseActivity implements BottomSheetOrganizationFragment.BottomSheetListener {
final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_org_detail; return R.layout.activity_org_detail;
@ -38,9 +42,11 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TinyDB tinyDb = new TinyDB(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
String orgName = tinyDb.getString("orgName"); String orgName = tinyDb.getString("orgName");
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
@ -62,15 +68,15 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
switch(tinyDb.getInt("customFontId", -1)) { switch(tinyDb.getInt("customFontId", -1)) {
case 0: case 0:
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/roboto.ttf"); myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
break; break;
case 2: case 2:
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/sourcecodeproregular.ttf"); myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
break; break;
default: default:
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/manroperegular.ttf"); myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf");
break; break;
} }
@ -126,7 +132,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@Override @Override
public void onButtonClicked(String text) { public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
switch (text) { switch (text) {
case "repository": case "repository":
@ -151,7 +157,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@Override @Override
public Fragment getItem(int position) { public Fragment getItem(int position) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
String orgName; String orgName;
if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) { if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) {
orgName = getIntent().getStringExtra("orgName"); orgName = getIntent().getStringExtra("orgName");

View File

@ -1,33 +1,41 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.Nullable; import android.content.Context;
import androidx.lifecycle.Observer; import android.content.Intent;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.GridView; import android.widget.GridView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.adapters.TeamMembersByOrgAdapter; import org.mian.gitnex.adapters.TeamMembersByOrgAdapter;
import org.mian.gitnex.fragments.BottomSheetOrganizationTeamsFragment;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.TeamMembersByOrgViewModel; import org.mian.gitnex.viewmodels.TeamMembersByOrgViewModel;
import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class OrganizationTeamMembersActivity extends BaseActivity { public class OrganizationTeamMembersActivity extends BaseActivity implements BottomSheetOrganizationTeamsFragment.BottomSheetListener {
private TextView noDataMembers; private TextView noDataMembers;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TeamMembersByOrgAdapter adapter; private TeamMembersByOrgAdapter adapter;
private GridView mGridView; private GridView mGridView;
final Context ctx = this;
private Context appCtx;
private String teamId;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_org_team_members; return R.layout.activity_org_team_members;
@ -35,9 +43,13 @@ public class OrganizationTeamMembersActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TinyDB tinyDb = new TinyDB(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -57,7 +69,6 @@ public class OrganizationTeamMembersActivity extends BaseActivity {
toolbarTitle.setText(R.string.orgTeamMembers); toolbarTitle.setText(R.string.orgTeamMembers);
} }
String teamId;
if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")){ if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")){
teamId = getIntent().getStringExtra("teamId"); teamId = getIntent().getStringExtra("teamId");
} }
@ -65,11 +76,24 @@ public class OrganizationTeamMembersActivity extends BaseActivity {
teamId = "0"; teamId = "0";
} }
getIntent().getStringExtra("teamId");
//Log.i("teamId", getIntent().getStringExtra("teamId"));
assert teamId != null; assert teamId != null;
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), Integer.valueOf(teamId)); fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), Integer.parseInt(teamId));
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("teamActionFlag")) {
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), Integer.parseInt(teamId));
tinyDb.putBoolean("teamActionFlag", false);
}
} }
@ -77,30 +101,65 @@ public class OrganizationTeamMembersActivity extends BaseActivity {
TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class); TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class);
teamMembersModel.getMembersByOrgList(instanceUrl, instanceToken, teamId, getApplicationContext()).observe(this, new Observer<List<UserInfo>>() { teamMembersModel.getMembersByOrgList(instanceUrl, instanceToken, teamId, ctx).observe(this, teamMembersListMain -> {
@Override
public void onChanged(@Nullable List<UserInfo> teamMembersListMain) { adapter = new TeamMembersByOrgAdapter(ctx, teamMembersListMain);
adapter = new TeamMembersByOrgAdapter(getApplicationContext(), teamMembersListMain); if(adapter.getCount() > 0) {
if(adapter.getCount() > 0) { mGridView.setAdapter(adapter);
mGridView.setAdapter(adapter); noDataMembers.setVisibility(View.GONE);
noDataMembers.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mGridView.setAdapter(adapter);
noDataMembers.setVisibility(View.VISIBLE);
}
} }
else {
adapter.notifyDataSetChanged();
mGridView.setAdapter(adapter);
noDataMembers.setVisibility(View.VISIBLE);
}
}); });
} }
private void initCloseListener() { @Override
onClickListener = new View.OnClickListener() { public boolean onCreateOptionsMenu(Menu menu) {
@Override
public void onClick(View view) { MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case android.R.id.home:
finish(); finish();
} return true;
}; case R.id.genericMenu:
BottomSheetOrganizationTeamsFragment bottomSheet = new BottomSheetOrganizationTeamsFragment();
bottomSheet.show(getSupportFragmentManager(), "orgTeamsBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(appCtx);
if("newMember".equals(text)) {
Intent intent = new Intent(OrganizationTeamMembersActivity.this, AddNewTeamMemberActivity.class);
intent.putExtra("teamId", teamId);
startActivity(intent);
}
}
private void initCloseListener() {
onClickListener = view -> finish();
} }
} }

View File

@ -35,6 +35,7 @@ public class ProfileEmailActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private EditText userEmail; private EditText userEmail;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private Button addEmailButton; private Button addEmailButton;
@Override @Override
@ -44,9 +45,11 @@ public class ProfileEmailActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -81,8 +84,8 @@ public class ProfileEmailActivity extends BaseActivity {
private void processAddNewEmail() { private void processAddNewEmail() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -91,20 +94,20 @@ public class ProfileEmailActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newUserEmail.equals("")) { if(newUserEmail.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.emailErrorEmpty)); Toasty.info(ctx, getString(R.string.emailErrorEmpty));
return; return;
} }
else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
Toasty.info(getApplicationContext(), getString(R.string.emailErrorInvalid)); Toasty.info(ctx, getString(R.string.emailErrorInvalid));
return; return;
} }
@ -112,19 +115,19 @@ public class ProfileEmailActivity extends BaseActivity {
List<String> newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(","))); List<String> newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(",")));
disableProcessButton(); disableProcessButton();
addNewEmail(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newEmailList); addNewEmail(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newEmailList);
} }
private void addNewEmail(final String instanceUrl, final String token, List<String> newUserEmail) { private void addNewEmail(final String instanceUrl, final String token, List<String> newUserEmail) {
AddEmail addEmailFunc = new AddEmail(newUserEmail); AddEmail addEmailFunc = new AddEmail(newUserEmail);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<JsonElement> call; Call<JsonElement> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.addNewEmail(token, addEmailFunc); .addNewEmail(token, addEmailFunc);
@ -135,7 +138,7 @@ public class ProfileEmailActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.info(getApplicationContext(), getString(R.string.emailAddedText)); Toasty.info(ctx, getString(R.string.emailAddedText));
tinyDb.putBoolean("emailsRefresh", true); tinyDb.putBoolean("emailsRefresh", true);
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -171,7 +174,7 @@ public class ProfileEmailActivity extends BaseActivity {
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }

View File

@ -39,6 +39,7 @@ public class ReplyToIssueActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private SocialAutoCompleteTextView addComment; private SocialAutoCompleteTextView addComment;
private ArrayAdapter<Mention> defaultMentionAdapter; private ArrayAdapter<Mention> defaultMentionAdapter;
@ -53,11 +54,12 @@ public class ReplyToIssueActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
addComment = findViewById(R.id.addComment); addComment = findViewById(R.id.addComment);
addComment.setShowSoftInputOnFocus(true); addComment.setShowSoftInputOnFocus(true);
@ -83,20 +85,26 @@ public class ReplyToIssueActivity extends BaseActivity {
replyButton = findViewById(R.id.replyButton); replyButton = findViewById(R.id.replyButton);
if(getIntent().getStringExtra("commentAction") != null && getIntent().getStringExtra("commentAction").equals("edit")) { if(getIntent().getStringExtra("commentBody") != null) {
addComment.setText(getIntent().getStringExtra("commentBody")); addComment.setText(getIntent().getStringExtra("commentBody"));
if(getIntent().getBooleanExtra("cursorToEnd", false)) {
addComment.setSelection(addComment.length());
}
}
if(getIntent().getStringExtra("commentAction") != null && getIntent().getStringExtra("commentAction").equals("edit")) {
final String commentId = getIntent().getStringExtra("commentId"); final String commentId = getIntent().getStringExtra("commentId");
toolbar_title.setText(getResources().getString(R.string.editCommentTitle)); toolbar_title.setText(getResources().getString(R.string.editCommentTitle));
replyButton.setText(getResources().getString(R.string.editCommentButtonText)); replyButton.setText(getResources().getString(R.string.editCommentButtonText));
replyButton.setOnClickListener(new View.OnClickListener() { replyButton.setOnClickListener(v -> {
public void onClick(View v) { disableProcessButton();
disableProcessButton(); IssueActions.editIssueComment(ctx, Integer.parseInt(commentId), addComment.getText().toString());
IssueActions.editIssueComment(ctx, Integer.valueOf(commentId), addComment.getText().toString());
}
}); });
return; return;
@ -117,7 +125,7 @@ public class ReplyToIssueActivity extends BaseActivity {
public void loadCollaboratorsList() { public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -128,9 +136,9 @@ public class ReplyToIssueActivity extends BaseActivity {
final String repoName = parts[1]; final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -183,18 +191,18 @@ public class ReplyToIssueActivity extends BaseActivity {
private void processNewCommentReply() { private void processNewCommentReply() {
String newReplyDT = addComment.getText().toString(); String newReplyDT = addComment.getText().toString();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
if(!connToInternet) { if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newReplyDT.equals("")) { if(newReplyDT.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.commentEmptyError)); Toasty.info(ctx, getString(R.string.commentEmptyError));
} }
else { else {
@ -208,7 +216,7 @@ public class ReplyToIssueActivity extends BaseActivity {
private void replyComment(String newReplyDT) { private void replyComment(String newReplyDT) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -222,9 +230,9 @@ public class ReplyToIssueActivity extends BaseActivity {
Issues issueComment = new Issues(newReplyDT); Issues issueComment = new Issues(newReplyDT);
Call<Issues> call = RetrofitClient Call<Issues> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.replyCommentToIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment); .replyCommentToIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment);
call.enqueue(new Callback<Issues>() { call.enqueue(new Callback<Issues>() {
@ -233,7 +241,7 @@ public class ReplyToIssueActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.info(getApplicationContext(), getString(R.string.commentSuccess)); Toasty.info(ctx, getString(R.string.commentSuccess));
tinyDb.putBoolean("commentPosted", true); tinyDb.putBoolean("commentPosted", true);
tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("resumePullRequests", true); tinyDb.putBoolean("resumePullRequests", true);
@ -252,7 +260,7 @@ public class ReplyToIssueActivity extends BaseActivity {
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.commentError)); Toasty.info(ctx, getString(R.string.commentError));
} }

View File

@ -1,19 +1,11 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import com.google.android.material.tabs.TabLayout;
import com.google.gson.JsonElement;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import retrofit2.Call;
import retrofit2.Callback;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -23,432 +15,543 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetIssuesFilterFragment;
import org.mian.gitnex.fragments.BottomSheetMilestonesFilterFragment;
import org.mian.gitnex.fragments.BottomSheetPullRequestFilterFragment;
import org.mian.gitnex.fragments.BottomSheetRepoFragment; import org.mian.gitnex.fragments.BottomSheetRepoFragment;
import org.mian.gitnex.fragments.BranchesFragment; import org.mian.gitnex.fragments.BranchesFragment;
import org.mian.gitnex.fragments.CollaboratorsFragment; import org.mian.gitnex.fragments.CollaboratorsFragment;
import org.mian.gitnex.fragments.FilesFragment; import org.mian.gitnex.fragments.FilesFragment;
import org.mian.gitnex.fragments.IssuesMainFragment; import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.fragments.LabelsFragment; import org.mian.gitnex.fragments.LabelsFragment;
import org.mian.gitnex.fragments.MilestonesFragment; import org.mian.gitnex.fragments.MilestonesFragment;
import org.mian.gitnex.fragments.PullRequestsFragment; import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.fragments.ReleasesFragment; import org.mian.gitnex.fragments.ReleasesFragment;
import org.mian.gitnex.fragments.RepoInfoFragment; import org.mian.gitnex.fragments.RepoInfoFragment;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.VersionCheck; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository; import org.mian.gitnex.models.WatchInfo;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.Objects; import java.util.Objects;
import android.net.Uri; import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoFragment.BottomSheetListener { public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoFragment.BottomSheetListener, BottomSheetIssuesFilterFragment.BottomSheetListener,
BottomSheetPullRequestFilterFragment.BottomSheetListener, BottomSheetMilestonesFilterFragment.BottomSheetListener {
private TextView textViewBadgeIssue; private TextView textViewBadgeIssue;
private TextView textViewBadgePull; private TextView textViewBadgePull;
private TextView textViewBadgeRelease; private TextView textViewBadgeRelease;
@Override private FragmentRefreshListener fragmentRefreshListener;
protected int getLayoutResourceId(){ private FragmentRefreshListenerPr fragmentRefreshListenerPr;
return R.layout.activity_repo_detail; private FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone;
}
@Override final Context ctx = this;
public void onCreate(Bundle savedInstanceState) { private Context appCtx;
super.onCreate(savedInstanceState);
TinyDB tinyDb = new TinyDB(getApplicationContext()); // issues interface
String repoFullName = tinyDb.getString("repoFullName"); public FragmentRefreshListener getFragmentRefreshListener() {
String[] parts = repoFullName.split("/");
String repoName1 = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String repoOwner = parts[0];
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String appLocale = tinyDb.getString("locale");
AppUtil.setAppLocale(getResources(), appLocale);
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(repoName1);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
ViewPager mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/roboto.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/manroperegular.ttf");
break;
}
toolbarTitle.setTypeface(myTypeface);
toolbarTitle.setText(repoName1);
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);
}
}
}
// only show Collaborators if you have permission to
final View collaboratorTab = vg.getChildAt(8);
if (tinyDb.getBoolean("isRepoAdmin")) {
collaboratorTab.setVisibility(View.VISIBLE);
}
else {
collaboratorTab.setVisibility(View.GONE);
}
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
if(tinyDb.getBoolean("enableCounterBadges")) {
@SuppressLint("InflateParams") View tabHeader2 = LayoutInflater.from(this).inflate(R.layout.badge_issue, null);
textViewBadgeIssue = tabHeader2.findViewById(R.id.counterBadgeIssue);
@SuppressLint("InflateParams") View tabHeader4 = LayoutInflater.from(this).inflate(R.layout.badge_pull, null);
textViewBadgePull = tabHeader4.findViewById(R.id.counterBadgePull);
@SuppressLint("InflateParams") View tabHeader6 = LayoutInflater.from(this).inflate(R.layout.badge_release, null);
textViewBadgeRelease = tabHeader6.findViewById(R.id.counterBadgeRelease);
textViewBadgeIssue.setVisibility(View.GONE);
textViewBadgePull.setVisibility(View.GONE);
textViewBadgeRelease.setVisibility(View.GONE);
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
ColorStateList textColor = tabLayout.getTabTextColors();
// issue count
if (textViewBadgeIssue.getText() != "") {
TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2);
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2);
assert tabOpenIssues != null;
TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeIssueText);
openIssueTabView.setTextColor(textColor);
}
// pull count
if (textViewBadgePull.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(3)).setCustomView(tabHeader4);
TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(3);
assert tabOpenPulls != null;
TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText);
openPullTabView.setTextColor(textColor);
}
// release count
if (VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) {
if(textViewBadgeRelease.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5);
assert tabOpenRelease != null;
TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText);
openReleaseTabView.setTextColor(textColor);
}
}
}
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("enableCounterIssueBadge")) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.repo_dotted_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
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;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
String repoFullName = tinyDb.getString("repoFullName");
String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw");
if(!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol");
}
Uri url = Uri.parse(instanceUrlWithProtocol + "/" + repoFullName);
switch (text) {
case "label":
startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class));
break;
case "newIssue":
startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class));
break;
case "newMilestone":
startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class));
break;
case "addCollaborator":
startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class));
break;
case "createRelease":
startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
break;
case "openWebRepo":
Intent i = new Intent(Intent.ACTION_VIEW, url);
startActivity(i);
break;
case "shareRepo":
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, url);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, url);
startActivity(Intent.createChooser(sharingIntent, url.toString()));
break;
case "newFile":
startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class));
break;
}
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
Fragment fragment = null;
switch (position) {
case 0: // information
return RepoInfoFragment.newInstance(repoOwner, repoName);
case 1: // files
return FilesFragment.newInstance(repoOwner, repoName);
case 2: // issues
fragment = new IssuesMainFragment();
break;
case 3: // pull requests
fragment = new PullRequestsFragment();
break;
case 4: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 5: // releases
return ReleasesFragment.newInstance(repoOwner, repoName);
case 6: // milestones
return MilestonesFragment.newInstance(repoOwner, repoName);
case 7: // labels
return LabelsFragment.newInstance(repoOwner, repoName);
case 8: // collaborators
return CollaboratorsFragment.newInstance(repoOwner, repoName);
}
assert fragment != null;
return fragment;
}
@Override
public int getCount() {
return 9;
}
}
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<UserRepositories> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserRepository(token, owner, repo);
call.enqueue(new Callback<UserRepositories>() {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
UserRepositories repoInfo = response.body();
if (response.isSuccessful()) {
if (response.code() == 200) {
if(tinyDb.getBoolean("enableCounterBadges")) {
assert repoInfo != null;
if(repoInfo.getOpen_issues_count() != null) {
textViewBadgeIssue.setVisibility(View.VISIBLE);
textViewBadgeIssue.setText(repoInfo.getOpen_issues_count());
}
if(repoInfo.getOpen_pull_count() != null) {
textViewBadgePull.setVisibility(View.VISIBLE);
textViewBadgePull.setText(repoInfo.getOpen_pull_count());
}
if(repoInfo.getRelease_count() != null) {
textViewBadgeRelease.setVisibility(View.VISIBLE);
textViewBadgeRelease.setText(repoInfo.getRelease_count());
}
}
} return fragmentRefreshListener;
}
} public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) {
else {
Log.e("onFailure", String.valueOf(response.code()));
}
} this.fragmentRefreshListener = fragmentRefreshListener;
}
@Override public interface FragmentRefreshListener {
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
}); void onRefresh(String text);
} }
private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) { // pr interface
public FragmentRefreshListenerPr getFragmentRefreshListenerPr() {
Call<JsonElement> call; return fragmentRefreshListenerPr;
}
call = RetrofitClient public void setFragmentRefreshListenerPr(FragmentRefreshListenerPr fragmentRefreshListenerPr) {
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.checkRepoStarStatus(instanceToken, owner, repo);
call.enqueue(new Callback<JsonElement>() { this.fragmentRefreshListenerPr = fragmentRefreshListenerPr;
}
@Override public interface FragmentRefreshListenerPr {
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); void onRefresh(String text);
tinyDb.putInt("repositoryStarStatus", response.code());
} }
@Override // milestones interface
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { public FragmentRefreshListenerMilestone getFragmentRefreshListenerMilestone() {
Log.e("onFailure", t.toString());
}
});
} return fragmentRefreshListenerMilestone;
}
private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) { public void setFragmentRefreshListenerMilestone(FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone) {
Call<WatchRepository> call; this.fragmentRefreshListenerMilestone = fragmentRefreshListenerMilestone;
}
call = RetrofitClient public interface FragmentRefreshListenerMilestone {
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.checkRepoWatchStatus(instanceToken, owner, repo);
call.enqueue(new Callback<WatchRepository>() { void onRefresh(String text);
@Override }
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); @Override
protected int getLayoutResourceId() {
if(response.code() == 200) { return R.layout.activity_repo_detail;
assert response.body() != null; }
if(response.body().getSubscribed()) {
tinyDb.putBoolean("repositoryWatchStatus", true);
}
}
else {
tinyDb.putBoolean("repositoryWatchStatus", false);
}
} @Override
public void onCreate(Bundle savedInstanceState) {
@Override super.onCreate(savedInstanceState);
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) { appCtx = getApplicationContext();
Log.e("onFailure", t.toString());
}
});
} TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoName1 = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String repoOwner = parts[0];
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
tinyDb.putString("repoIssuesState", "open");
tinyDb.putString("repoPrState", "open");
tinyDb.putString("milestoneState", "open");
String appLocale = tinyDb.getString("locale");
AppUtil.setAppLocale(getResources(), appLocale);
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(repoName1);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
ViewPager mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
Typeface myTypeface;
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(repoName1);
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);
}
}
}
// only show Collaborators if you have permission to
final View collaboratorTab = vg.getChildAt(8);
if(tinyDb.getBoolean("isRepoAdmin")) {
collaboratorTab.setVisibility(View.VISIBLE);
}
else {
collaboratorTab.setVisibility(View.GONE);
}
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
if(tinyDb.getBoolean("enableCounterBadges")) {
@SuppressLint("InflateParams") View tabHeader2 = LayoutInflater.from(this).inflate(R.layout.badge_issue, null);
textViewBadgeIssue = tabHeader2.findViewById(R.id.counterBadgeIssue);
@SuppressLint("InflateParams") View tabHeader4 = LayoutInflater.from(this).inflate(R.layout.badge_pull, null);
textViewBadgePull = tabHeader4.findViewById(R.id.counterBadgePull);
@SuppressLint("InflateParams") View tabHeader6 = LayoutInflater.from(this).inflate(R.layout.badge_release, null);
textViewBadgeRelease = tabHeader6.findViewById(R.id.counterBadgeRelease);
textViewBadgeIssue.setVisibility(View.GONE);
textViewBadgePull.setVisibility(View.GONE);
textViewBadgeRelease.setVisibility(View.GONE);
getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName1);
ColorStateList textColor = tabLayout.getTabTextColors();
// issue count
if(textViewBadgeIssue.getText() != "") {
TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2);
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2);
assert tabOpenIssues != null;
TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeIssueText);
openIssueTabView.setTextColor(textColor);
}
// pull count
if(textViewBadgePull.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(3)).setCustomView(tabHeader4);
TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(3);
assert tabOpenPulls != null;
TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText);
openPullTabView.setTextColor(textColor);
}
// release count
if(new Version("1.11.4").less(tinyDb.getString("giteaVersion"))) {
if(textViewBadgeRelease.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5);
assert tabOpenRelease != null;
TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText);
openReleaseTabView.setTextColor(textColor);
}
}
}
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName1);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName1);
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("enableCounterIssueBadge")) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.repo_dotted_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
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;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(appCtx);
switch(text) {
case "label":
startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class));
break;
case "newIssue":
startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class));
break;
case "newMilestone":
startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class));
break;
case "addCollaborator":
startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class));
break;
case "createRelease":
startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
break;
case "openWebRepo":
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(tinyDb.getString("repoHtmlUrl")));
startActivity(i);
break;
case "shareRepo":
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, tinyDb.getString("repoHtmlUrl"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, tinyDb.getString("repoHtmlUrl"));
startActivity(Intent.createChooser(sharingIntent, tinyDb.getString("repoHtmlUrl")));
break;
case "newFile":
startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class));
break;
case "openIssues":
if(getFragmentRefreshListener() != null) {
getFragmentRefreshListener().onRefresh("open");
}
break;
case "closedIssues":
if(getFragmentRefreshListener() != null) {
getFragmentRefreshListener().onRefresh("closed");
}
break;
case "openPr":
if(getFragmentRefreshListenerPr() != null) {
getFragmentRefreshListenerPr().onRefresh("open");
}
break;
case "closedPr":
if(getFragmentRefreshListenerPr() != null) {
getFragmentRefreshListenerPr().onRefresh("closed");
}
break;
case "openMilestone":
if(getFragmentRefreshListenerMilestone() != null) {
getFragmentRefreshListenerMilestone().onRefresh("open");
}
break;
case "closedMilestone":
if(getFragmentRefreshListenerMilestone() != null) {
getFragmentRefreshListenerMilestone().onRefresh("closed");
}
break;
}
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
Fragment fragment = null;
switch(position) {
case 0: // information
return RepoInfoFragment.newInstance(repoOwner, repoName);
case 1: // files
return FilesFragment.newInstance(repoOwner, repoName);
case 2: // issues
fragment = new IssuesFragment();
break;
case 3: // pull requests
fragment = new PullRequestsFragment();
break;
case 4: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 5: // releases
return ReleasesFragment.newInstance(repoOwner, repoName);
case 6: // milestones
fragment = new MilestonesFragment();
break;
case 7: // labels
return LabelsFragment.newInstance(repoOwner, repoName);
case 8: // collaborators
return CollaboratorsFragment.newInstance(repoOwner, repoName);
}
assert fragment != null;
return fragment;
}
@Override
public int getCount() {
return 9;
}
}
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) {
TinyDB tinyDb = new TinyDB(appCtx);
Call<UserRepositories> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserRepository(token, owner, repo);
call.enqueue(new Callback<UserRepositories>() {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
UserRepositories repoInfo = response.body();
if(response.isSuccessful()) {
if(response.code() == 200) {
if(tinyDb.getBoolean("enableCounterBadges")) {
assert repoInfo != null;
if(repoInfo.getOpen_issues_count() != null) {
textViewBadgeIssue.setVisibility(View.VISIBLE);
textViewBadgeIssue.setText(repoInfo.getOpen_issues_count());
}
if(repoInfo.getOpen_pull_count() != null) {
textViewBadgePull.setVisibility(View.VISIBLE);
textViewBadgePull.setText(repoInfo.getOpen_pull_count());
}
if(repoInfo.getRelease_count() != null) {
textViewBadgeRelease.setVisibility(View.VISIBLE);
textViewBadgeRelease.setText(repoInfo.getRelease_count());
}
}
}
}
else {
Log.e("onFailure", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
Call<JsonElement> call;
call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoStarStatus(instanceToken, owner, repo);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putInt("repositoryStarStatus", response.code());
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoWatchStatus(instanceToken, owner, repo);
call.enqueue(new Callback<WatchInfo>() {
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
TinyDB tinyDb = new TinyDB(appCtx);
if(response.code() == 200) {
assert response.body() != null;
if(response.body().getSubscribed()) {
tinyDb.putBoolean("repositoryWatchStatus", true);
}
}
else {
tinyDb.putBoolean("repositoryWatchStatus", false);
}
}
@Override
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
} }

View File

@ -1,5 +1,6 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
@ -29,6 +30,9 @@ public class RepoStargazersActivity extends BaseActivity {
private GridView mGridView; private GridView mGridView;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_repo_stargazers; return R.layout.activity_repo_stargazers;
@ -36,9 +40,11 @@ public class RepoStargazersActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TinyDB tinyDb = new TinyDB(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -59,7 +65,7 @@ public class RepoStargazersActivity extends BaseActivity {
toolbarTitle.setText(R.string.repoStargazersInMenu); toolbarTitle.setText(R.string.repoStargazersInMenu);
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
} }
@ -67,10 +73,10 @@ public class RepoStargazersActivity extends BaseActivity {
RepoStargazersViewModel repoStargazersModel = new ViewModelProvider(this).get(RepoStargazersViewModel.class); RepoStargazersViewModel repoStargazersModel = new ViewModelProvider(this).get(RepoStargazersViewModel.class);
repoStargazersModel.getRepoStargazers(instanceUrl, instanceToken, repoOwner, repoName, getApplicationContext()).observe(this, new Observer<List<UserInfo>>() { repoStargazersModel.getRepoStargazers(instanceUrl, instanceToken, repoOwner, repoName, ctx).observe(this, new Observer<List<UserInfo>>() {
@Override @Override
public void onChanged(@Nullable List<UserInfo> stargazersListMain) { public void onChanged(@Nullable List<UserInfo> stargazersListMain) {
adapter = new RepoStargazersAdapter(getApplicationContext(), stargazersListMain); adapter = new RepoStargazersAdapter(ctx, stargazersListMain);
if(adapter.getCount() > 0) { if(adapter.getCount() > 0) {
mGridView.setAdapter(adapter); mGridView.setAdapter(adapter);
noDataStargazers.setVisibility(View.GONE); noDataStargazers.setVisibility(View.GONE);

View File

@ -1,5 +1,6 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
@ -29,6 +30,9 @@ public class RepoWatchersActivity extends BaseActivity {
private GridView mGridView; private GridView mGridView;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_repo_watchers; return R.layout.activity_repo_watchers;
@ -36,9 +40,11 @@ public class RepoWatchersActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TinyDB tinyDb = new TinyDB(getApplicationContext()); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -59,7 +65,7 @@ public class RepoWatchersActivity extends BaseActivity {
toolbarTitle.setText(R.string.repoWatchersInMenu); toolbarTitle.setText(R.string.repoWatchersInMenu);
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
} }
@ -67,10 +73,10 @@ public class RepoWatchersActivity extends BaseActivity {
RepoWatchersViewModel repoWatchersModel = new ViewModelProvider(this).get(RepoWatchersViewModel.class); RepoWatchersViewModel repoWatchersModel = new ViewModelProvider(this).get(RepoWatchersViewModel.class);
repoWatchersModel.getRepoWatchers(instanceUrl, instanceToken, repoOwner, repoName, getApplicationContext()).observe(this, new Observer<List<UserInfo>>() { repoWatchersModel.getRepoWatchers(instanceUrl, instanceToken, repoOwner, repoName, ctx).observe(this, new Observer<List<UserInfo>>() {
@Override @Override
public void onChanged(@Nullable List<UserInfo> watchersListMain) { public void onChanged(@Nullable List<UserInfo> watchersListMain) {
adapter = new RepoWatchersAdapter(getApplicationContext(), watchersListMain); adapter = new RepoWatchersAdapter(ctx, watchersListMain);
if(adapter.getCount() > 0) { if(adapter.getCount() > 0) {
mGridView.setAdapter(adapter); mGridView.setAdapter(adapter);
noDataWatchers.setVisibility(View.GONE); noDataWatchers.setVisibility(View.GONE);

View File

@ -0,0 +1,328 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
/**
* Author M M Arif
*/
public class SettingsAppearanceActivity extends BaseActivity {
private Context appCtx;
private View.OnClickListener onClickListener;
private static String[] timeList = {"Pretty", "Normal"};
private static int timeSelectedChoice = 0;
private static String[] codeBlockList = {"Green - Black", "White - Black", "Grey - Black", "White - Grey", "Dark - White"};
private static int codeBlockSelectedChoice = 0;
private static String[] homeScreenList = {"My Repositories", "Starred Repositories", "Organizations", "Repositories", "Profile"};
private static int homeScreenSelectedChoice = 0;
private static String[] customFontList = {"Roboto", "Manrope", "Source Code Pro"};
private static int customFontSelectedChoice = 0;
private static String[] themeList = {"Dark", "Light", "Auto (Day/Night)"};
private static int themeSelectedChoice = 0;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_settings_appearance;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
final TinyDB tinyDb = new TinyDB(appCtx);
ImageView closeActivity = findViewById(R.id.close);
final TextView tvDateTimeSelected = findViewById(R.id.tvDateTimeSelected); // setter for time
final TextView codeBlockSelected = findViewById(R.id.codeBlockSelected); // setter for code block
final TextView homeScreenSelected = findViewById(R.id.homeScreenSelected); // setter for home screen
final TextView customFontSelected = findViewById(R.id.customFontSelected); // setter for custom font
final TextView themeSelected = findViewById(R.id.themeSelected); // setter for theme
LinearLayout timeFrame = findViewById(R.id.timeFrame);
LinearLayout codeBlockFrame = findViewById(R.id.codeBlockFrame);
LinearLayout homeScreenFrame = findViewById(R.id.homeScreenFrame);
LinearLayout customFontFrame = findViewById(R.id.customFontFrame);
LinearLayout themeFrame = findViewById(R.id.themeSelectionFrame);
Switch counterBadgesSwitch = findViewById(R.id.switchCounterBadge);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
if(!tinyDb.getString("timeStr").isEmpty()) {
tvDateTimeSelected.setText(tinyDb.getString("timeStr"));
}
if(!tinyDb.getString("codeBlockStr").isEmpty()) {
codeBlockSelected.setText(tinyDb.getString("codeBlockStr"));
}
if(!tinyDb.getString("homeScreenStr").isEmpty()) {
homeScreenSelected.setText(tinyDb.getString("homeScreenStr"));
}
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(codeBlockSelectedChoice == 0) {
codeBlockSelectedChoice = tinyDb.getInt("codeBlockId");
}
if(homeScreenSelectedChoice == 0) {
homeScreenSelectedChoice = tinyDb.getInt("homeScreenId");
}
if(customFontSelectedChoice == 0) {
customFontSelectedChoice = tinyDb.getInt("customFontId", 1);
}
if(themeSelectedChoice == 0) {
themeSelectedChoice = tinyDb.getInt("themeId");
}
if(tinyDb.getBoolean("enableCounterBadges")) {
counterBadgesSwitch.setChecked(true);
}
else {
counterBadgesSwitch.setChecked(false);
}
// counter badge switcher
counterBadgesSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (isChecked) {
tinyDb.putBoolean("enableCounterBadges", true);
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}
else {
tinyDb.putBoolean("enableCounterBadges", false);
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}
});
// theme selection dialog
themeFrame.setOnClickListener(view -> {
AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
tsBuilder.setTitle(getResources().getString(R.string.themeSelectorDialogTitle));
if(themeSelectedChoice != -1) {
tsBuilder.setCancelable(true);
}
else {
tsBuilder.setCancelable(false);
}
tsBuilder.setSingleChoiceItems(themeList, themeSelectedChoice, (dialogInterfaceTheme, i) -> {
themeSelectedChoice = i;
themeSelected.setText(themeList[i]);
tinyDb.putString("themeStr", themeList[i]);
tinyDb.putInt("themeId", i);
tinyDb.putBoolean("refreshParent", true);
this.recreate();
this.overridePendingTransition(0, 0);
dialogInterfaceTheme.dismiss();
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = tsBuilder.create();
cfDialog.show();
});
// custom font dialog
customFontFrame.setOnClickListener(view -> {
AlertDialog.Builder cfBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
cfBuilder.setTitle(R.string.settingsCustomFontSelectorDialogTitle);
if(customFontSelectedChoice != -1) {
cfBuilder.setCancelable(true);
}
else {
cfBuilder.setCancelable(false);
}
cfBuilder.setSingleChoiceItems(customFontList, customFontSelectedChoice, (dialogInterfaceCustomFont, i) -> {
customFontSelectedChoice = i;
customFontSelected.setText(customFontList[i]);
tinyDb.putString("customFontStr", customFontList[i]);
tinyDb.putInt("customFontId", i);
tinyDb.putBoolean("refreshParent", true);
this.recreate();
this.overridePendingTransition(0, 0);
dialogInterfaceCustomFont.dismiss();
Toasty.info(appCtx, appCtx.getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = cfBuilder.create();
cfDialog.show();
});
// home screen dialog
homeScreenFrame.setOnClickListener(view -> {
AlertDialog.Builder hsBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
hsBuilder.setTitle(R.string.settingshomeScreenSelectorDialogTitle);
if(homeScreenSelectedChoice != -1) {
hsBuilder.setCancelable(true);
}
else {
hsBuilder.setCancelable(false);
}
hsBuilder.setSingleChoiceItems(homeScreenList, homeScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> {
homeScreenSelectedChoice = i;
homeScreenSelected.setText(homeScreenList[i]);
tinyDb.putString("homeScreenStr", homeScreenList[i]);
tinyDb.putInt("homeScreenId", i);
dialogInterfaceHomeScreen.dismiss();
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});
AlertDialog hsDialog = hsBuilder.create();
hsDialog.show();
});
// code block dialog
codeBlockFrame.setOnClickListener(view -> {
AlertDialog.Builder cBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
cBuilder.setTitle(R.string.settingsCodeBlockSelectorDialogTitle);
if(codeBlockSelectedChoice != -1) {
cBuilder.setCancelable(true);
}
else {
cBuilder.setCancelable(false);
}
cBuilder.setSingleChoiceItems(codeBlockList, codeBlockSelectedChoice, (dialogInterfaceCodeBlock, i) -> {
codeBlockSelectedChoice = i;
codeBlockSelected.setText(codeBlockList[i]);
tinyDb.putString("codeBlockStr", codeBlockList[i]);
tinyDb.putInt("codeBlockId", i);
switch(codeBlockList[i]) {
case "White - Black":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
case "Grey - Black":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorAccent));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
case "White - Grey":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorAccent));
break;
case "Dark - White":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorPrimary));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.white));
break;
default:
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
}
dialogInterfaceCodeBlock.dismiss();
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});
AlertDialog cDialog = cBuilder.create();
cDialog.show();
});
// time and date dialog
timeFrame.setOnClickListener(view -> {
AlertDialog.Builder tBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
tBuilder.setTitle(R.string.settingsTimeSelectorDialogTitle);
if(timeSelectedChoice != -1) {
tBuilder.setCancelable(true);
}
else {
tBuilder.setCancelable(false);
}
tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, (dialogInterfaceTime, i) -> {
timeSelectedChoice = i;
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");
}
dialogInterfaceTime.dismiss();
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});
AlertDialog tDialog = tBuilder.create();
tDialog.show();
});
}
private void initCloseListener() {
onClickListener = view -> {
finish();
};
}
}

View File

@ -0,0 +1,119 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
/**
* Author M M Arif
*/
public class SettingsFileViewerActivity extends BaseActivity {
private Context appCtx;
private View.OnClickListener onClickListener;
private static String[] fileViewerSourceCodeThemesList = {"Sublime", "Arduino Light", "Github", "Far ", "Ir Black", "Android Studio"};
private static int fileViewerSourceCodeThemesSelectedChoice = 0;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_settings_fileview;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
final TinyDB tinyDb = new TinyDB(appCtx);
ImageView closeActivity = findViewById(R.id.close);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
final TextView fileViewerSourceCodeThemesSelected = findViewById(R.id.sourceCodeThemeSelected); // setter for fileviewer theme
LinearLayout sourceCodeThemeFrame = findViewById(R.id.sourceCodeThemeFrame);
Switch pdfModeSwitch = findViewById(R.id.switchPdfMode);
if(!tinyDb.getString("fileviewerSourceCodeThemeStr").isEmpty()) {
fileViewerSourceCodeThemesSelected.setText(tinyDb.getString("fileviewerSourceCodeThemeStr"));
}
if(fileViewerSourceCodeThemesSelectedChoice == 0) {
fileViewerSourceCodeThemesSelectedChoice = tinyDb.getInt("fileviewerThemeId");
}
if(tinyDb.getBoolean("enablePdfMode")) {
pdfModeSwitch.setChecked(true);
}
else {
pdfModeSwitch.setChecked(false);
}
// fileviewer srouce code theme selection dialog
sourceCodeThemeFrame.setOnClickListener(view -> {
AlertDialog.Builder fvtsBuilder = new AlertDialog.Builder(SettingsFileViewerActivity.this);
fvtsBuilder.setTitle(R.string.fileviewerSourceCodeThemeSelectorDialogTitle);
if(fileViewerSourceCodeThemesSelectedChoice != -1) {
fvtsBuilder.setCancelable(true);
}
else {
fvtsBuilder.setCancelable(false);
}
fvtsBuilder.setSingleChoiceItems(fileViewerSourceCodeThemesList, fileViewerSourceCodeThemesSelectedChoice, (dialogInterfaceTheme, i) -> {
fileViewerSourceCodeThemesSelectedChoice = i;
fileViewerSourceCodeThemesSelected.setText(fileViewerSourceCodeThemesList[i]);
tinyDb.putString("fileviewerSourceCodeThemeStr", fileViewerSourceCodeThemesList[i]);
tinyDb.putInt("fileviewerSourceCodeThemeId", i);
dialogInterfaceTheme.dismiss();
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = fvtsBuilder.create();
cfDialog.show();
});
// pdf night mode switcher
pdfModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked) {
tinyDb.putBoolean("enablePdfMode", true);
tinyDb.putString("enablePdfModeInit", "yes");
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}
else {
tinyDb.putBoolean("enablePdfMode", false);
tinyDb.putString("enablePdfModeInit", "yes");
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}
});
}
private void initCloseListener() {
onClickListener = view -> finish();
}
}

View File

@ -0,0 +1,71 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Switch;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
/**
* Author M M Arif
*/
public class SettingsReportsActivity extends BaseActivity {
private Context appCtx;
private View.OnClickListener onClickListener;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_settings_reporting;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
ImageView closeActivity = findViewById(R.id.close);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
Switch crashReportsSwitch = findViewById(R.id.crashReportsSwitch);
if(tinyDb.getBoolean("crashReportingEnabled")) {
crashReportsSwitch.setChecked(true);
}
else {
crashReportsSwitch.setChecked(false);
}
// crash reports switcher
crashReportsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked) {
tinyDb.putBoolean("crashReportingEnabled", true);
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}
else {
tinyDb.putBoolean("crashReportingEnabled", false);
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}
});
}
private void initCloseListener() {
onClickListener = view -> {
finish();
};
}
}

View File

@ -0,0 +1,214 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.FilesData;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
/**
* Author M M Arif
*/
public class SettingsSecurityActivity extends BaseActivity {
private Context appCtx;
private View.OnClickListener onClickListener;
private static String[] cacheSizeDataList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"};
private static int cacheSizeDataSelectedChoice = 0;
private static String[] cacheSizeImagesList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"};
private static int cacheSizeImagesSelectedChoice = 0;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_settings_security;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
ImageView closeActivity = findViewById(R.id.close);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
TextView cacheSizeDataSelected = findViewById(R.id.cacheSizeDataSelected); // setter for data cache size
TextView cacheSizeImagesSelected = findViewById(R.id.cacheSizeImagesSelected); // setter for images cache size
TextView clearCacheSelected = findViewById(R.id.clearCacheSelected); // setter for clear cache
LinearLayout certsFrame = findViewById(R.id.certsFrame);
LinearLayout cacheSizeDataFrame = findViewById(R.id.cacheSizeDataSelectionFrame);
LinearLayout cacheSizeImagesFrame = findViewById(R.id.cacheSizeImagesSelectionFrame);
LinearLayout clearCacheFrame = findViewById(R.id.clearCacheSelectionFrame);
if(!tinyDb.getString("cacheSizeStr").isEmpty()) {
cacheSizeDataSelected.setText(tinyDb.getString("cacheSizeStr"));
}
if(!tinyDb.getString("cacheSizeImagesStr").isEmpty()) {
cacheSizeImagesSelected.setText(tinyDb.getString("cacheSizeImagesStr"));
}
if(cacheSizeDataSelectedChoice == 0) {
cacheSizeDataSelectedChoice = tinyDb.getInt("cacheSizeId");
}
if(cacheSizeImagesSelectedChoice == 0) {
cacheSizeImagesSelectedChoice = tinyDb.getInt("cacheSizeImagesId");
}
// clear cache setter
File cacheDir = appCtx.getCacheDir();
long size__ = FilesData.getFileSizeRecursively(new HashSet<>(), cacheDir);
if(size__ > 0) {
clearCacheSelected.setText(String.valueOf(AppUtil.formatFileSizeInDetail(size__)));
}
// clear cache
clearCacheFrame.setOnClickListener(v1 -> {
AlertDialog.Builder builder = new AlertDialog.Builder(SettingsSecurityActivity.this);
builder.setTitle(getResources().getString(R.string.clearCacheDialogHeader));
builder.setMessage(getResources().getString(R.string.clearCacheDialogMessage));
builder.setPositiveButton(R.string.menuDeleteText, (dialog, which) -> {
try {
FileUtils.deleteDirectory(cacheDir);
FileUtils.mkdir(cacheDir.getAbsolutePath());
this.recreate();
this.overridePendingTransition(0, 0);
}
catch (IOException e) {
Log.e("SettingsSecurity", e.toString());
}
});
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
builder.create().show();
});
// cache size images selection dialog
cacheSizeImagesFrame.setOnClickListener(view -> {
AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsSecurityActivity.this);
tsBuilder.setTitle(getResources().getString(R.string.cacheSizeImagesDialogHeader));
if(cacheSizeImagesSelectedChoice != -1) {
tsBuilder.setCancelable(true);
}
else {
tsBuilder.setCancelable(false);
}
tsBuilder.setSingleChoiceItems(cacheSizeImagesList, cacheSizeImagesSelectedChoice, (dialogInterfaceTheme, i) -> {
cacheSizeImagesSelectedChoice = i;
cacheSizeImagesSelected.setText(cacheSizeImagesList[i]);
tinyDb.putString("cacheSizeImagesStr", cacheSizeImagesList[i]);
tinyDb.putInt("cacheSizeImagesId", i);
dialogInterfaceTheme.dismiss();
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = tsBuilder.create();
cfDialog.show();
});
// cache size data selection dialog
cacheSizeDataFrame.setOnClickListener(view -> {
AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsSecurityActivity.this);
tsBuilder.setTitle(getResources().getString(R.string.cacheSizeDataDialogHeader));
if(cacheSizeDataSelectedChoice != -1) {
tsBuilder.setCancelable(true);
}
else {
tsBuilder.setCancelable(false);
}
tsBuilder.setSingleChoiceItems(cacheSizeDataList, cacheSizeDataSelectedChoice, (dialogInterfaceTheme, i) -> {
cacheSizeDataSelectedChoice = i;
cacheSizeDataSelected.setText(cacheSizeDataList[i]);
tinyDb.putString("cacheSizeStr", cacheSizeDataList[i]);
tinyDb.putInt("cacheSizeId", i);
dialogInterfaceTheme.dismiss();
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = tsBuilder.create();
cfDialog.show();
});
// certs deletion
certsFrame.setOnClickListener(v1 -> {
AlertDialog.Builder builder = new AlertDialog.Builder(SettingsSecurityActivity.this);
builder.setTitle(getResources().getString(R.string.settingsCertsPopupTitle));
builder.setMessage(getResources().getString(R.string.settingsCertsPopupMessage));
builder.setPositiveButton(R.string.menuDeleteText, (dialog, which) -> {
appCtx.getSharedPreferences(MemorizingTrustManager.KEYSTORE_NAME, Context.MODE_PRIVATE).edit().remove(MemorizingTrustManager.KEYSTORE_KEY).apply();
tinyDb.putBoolean("loggedInMode", false);
tinyDb.remove("basicAuthPassword");
tinyDb.putBoolean("basicAuthFlag", false);
//tinyDb.clear();
Intent loginActivityIntent = new Intent().setClass(appCtx, LoginActivity.class);
loginActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
appCtx.startActivity(loginActivityIntent);
});
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
builder.create().show();
});
}
private void initCloseListener() {
onClickListener = view -> {
finish();
};
}
}

View File

@ -0,0 +1,165 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
/**
* Author M M Arif
*/
public class SettingsTranslationActivity extends BaseActivity {
private Context appCtx;
private View.OnClickListener onClickListener;
private static String[] langList = {"English", "Arabic", "Chinese", "Finnish", "French", "German", "Italian", "Latvian", "Persian", "Polish", "Portuguese/Brazilian", "Russian", "Serbian", "Spanish", "Turkish",
"Ukrainian"};
private static int langSelectedChoice = 0;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_settings_translation;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
ImageView closeActivity = findViewById(R.id.close);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
final TextView tvLanguageSelected = findViewById(R.id.tvLanguageSelected); // setter for en, fr
TextView helpTranslate = findViewById(R.id.helpTranslate);
LinearLayout langFrame = findViewById(R.id.langFrame);
helpTranslate.setOnClickListener(v12 -> {
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);
});
if(!tinyDb.getString("localeStr").isEmpty()) {
tvLanguageSelected.setText(tinyDb.getString("localeStr"));
}
if(langSelectedChoice == 0) {
langSelectedChoice = tinyDb.getInt("langId");
}
// language dialog
langFrame.setOnClickListener(view -> {
AlertDialog.Builder lBuilder = new AlertDialog.Builder(SettingsTranslationActivity.this);
lBuilder.setTitle(R.string.settingsLanguageSelectorDialogTitle);
if(langSelectedChoice != -1) {
lBuilder.setCancelable(true);
}
else {
lBuilder.setCancelable(false);
}
lBuilder.setSingleChoiceItems(langList, langSelectedChoice, (dialogInterface, i) -> {
langSelectedChoice = i;
tvLanguageSelected.setText(langList[i]);
tinyDb.putString("localeStr", langList[i]);
tinyDb.putInt("langId", i);
switch(langList[i]) {
case "Arabic":
tinyDb.putString("locale", "ar");
break;
case "Chinese":
tinyDb.putString("locale", "zh");
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.putBoolean("refreshParent", true);
this.recreate();
this.overridePendingTransition(0, 0);
dialogInterface.dismiss();
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
});
lBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> dialog.dismiss());
AlertDialog lDialog = lBuilder.create();
lDialog.show();
});
}
private void initCloseListener() {
onClickListener = view -> {
finish();
};
}
}

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.activities;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
@ -20,6 +21,7 @@ import java.util.List;
public class SponsorsActivity extends BaseActivity { public class SponsorsActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -28,7 +30,9 @@ public class SponsorsActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
@ -43,7 +47,7 @@ public class SponsorsActivity extends BaseActivity {
RecyclerView mRecyclerView = findViewById(R.id.recyclerView); RecyclerView mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(appCtx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL); DividerItemDecoration.VERTICAL);

View File

@ -5,6 +5,7 @@ import android.content.Intent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.CommitsActivity; import org.mian.gitnex.activities.CommitsActivity;
@ -34,7 +35,7 @@ public class BranchesAdapter extends RecyclerView.Adapter<BranchesAdapter.Branch
branchNameTv = itemView.findViewById(R.id.branchName); branchNameTv = itemView.findViewById(R.id.branchName);
branchCommitAuthor = itemView.findViewById(R.id.branchCommitAuthor); branchCommitAuthor = itemView.findViewById(R.id.branchCommitAuthor);
TextView branchCommitHash = itemView.findViewById(R.id.branchCommitHash); Button branchCommitHash = itemView.findViewById(R.id.branchCommitHash);
branchCommitHash.setOnClickListener(new View.OnClickListener() { branchCommitHash.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {

View File

@ -1,18 +1,21 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.text.Html; import android.content.Intent;
import android.text.method.LinkMovementMethod; import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.mikepenz.fastadapter.FastAdapter; import androidx.recyclerview.widget.RecyclerView;
import com.mikepenz.fastadapter.items.AbstractItem;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.Commits;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -20,142 +23,152 @@ import java.util.Locale;
* Author M M Arif * Author M M Arif
*/ */
public class CommitsAdapter extends AbstractItem<CommitsAdapter, CommitsAdapter.ViewHolder> { public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final private Context ctx; private Context ctx;
private String commitTitle; private final int TYPE_LOAD = 0;
private String commitHtmlUrl; private List<Commits> commitsList;
private String commitCommitter; private CommitsAdapter.OnLoadMoreListener loadMoreListener;
private Date commitDate; private boolean isLoading = false;
private boolean isMoreDataAvailable = true;
private boolean isSelectable = true; public CommitsAdapter(Context ctx, List<Commits> commitsListMain) {
public CommitsAdapter(Context ctx) {
this.ctx = ctx; this.ctx = ctx;
} this.commitsList = commitsListMain;
public CommitsAdapter withNewItems(String commitTitle, String commitHtmlUrl, String commitCommitter, Date commitDate) {
this.setNewItems(commitTitle, commitHtmlUrl, commitCommitter, commitDate);
return this;
}
private void setNewItems(String commitTitle, String commitHtmlUrl, String commitCommitter, Date commitDate) {
this.commitTitle = commitTitle;
this.commitHtmlUrl = commitHtmlUrl;
this.commitCommitter = commitCommitter;
this.commitDate = commitDate;
}
public String getCommitTitle() {
return commitTitle;
}
private String getCommitHtmlUrl() {
return commitHtmlUrl;
}
private String getcommitCommitter() {
return commitCommitter;
}
private Date getcommitDate() {
return commitDate;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public CommitsAdapter withEnabled(boolean enabled) {
return null;
}
@Override
public boolean isSelectable() {
return isSelectable;
}
@Override
public CommitsAdapter withSelectable(boolean selectable) {
this.isSelectable = selectable;
return this;
}
@Override
public int getType() {
return R.id.commitList;
}
@Override
public int getLayoutRes() {
return R.layout.list_commits;
} }
@NonNull @NonNull
@Override @Override
public CommitsAdapter.ViewHolder getViewHolder(@NonNull View v) { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new CommitsAdapter.ViewHolder(v); LayoutInflater inflater = LayoutInflater.from(ctx);
if(viewType == TYPE_LOAD) {
return new CommitsHolder(inflater.inflate(R.layout.list_commits, parent, false));
}
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
} }
public class ViewHolder extends FastAdapter.ViewHolder<CommitsAdapter> { @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
final TinyDB tinyDb = new TinyDB(ctx); if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
TextView commitTitleVw; isLoading = true;
TextView commitCommitterVw; loadMoreListener.onLoadMore();
TextView commitDateVw;
TextView commitHtmlUrlVw;
public ViewHolder(View itemView) { }
if(getItemViewType(position) == TYPE_LOAD) {
((CommitsHolder) holder).bindData(commitsList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(commitsList.get(position).getSha() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return commitsList.size();
}
class CommitsHolder extends RecyclerView.ViewHolder {
TextView commitTitle;
TextView commitCommitter;
TextView commitDate;
Button commitHtmlUrl;
CommitsHolder(View itemView) {
super(itemView); super(itemView);
commitTitleVw = itemView.findViewById(R.id.commitTitleVw); commitTitle = itemView.findViewById(R.id.commitTitleVw);
commitCommitterVw = itemView.findViewById(R.id.commitCommitterVw); commitCommitter = itemView.findViewById(R.id.commitCommitterVw);
commitDateVw = itemView.findViewById(R.id.commitDateVw); commitDate = itemView.findViewById(R.id.commitDateVw);
commitHtmlUrlVw = itemView.findViewById(R.id.commitHtmlUrlVw); commitHtmlUrl = itemView.findViewById(R.id.commitHtmlUrlVw);
} }
@Override @SuppressLint("SetTextI18n")
public void bindView(CommitsAdapter item, @NonNull List<Object> payloads) { void bindData(Commits commitsModel) {
commitTitleVw.setText(item.getCommitTitle()); final TinyDB tinyDb = new TinyDB(ctx);
commitCommitterVw.setText(ctx.getString(R.string.commitCommittedBy, item.getcommitCommitter())); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
commitDateVw.setText(TimeHelper.formatTime(item.getcommitDate(), new Locale(locale), timeFormat, ctx)); commitTitle.setText(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));
if(timeFormat.equals("pretty")) { if(timeFormat.equals("pretty")) {
commitDateVw.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getcommitDate()), ctx)); commitDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(commitsModel.getCommit().getCommitter().getDate()), ctx));
} }
commitHtmlUrlVw.setText(Html.fromHtml("<a href='" + item.getCommitHtmlUrl() + "'>" + ctx.getResources().getString(R.string.viewInBrowser) + "</a> ")); commitHtmlUrl.setOnClickListener(v -> ctx.startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(commitsModel.getHtml_url()))));
commitHtmlUrlVw.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
public void unbindView(@NonNull CommitsAdapter item) {
commitTitleVw.setText(null);
commitCommitterVw.setText(null);
commitDateVw.setText(null);
commitHtmlUrlVw.setText(null);
} }
} }
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

@ -25,7 +25,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository; import org.mian.gitnex.models.WatchInfo;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.List; import java.util.List;
import retrofit2.Call; import retrofit2.Call;
@ -95,16 +95,16 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
final String repoName = parts[1]; final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository(); WatchInfo watch = new WatchInfo();
Call<WatchRepository> call; Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() { call.enqueue(new Callback<WatchInfo>() {
@Override @Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) { public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.isSuccessful()) { if(response.isSuccessful()) {
@ -126,7 +126,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
} }
@Override @Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
@ -192,7 +192,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
@Override @Override
public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repos, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new ExploreRepositoriesAdapter.ReposSearchViewHolder(v); return new ExploreRepositoriesAdapter.ReposSearchViewHolder(v);
} }

View File

@ -1,138 +1,267 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.HorizontalScrollView; import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.helpers.DiffTextView;
import org.mian.gitnex.models.FileDiffView; import org.mian.gitnex.models.FileDiffView;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
/** /**
* Author M M Arif * Author opyale
*/ */
public class FilesDiffAdapter extends RecyclerView.Adapter<FilesDiffAdapter.FilesDiffViewHolder> { public class FilesDiffAdapter extends BaseAdapter {
private List<FileDiffView> dataList; private static Map<Long, View> selectedViews;
private Context ctx; private static final int MAXIMUM_LINES = 5000;
static class FilesDiffViewHolder extends RecyclerView.ViewHolder { private static int COLOR_ADDED;
private static int COLOR_REMOVED;
private static int COLOR_NORMAL;
private static int COLOR_SELECTED;
private static int COLOR_FONT;
private TextView fileContents; private Context context;
private TextView fileName; private List<FileDiffView> fileDiffViews;
private TextView fileInfo;
private ImageView fileImage;
private HorizontalScrollView fileContentsView;
private LinearLayout allLines;
private FilesDiffViewHolder(View itemView) { public FilesDiffAdapter(Context context, List<FileDiffView> fileDiffViews) {
super(itemView);
fileContents = itemView.findViewById(R.id.fileContents); this.context = context;
fileName = itemView.findViewById(R.id.fileName); this.fileDiffViews = fileDiffViews;
fileInfo = itemView.findViewById(R.id.fileInfo);
fileImage = itemView.findViewById(R.id.fileImage);
fileContentsView = itemView.findViewById(R.id.fileContentsView);
allLines = itemView.findViewById(R.id.allLinesLayout);
} selectedViews = new ConcurrentSkipListMap<>();
}
public FilesDiffAdapter(List<FileDiffView> dataListMain, Context ctx) { COLOR_ADDED = getColorFromAttribute(R.attr.diffAddedColor);
this.dataList = dataListMain; COLOR_REMOVED = getColorFromAttribute(R.attr.diffRemovedColor);
this.ctx = ctx; COLOR_NORMAL = getColorFromAttribute(R.attr.primaryBackgroundColor);
} COLOR_SELECTED = getColorFromAttribute(R.attr.diffSelectedColor);
COLOR_FONT = getColorFromAttribute(R.attr.inputTextColor);
@NonNull }
@Override
public FilesDiffAdapter.FilesDiffViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_files_diffs, parent, false);
return new FilesDiffAdapter.FilesDiffViewHolder(v);
}
@Override @Override
public void onBindViewHolder(@NonNull FilesDiffViewHolder holder, int position) { public int getCount() {
FileDiffView data = dataList.get(position); return fileDiffViews.size();
}
if(data.isFileType()) { @Override
public Object getItem(int position) {
holder.fileName.setText(data.getFileName()); return fileDiffViews.get(position);
}
holder.fileInfo.setVisibility(View.GONE); @Override
public long getItemId(int position) {
//byte[] imageData = Base64.decode(data.getFileContents(), Base64.DEFAULT); return position;
//Drawable imageDrawable = new BitmapDrawable(ctx.getResources(), BitmapFactory.decodeByteArray(imageData, 0, imageData.length)); }
//holder.fileImage.setImageDrawable(imageDrawable);
holder.fileContentsView.setVisibility(View.GONE);
} @SuppressLint({"ViewHolder", "InflateParams"})
else { @Override
public View getView(int position, View convertView, ViewGroup parent) {
String[] splitData = data.getFileContents().split("\\R"); convertView = LayoutInflater.from(context).inflate(R.layout.list_files_diffs, null, false);
for (String eachSplit : splitData) { TextView headerFileName = convertView.findViewById(R.id.headerFileName);
TextView headerFileInfo = convertView.findViewById(R.id.headerFileInfo);
ImageView footerImage = convertView.findViewById(R.id.footerImage);
LinearLayout diffStats = convertView.findViewById(R.id.diff_stats);
LinearLayout diffLines = convertView.findViewById(R.id.diffLines);
TextView textLine = new TextView(ctx); FileDiffView data = (FileDiffView) getItem(position);
textLine.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); headerFileName.setText(data.getFileName());
if (eachSplit.startsWith("+")) { if(data.isFileType()) {
textLine.setText(eachSplit); diffStats.setVisibility(View.GONE);
holder.allLines.addView(textLine); diffLines.addView(getMessageView(context.getResources().getString(R.string.binaryFileError)));
textLine.setTextColor(ctx.getResources().getColor(R.color.colorPrimary)); }
textLine.setPadding(5, 5, 5, 5); else {
textLine.setBackgroundColor(ctx.getResources().getColor(R.color.diffAddedColor));
} diffStats.setVisibility(View.VISIBLE);
else if (eachSplit.startsWith("-")) { headerFileInfo.setText(data.getFileInfo());
textLine.setText(eachSplit); String[] codeLines = getLines(data.getFileContents());
holder.allLines.addView(textLine);
textLine.setTextColor(ctx.getResources().getColor(R.color.colorPrimary)); if(MAXIMUM_LINES > codeLines.length) {
textLine.setPadding(5, 5, 5, 5);
textLine.setBackgroundColor(ctx.getResources().getColor(R.color.diffRemovedColor));
} for(int l=0; l<codeLines.length; l++) {
else {
if(eachSplit.length() > 0) { if(codeLines[l].length() > 0) {
textLine.setText(eachSplit);
holder.allLines.addView(textLine);
textLine.setTextColor(ctx.getResources().getColor(R.color.colorPrimary)); int uniquePosition = l + (position * MAXIMUM_LINES);
textLine.setPadding(5, 5, 5, 5);
textLine.setBackgroundColor(ctx.getResources().getColor(R.color.white));
}
} DiffTextView diffTextView = new DiffTextView(context);
} diffTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
diffTextView.setPadding(15, 2, 15, 2);
diffTextView.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf"));
diffTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
diffTextView.setPosition(uniquePosition);
holder.fileName.setText(data.getFileName()); boolean isSelected = false;
if(!data.getFileInfo().equals("")) {
holder.fileInfo.setText(ctx.getResources().getString(R.string.fileDiffInfoChanges, data.getFileInfo()));
}
else {
holder.fileInfo.setVisibility(View.GONE);
}
} for(View view : selectedViews.values()) {
} if(((DiffTextView) view).getPosition() == uniquePosition) {
@Override diffTextView.setBackgroundColor(COLOR_SELECTED);
public int getItemCount() { isSelected = true;
return dataList.size(); break;
}
} }
}
if(codeLines[l].startsWith("+")) {
diffTextView.setText(codeLines[l]);
diffTextView.setTextColor(COLOR_FONT);
if(!isSelected) {
diffTextView.setInitialBackgroundColor(COLOR_ADDED);
}
}
else if(codeLines[l].startsWith("-")) {
diffTextView.setText(codeLines[l]);
diffTextView.setTextColor(COLOR_FONT);
if(!isSelected) {
diffTextView.setInitialBackgroundColor(COLOR_REMOVED);
}
}
else {
diffTextView.setText(codeLines[l]);
diffTextView.setTextColor(COLOR_FONT);
if(!isSelected) {
diffTextView.setInitialBackgroundColor(COLOR_NORMAL);
}
}
diffTextView.setOnClickListener(v -> {
if(((DiffTextView) v).getCurrentBackgroundColor() != COLOR_SELECTED) {
selectedViews.put(((DiffTextView) v).getPosition(), v);
v.setBackgroundColor(COLOR_SELECTED);
}
else {
selectedViews.remove(((DiffTextView) v).getPosition());
v.setBackgroundColor(((DiffTextView) v).getInitialBackgroundColor());
}
});
diffTextView.setOnLongClickListener(v -> {
if(((DiffTextView) v).getCurrentBackgroundColor() == COLOR_SELECTED) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("```\n");
for(View view : selectedViews.values()) {
stringBuilder.append(((DiffTextView) view).getText());
stringBuilder.append("\n");
}
stringBuilder.append("```\n\n");
selectedViews.clear();
Intent intent = new Intent(context, ReplyToIssueActivity.class);
intent.putExtra("commentBody", stringBuilder.toString());
intent.putExtra("cursorToEnd", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
return true;
});
diffLines.addView(diffTextView);
}
}
}
else {
diffLines.addView(getMessageView(context.getResources().getString(R.string.fileTooLarge)));
}
}
return convertView;
}
private TextView getMessageView(String message) {
TextView textView = new TextView(context);
textView.setTextColor(COLOR_FONT);
textView.setBackgroundColor(COLOR_NORMAL);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
textView.setPadding(15, 15, 15, 15);
textView.setTypeface(Typeface.DEFAULT);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setText(message);
return textView;
}
private String[] getLines(String content) {
return content.split("\\R");
}
private int getColorFromAttribute(int resid) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(resid, typedValue, true);
return typedValue.data;
}
}

View File

@ -11,29 +11,28 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.gson.JsonElement;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity; import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.models.IssueComments;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.ClickListener;
import org.ocpsoft.prettytime.PrettyTime;
import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin; import io.noties.markwon.core.CorePlugin;
@ -42,7 +41,6 @@ import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.AsyncDrawable;
import io.noties.markwon.image.DefaultMediaDecoder; import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem; import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.ImagesPlugin;
@ -50,6 +48,8 @@ import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder; import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder; import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -60,14 +60,20 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
private List<IssueComments> issuesComments; private List<IssueComments> issuesComments;
private Context mCtx; private Context mCtx;
static class IssueCommentViewHolder extends RecyclerView.ViewHolder { public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {
this.mCtx = mCtx;
this.issuesComments = issuesCommentsMain;
}
class IssueCommentViewHolder extends RecyclerView.ViewHolder {
private TextView issueNumber; private TextView issueNumber;
private TextView commendId; private TextView commendId;
private ImageView issueCommenterAvatar; private ImageView issueCommenterAvatar;
private TextView issueComment; private TextView issueComment;
private TextView issueCommentDate; private TextView issueCommentDate;
private ImageView commentsOptionsMenu;
private TextView commendBodyRaw; private TextView commendBodyRaw;
private TextView commentModified; private TextView commentModified;
private TextView commenterUsername; private TextView commenterUsername;
@ -82,7 +88,7 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar); issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar);
issueComment = itemView.findViewById(R.id.issueComment); issueComment = itemView.findViewById(R.id.issueComment);
issueCommentDate = itemView.findViewById(R.id.issueCommentDate); issueCommentDate = itemView.findViewById(R.id.issueCommentDate);
commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu); ImageView commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu);
commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw); commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw);
commentModified = itemView.findViewById(R.id.commentModified); commentModified = itemView.findViewById(R.id.commentModified);
commenterUsername = itemView.findViewById(R.id.commenterUsername); commenterUsername = itemView.findViewById(R.id.commenterUsername);
@ -90,32 +96,32 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
commentsOptionsMenu.setOnClickListener(v -> { commentsOptionsMenu.setOnClickListener(v -> {
final Context context = v.getContext(); final Context ctx = v.getContext();
final TinyDB tinyDb = new TinyDB(context); final TinyDB tinyDb = new TinyDB(ctx);
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_issue_comments, null); @SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_issue_comments, null);
TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit); TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit);
TextView commentShare = view.findViewById(R.id.issueCommentShare); TextView commentShare = view.findViewById(R.id.issueCommentShare);
//TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete); TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete);
if(!loginUid.contentEquals(commenterUsername.getText())) { if(!loginUid.contentEquals(commenterUsername.getText())) {
commentMenuEdit.setVisibility(View.GONE); commentMenuEdit.setVisibility(View.GONE);
//commentMenuDelete.setVisibility(View.GONE); commentMenuDelete.setVisibility(View.GONE);
} }
BottomSheetDialog dialog = new BottomSheetDialog(context); BottomSheetDialog dialog = new BottomSheetDialog(ctx);
dialog.setContentView(view); dialog.setContentView(view);
dialog.show(); dialog.show();
commentMenuEdit.setOnClickListener(ediComment -> { commentMenuEdit.setOnClickListener(ediComment -> {
Intent intent = new Intent(context, ReplyToIssueActivity.class); Intent intent = new Intent(ctx, ReplyToIssueActivity.class);
intent.putExtra("commentId", commendId.getText()); intent.putExtra("commentId", commendId.getText());
intent.putExtra("commentAction", "edit"); intent.putExtra("commentAction", "edit");
intent.putExtra("commentBody", commendBodyRaw.getText()); intent.putExtra("commentBody", commendBodyRaw.getText());
context.startActivity(intent); ctx.startActivity(intent);
dialog.dismiss(); dialog.dismiss();
}); });
@ -128,20 +134,21 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
// share issue comment // share issue comment
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain"); sharingIntent.setType("text/plain");
String intentHeader = tinyDb.getString("issueNumber") + context.getResources().getString(R.string.hash) + "issuecomment-" + commendId.getText() + " " + tinyDb.getString("issueTitle"); String intentHeader = tinyDb.getString("issueNumber") + ctx.getResources().getString(R.string.hash) + "issuecomment-" + commendId.getText() + " " + tinyDb.getString("issueTitle");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, intentHeader); sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, intentHeader);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, commentUrl); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, commentUrl);
context.startActivity(Intent.createChooser(sharingIntent, intentHeader)); ctx.startActivity(Intent.createChooser(sharingIntent, intentHeader));
dialog.dismiss(); dialog.dismiss();
}); });
/*commentMenuDelete.setOnClickListener(deleteComment -> { commentMenuDelete.setOnClickListener(deleteComment -> {
dialog.dismiss(); deleteIssueComment(ctx, Integer.parseInt(commendId.getText().toString()), getAdapterPosition());
dialog.dismiss();
});*/ });
}); });
@ -149,10 +156,79 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
} }
public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) { private void updateAdapter(int position) {
this.mCtx = mCtx; issuesComments.remove(position);
this.issuesComments = issuesCommentsMain; notifyItemRemoved(position);
notifyItemRangeChanged(position, issuesComments.size());
}
private void deleteIssueComment(final Context ctx, final int commentId, int position) {
final TinyDB tinyDb = new TinyDB(ctx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String[] repoFullName = tinyDb.getString("repoFullName").split("/");
if (repoFullName.length != 2) {
return;
}
final String repoOwner = repoFullName[0];
final String repoName = repoFullName[1];
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.deleteComment(instanceToken, repoOwner, repoName, commentId);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 204) {
updateAdapter(position);
Toasty.info(ctx, ctx.getResources().getString(R.string.deleteCommentSuccess));
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.info(ctx, ctx.getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
}
});
} }
@ -218,20 +294,13 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
return Collections.singleton("drawable"); return Collections.singleton("drawable");
} }
}); });
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() { plugin.placeholderProvider(drawable -> null);
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false)); plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources())); plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create()); plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources())); plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
} }
})).usePlugin(new AbstractMarkwonPlugin() { })).usePlugin(new AbstractMarkwonPlugin() {

View File

@ -1,29 +1,28 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.Html; import android.text.Html;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.items.AbstractItem;
import com.mikepenz.fastadapter.listeners.ClickEventHook;
import com.mikepenz.fastadapter.utils.EventHookUtil;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime; import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -31,112 +30,74 @@ import java.util.Locale;
* Author M M Arif * Author M M Arif
*/ */
public class IssuesAdapter extends AbstractItem<IssuesAdapter, IssuesAdapter.ViewHolder> { public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final private Context ctx; private Context context;
private String issueTitle; private final int TYPE_LOAD = 0;
private int issueNumber; private List<Issues> issuesList;
private String issueAssigneeAvatar; private OnLoadMoreListener loadMoreListener;
private Date issueCreatedTime; private boolean isLoading = false, isMoreDataAvailable = true;
private int issueCommentsCount;
private String userFullname;
private String userLogin;
private boolean isSelectable = true; public IssuesAdapter(Context context, List<Issues> issuesListMain) {
public IssuesAdapter(Context ctx) { this.context = context;
this.ctx = ctx; this.issuesList = issuesListMain;
}
public IssuesAdapter withNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) {
this.setNewItems(issueTitle, issueNumber, issueAssigneeAvatar, issueCreatedTime, issueCommentsCount, userFullname, userLogin);
return this;
}
private void setNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) {
this.issueTitle = issueTitle;
this.issueNumber = issueNumber;
this.issueAssigneeAvatar = issueAssigneeAvatar;
this.issueCreatedTime = issueCreatedTime;
this.issueCommentsCount = issueCommentsCount;
this.userFullname = userFullname;
this.userLogin = userLogin;
}
private int getIssueNumber() {
return issueNumber;
}
public String getIssueTitle() {
return issueTitle;
}
private String getIssueAssigneeAvatar() {
return issueAssigneeAvatar;
}
private Date getIssueCreatedTime() {
return issueCreatedTime;
}
private int getIssueCommentsCount() {
return issueCommentsCount;
}
private String getUserFullname() {
return userFullname;
}
private String getUserLogin() {
return userLogin;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public IssuesAdapter withEnabled(boolean enabled) {
return null;
}
@Override
public boolean isSelectable() {
return isSelectable;
}
@Override
public IssuesAdapter withSelectable(boolean selectable) {
this.isSelectable = selectable;
return this;
}
@Override
public int getType() {
return R.id.relativeLayoutFrameIssuesList;
}
@Override
public int getLayoutRes() {
return R.layout.list_issues;
} }
@NonNull @NonNull
@Override @Override
public IssuesAdapter.ViewHolder getViewHolder(@NonNull View v) { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new IssuesAdapter.ViewHolder(v);
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new IssuesHolder(inflater.inflate(R.layout.list_issues, parent, false));
}
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
} }
public class ViewHolder extends FastAdapter.ViewHolder<IssuesAdapter> { @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
final TinyDB tinyDb = new TinyDB(ctx); if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((IssuesHolder) holder).bindData(issuesList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(issuesList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return issuesList.size();
}
class IssuesHolder extends RecyclerView.ViewHolder {
private TextView issueNumber; private TextView issueNumber;
private ImageView issueAssigneeAvatar; private ImageView issueAssigneeAvatar;
@ -144,7 +105,7 @@ public class IssuesAdapter extends AbstractItem<IssuesAdapter, IssuesAdapter.Vie
private TextView issueCreatedTime; private TextView issueCreatedTime;
private TextView issueCommentsCount; private TextView issueCommentsCount;
public ViewHolder(View itemView) { IssuesHolder(View itemView) {
super(itemView); super(itemView);
@ -152,94 +113,124 @@ public class IssuesAdapter extends AbstractItem<IssuesAdapter, IssuesAdapter.Vie
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle); issueTitle = itemView.findViewById(R.id.issueTitle);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount); issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime); issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
issueTitle.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
});
frameCommentsCount.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
});
} }
@Override @SuppressLint("SetTextI18n")
public void bindView(@NonNull IssuesAdapter item, @NonNull List<Object> payloads) { void bindData(Issues issuesModel) {
if (!item.getUserFullname().equals("")) { final TinyDB tinyDb = new TinyDB(context);
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserFullname(), ctx)); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
if(!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} }
else { else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserLogin(), ctx)); issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
} }
PicassoService.getInstance(ctx).get().load(item.getIssueAssigneeAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar); PicassoService.getInstance(context).get().load(issuesModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
String issueNumber_ = "<font color='" + ctx.getResources().getColor(R.color.lightGray) + "'>" + ctx.getResources().getString(R.string.hash) + item.getIssueNumber() + "</font>"; String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + item.getIssueTitle())); issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
issueNumber.setText(String.valueOf(item.getIssueNumber())); issueNumber.setText(String.valueOf(issuesModel.getNumber()));
issueCommentsCount.setText(String.valueOf(item.getIssueCommentsCount())); issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
switch (timeFormat) {
switch(timeFormat) {
case "pretty": { case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale)); PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(item.getIssueCreatedTime()); String createdTime = prettyTime.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime); issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getIssueCreatedTime()), ctx)); issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
break; break;
} }
case "normal": { case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + ctx.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", new Locale(locale));
String createdTime = formatter.format(item.getIssueCreatedTime()); String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime); issueCreatedTime.setText(createdTime);
break; break;
} }
case "normal1": { case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + ctx.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", new Locale(locale));
String createdTime = formatter.format(item.getIssueCreatedTime()); String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime); issueCreatedTime.setText(createdTime);
break; break;
} }
} }
} }
@Override
public void unbindView(@NonNull IssuesAdapter item) {
issueTitle.setText(null);
issueCommentsCount.setText(null);
issueCreatedTime.setText(null);
}
} }
public static class IssueTitleClickEvent extends ClickEventHook<IssuesAdapter> { static class LoadHolder extends RecyclerView.ViewHolder {
@Nullable LoadHolder(View itemView) {
@Override
public List<View> onBindMany(@NonNull RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof IssuesAdapter.ViewHolder) {
return EventHookUtil.toList(((ViewHolder) viewHolder).issueTitle);
}
return super.onBindMany(viewHolder);
super(itemView);
} }
@Override }
public void onClick(View v, int position, @NonNull FastAdapter<IssuesAdapter> fastAdapter, IssuesAdapter item) {
Context context = v.getContext(); public void setMoreDataAvailable(boolean moreDataAvailable) {
Intent intent = new Intent(context, IssueDetailActivity.class); isMoreDataAvailable = moreDataAvailable;
intent.putExtra("issueNumber", item.getIssueNumber());
TinyDB tinyDb = new TinyDB(context); }
tinyDb.putString("issueNumber", String.valueOf(item.getIssueNumber()));
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
} 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) {
issuesList = list;
notifyDataSetChanged();
} }
} }

View File

@ -6,35 +6,34 @@ import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.text.Spanned; import android.text.Spanned;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.MilestoneActions; import org.mian.gitnex.actions.MilestoneActions;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin; import io.noties.markwon.core.CorePlugin;
@ -55,13 +54,57 @@ import io.noties.markwon.linkify.LinkifyPlugin;
* Author M M Arif * Author M M Arif
*/ */
public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.MilestonesViewHolder> implements Filterable { public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Milestones> milestonesList; private Context context;
private Context mCtx; private final int TYPE_LOAD = 0;
private List<Milestones> milestonesListFull; private List<Milestones> dataList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false;
private boolean isMoreDataAvailable = true;
private String TAG = StaticGlobalVariables.tagMilestonesAdapter;
static class MilestonesViewHolder extends RecyclerView.ViewHolder { public MilestonesAdapter(Context context, List<Milestones> dataListMain) {
this.context = context;
this.dataList = dataListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new MilestonesAdapter.DataHolder(inflater.inflate(R.layout.list_milestones, parent, false));
}
else {
return new MilestonesAdapter.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) {
((MilestonesAdapter.DataHolder) holder).bindData(dataList.get(position));
}
}
class DataHolder extends RecyclerView.ViewHolder {
private TextView milestoneId; private TextView milestoneId;
private TextView msTitle; private TextView msTitle;
@ -71,9 +114,10 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
private TextView msDueDate; private TextView msDueDate;
private ImageView msStatus; private ImageView msStatus;
private ProgressBar msProgress; private ProgressBar msProgress;
private TextView milestoneStatus; private TextView milestoneStatus;
DataHolder(View itemView) {
private MilestonesViewHolder(View itemView) {
super(itemView); super(itemView);
milestoneId = itemView.findViewById(R.id.milestoneId); milestoneId = itemView.findViewById(R.id.milestoneId);
@ -84,8 +128,8 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
msClosedIssues = itemView.findViewById(R.id.milestoneIssuesClosed); msClosedIssues = itemView.findViewById(R.id.milestoneIssuesClosed);
msDueDate = itemView.findViewById(R.id.milestoneDueDate); msDueDate = itemView.findViewById(R.id.milestoneDueDate);
msProgress = itemView.findViewById(R.id.milestoneProgress); msProgress = itemView.findViewById(R.id.milestoneProgress);
ImageView milestonesMenu = itemView.findViewById(R.id.milestonesMenu); ImageView milestonesMenu = itemView.findViewById(R.id.milestonesMenu);
milestoneStatus = itemView.findViewById(R.id.milestoneStatus); milestoneStatus = itemView.findViewById(R.id.milestoneStatus);
milestonesMenu.setOnClickListener(v -> { milestonesMenu.setOnClickListener(v -> {
@ -94,269 +138,287 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
@SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_milestones_in_list, null); @SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_milestones_in_list, null);
TextView closeMilestone = view.findViewById(R.id.closeMilestone); TextView closeMilestone = view.findViewById(R.id.closeMilestone);
TextView openMilestone = view.findViewById(R.id.openMilestone); TextView openMilestone = view.findViewById(R.id.openMilestone);
BottomSheetDialog dialog = new BottomSheetDialog(ctx); BottomSheetDialog dialog = new BottomSheetDialog(ctx);
dialog.setContentView(view); dialog.setContentView(view);
dialog.show(); dialog.show();
if(milestoneStatus.getText().toString().equals("open")) { if(milestoneStatus.getText().toString().equals("open")) {
closeMilestone.setVisibility(View.VISIBLE); closeMilestone.setVisibility(View.VISIBLE);
openMilestone.setVisibility(View.GONE); openMilestone.setVisibility(View.GONE);
} }
else { else {
closeMilestone.setVisibility(View.GONE); closeMilestone.setVisibility(View.GONE);
openMilestone.setVisibility(View.VISIBLE); openMilestone.setVisibility(View.VISIBLE);
} }
closeMilestone.setOnClickListener(v12 -> { closeMilestone.setOnClickListener(v12 -> {
MilestoneActions.closeMilestone(ctx, milestoneId_); MilestoneActions.closeMilestone(ctx, milestoneId_);
dialog.dismiss(); dialog.dismiss();
updateAdapter(getAdapterPosition());
}); });
openMilestone.setOnClickListener(v12 -> { openMilestone.setOnClickListener(v12 -> {
MilestoneActions.openMilestone(ctx, milestoneId_); MilestoneActions.openMilestone(ctx, milestoneId_);
dialog.dismiss(); dialog.dismiss();
updateAdapter(getAdapterPosition());
}); });
}); });
} }
}
public MilestonesAdapter(Context mCtx, List<Milestones> milestonesMain) { @SuppressLint("SetTextI18n")
this.mCtx = mCtx; void bindData(Milestones dataModel) {
this.milestonesList = milestonesMain;
milestonesListFull = new ArrayList<>(milestonesList);
}
@NonNull final TinyDB tinyDb = new TinyDB(context);
@Override final String locale = tinyDb.getString("locale");
public MilestonesAdapter.MilestonesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { final String timeFormat = tinyDb.getString("dateFormat");
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_milestones, parent, false);
return new MilestonesAdapter.MilestonesViewHolder(v);
}
@Override milestoneId.setText(String.valueOf(dataModel.getId()));
public void onBindViewHolder(@NonNull MilestonesAdapter.MilestonesViewHolder holder, int position) { milestoneStatus.setText(dataModel.getState());
final TinyDB tinyDb = new TinyDB(mCtx); final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
final String locale = tinyDb.getString("locale"); .usePlugin(CorePlugin.create())
final String timeFormat = tinyDb.getString("dateFormat"); .usePlugin(ImagesPlugin.create(plugin -> {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
Milestones currentItem = milestonesList.get(position); final int resourceId = context.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
context.getPackageName());
holder.milestoneId.setText(String.valueOf(currentItem.getId())); final Drawable drawable = context.getDrawable(resourceId);
holder.milestoneStatus.setText(currentItem.getState());
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)) assert drawable != null;
.usePlugin(CorePlugin.create()) return ImageItem.withResult(drawable);
.usePlugin(ImagesPlugin.create(plugin -> { }
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull @NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(drawable -> null);
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(context.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(context.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
final int resourceId = mCtx.getResources().getIdentifier( .codeTextColor(tinyDb.getInt("codeBlockColor"))
raw.substring("drawable://".length()), .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
"drawable", .linkColor(context.getResources().getColor(R.color.lightBlue));
mCtx.getPackageName());
final Drawable drawable = mCtx.getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
} }
})
.usePlugin(TablePlugin.create(context))
.usePlugin(TaskListPlugin.create(context))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
@NonNull Spanned msTitle_ = markwon.toMarkdown(dataModel.getTitle());
@Override markwon.setParsedMarkdown(msTitle, msTitle_);
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(drawable -> null);
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
Spanned msTitle = markwon.toMarkdown(currentItem.getTitle()); if(dataModel.getState().equals("open")) {
markwon.setParsedMarkdown(holder.msTitle, msTitle);
if(currentItem.getState().equals("open")) { @SuppressLint("ResourceType") int color = Color.parseColor(context.getResources().getString(R.color.releaseStable));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
//.useFont(Typeface.DEFAULT)
.textColor(context.getResources().getColor(R.color.white))
.fontSize(30)
.toUpperCase()
.width(120)
.height(60)
.endConfig()
.buildRoundRect("open", color, 8);
@SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.releaseStable)); msStatus.setImageDrawable(drawable);
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
//.useFont(Typeface.DEFAULT)
.textColor(mCtx.getResources().getColor(R.color.white))
.fontSize(30)
.toUpperCase()
.width(120)
.height(60)
.endConfig()
.buildRoundRect("open", color, 8);
holder.msStatus.setImageDrawable(drawable); }
else if(dataModel.getState().equals("closed")) {
} @SuppressLint("ResourceType") int color = Color.parseColor(context.getResources().getString(R.color.colorRed));
else if(currentItem.getState().equals("closed")) { TextDrawable drawable = TextDrawable.builder()
.beginConfig()
//.useFont(Typeface.DEFAULT)
.textColor(context.getResources().getColor(R.color.white))
.fontSize(30)
.toUpperCase()
.width(140)
.height(60)
.endConfig()
.buildRoundRect("closed", color, 8);
@SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.colorRed)); msStatus.setImageDrawable(drawable);
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
//.useFont(Typeface.DEFAULT)
.textColor(mCtx.getResources().getColor(R.color.white))
.fontSize(30)
.toUpperCase()
.width(140)
.height(60)
.endConfig()
.buildRoundRect("closed", color, 8);
holder.msStatus.setImageDrawable(drawable); }
} if (!dataModel.getDescription().equals("")) {
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(dataModel.getDescription()));
if (!currentItem.getDescription().equals("")) { msDescription.setText(bodyWithMD);
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getDescription()));
holder.msDescription.setText(bodyWithMD);
}
else {
holder.msDescription.setText("");
}
holder.msOpenIssues.setText(String.valueOf(currentItem.getOpen_issues()));
holder.msOpenIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneOpenIssues, currentItem.getOpen_issues()), mCtx));
holder.msClosedIssues.setText(String.valueOf(currentItem.getClosed_issues()));
holder.msClosedIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneClosedIssues, currentItem.getClosed_issues()), mCtx));
if ((currentItem.getOpen_issues() + currentItem.getClosed_issues()) > 0) {
if (currentItem.getOpen_issues() == 0) {
holder.msProgress.setProgress(100);
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 100), mCtx));
} }
else { else {
int msCompletion = 100 * currentItem.getClosed_issues() / (currentItem.getOpen_issues() + currentItem.getClosed_issues()); msDescription.setText("");
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, msCompletion), mCtx)); }
holder.msProgress.setProgress(msCompletion);
msOpenIssues.setText(String.valueOf(dataModel.getOpen_issues()));
msOpenIssues.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneOpenIssues, dataModel.getOpen_issues()), context));
msClosedIssues.setText(String.valueOf(dataModel.getClosed_issues()));
msClosedIssues.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneClosedIssues, dataModel.getClosed_issues()), context));
if ((dataModel.getOpen_issues() + dataModel.getClosed_issues()) > 0) {
if (dataModel.getOpen_issues() == 0) {
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);
}
}
else {
msProgress.setProgress(0);
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 0), context));
}
if(dataModel.getDue_on() != null) {
if (timeFormat.equals("normal") || timeFormat.equals("pretty")) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
Date date = null;
try {
date = formatter.parse(dataModel.getDue_on());
}
catch (ParseException e) {
Log.e(TAG, e.toString());
}
assert date != null;
String dueDate = formatter.format(date);
if(date.before(new Date())) {
msDueDate.setTextColor(context.getResources().getColor(R.color.darkRed));
}
msDueDate.setText(dueDate);
msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(dataModel.getDue_on()), context));
}
else if (timeFormat.equals("normal1")) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
Date date1 = null;
try {
date1 = formatter.parse(dataModel.getDue_on());
}
catch (ParseException e) {
Log.e(TAG, e.toString());
}
assert date1 != null;
String dueDate = formatter.format(date1);
msDueDate.setText(dueDate);
}
}
else {
msDueDate.setText("");
} }
} }
else {
holder.msProgress.setProgress(0);
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 0), mCtx));
}
if(currentItem.getDue_on() != null) { }
if (timeFormat.equals("normal") || timeFormat.equals("pretty")) { private void updateAdapter(int position) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
Date date = null;
try {
date = formatter.parse(currentItem.getDue_on());
} catch (ParseException e) {
e.printStackTrace();
}
assert date != null;
String dueDate = formatter.format(date);
if(date.before(new Date())) { dataList.remove(position);
holder.msDueDate.setTextColor(mCtx.getResources().getColor(R.color.darkRed)); notifyItemRemoved(position);
} notifyItemRangeChanged(position, dataList.size());
holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate)); }
holder.msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(currentItem.getDue_on()), mCtx));
} else if (timeFormat.equals("normal1")) { @Override
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale)); public int getItemViewType(int position) {
Date date1 = null;
try {
date1 = formatter.parse(currentItem.getDue_on());
} catch (ParseException e) {
e.printStackTrace();
}
assert date1 != null;
String dueDate = formatter.format(date1);
holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate));
}
if(dataList.get(position).getTitle() != null) {
return TYPE_LOAD;
} }
else { else {
holder.msDueDate.setText(""); return 1;
} }
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return milestonesList.size();
return dataList.size();
} }
@Override static class LoadHolder extends RecyclerView.ViewHolder {
public Filter getFilter() {
return milestoneFilter; LoadHolder(View itemView) {
super(itemView);
}
} }
private Filter milestoneFilter = new Filter() { public void setMoreDataAvailable(boolean moreDataAvailable) {
@Override isMoreDataAvailable = moreDataAvailable;
protected FilterResults performFiltering(CharSequence constraint) {
List<Milestones> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) { }
filteredList.addAll(milestonesListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Milestones item : milestonesListFull) { public void notifyDataChanged() {
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults(); notifyDataSetChanged();
results.values = filteredList; isLoading = false;
return results; }
}
@Override public interface OnLoadMoreListener {
protected void publishResults(CharSequence constraint, FilterResults results) {
milestonesList.clear();
milestonesList.addAll((List) results.values);
notifyDataSetChanged();
}
}; void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Milestones> list) {
dataList = list;
notifyDataSetChanged();
}
} }

View File

@ -7,6 +7,7 @@ import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
@ -24,7 +25,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository; import org.mian.gitnex.models.WatchInfo;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -45,59 +46,62 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
static class MyReposViewHolder extends RecyclerView.ViewHolder { static class MyReposViewHolder extends RecyclerView.ViewHolder {
private ImageView imageMy; private ImageView imageAvatar;
private TextView mTextView1My; private TextView repoName;
private TextView mTextView2My; private TextView repoDescription;
private TextView fullNameMy; private TextView repoFullName;
private ImageView repoPrivatePublicMy; private ImageView repoPrivatePublic;
private TextView repoStarsMy; private TextView repoStars;
private TextView repoForksMy; private TextView repoForks;
private TextView repoOpenIssuesCountMy; private TextView repoOpenIssuesCount;
private TextView repoType; private TextView repoType;
private CheckBox isRepoAdmin;
private MyReposViewHolder(View itemView) { private MyReposViewHolder(View itemView) {
super(itemView); super(itemView);
mTextView1My = itemView.findViewById(R.id.repoNameMy); repoName = itemView.findViewById(R.id.repoName);
mTextView2My = itemView.findViewById(R.id.repoDescriptionMy); repoDescription = itemView.findViewById(R.id.repoDescription);
imageMy = itemView.findViewById(R.id.imageAvatarMy); imageAvatar = itemView.findViewById(R.id.imageAvatar);
fullNameMy = itemView.findViewById(R.id.repoFullNameMy); repoFullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublicMy = itemView.findViewById(R.id.imageRepoTypeMy); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStarsMy = itemView.findViewById(R.id.repoStarsMy); repoStars = itemView.findViewById(R.id.repoStars);
repoForksMy = itemView.findViewById(R.id.repoForksMy); repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCountMy = itemView.findViewById(R.id.repoOpenIssuesCountMy); repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(v -> {
Context context = v.getContext(); Context context = v.getContext();
Intent intent = new Intent(context, RepoDetailActivity.class); Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", fullNameMy.getText().toString()); intent.putExtra("repoFullName", repoFullName.getText().toString());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullNameMy.getText().toString()); tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString()); tinyDb.putString("repoType", repoType.getText().toString());
//tinyDb.putBoolean("resumeIssues", true); //tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
//store if user is watching this repo //store if user is watching this repo
{ {
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
String[] parts = fullNameMy.getText().toString().split("/"); String[] parts = repoFullName.getText().toString().split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
final String repoName = parts[1]; final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository(); WatchInfo watch = new WatchInfo();
Call<WatchRepository> call; Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() { call.enqueue(new Callback<WatchInfo>() {
@Override @Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) { public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.isSuccessful()) { if(response.isSuccessful()) {
@ -119,7 +123,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
} }
@Override @Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
@ -144,7 +148,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
TextView repoWatchers = view.findViewById(R.id.repoWatchers); TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullNameMy.getText()); bottomSheetHeader.setText(repoFullName.getText());
BottomSheetDialog dialog = new BottomSheetDialog(context); BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view); dialog.setContentView(view);
dialog.show(); dialog.show();
@ -152,7 +156,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
repoOpenInBrowser.setOnClickListener(openInBrowser -> { repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullNameMy.getText()); intentOpenInBrowser.putExtra("repoFullNameBrowser", repoFullName.getText());
context.startActivity(intentOpenInBrowser); context.startActivity(intentOpenInBrowser);
dialog.dismiss(); dialog.dismiss();
@ -161,7 +165,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
repoStargazers.setOnClickListener(stargazers -> { repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class); Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullNameMy.getText()); intent.putExtra("repoFullNameForStars", repoFullName.getText());
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); dialog.dismiss();
@ -170,7 +174,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
repoWatchers.setOnClickListener(watchers -> { repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class); Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullNameMy.getText()); intentW.putExtra("repoFullNameForWatchers", repoFullName.getText());
context.startActivity(intentW); context.startActivity(intentW);
dialog.dismiss(); dialog.dismiss();
@ -190,7 +194,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
@NonNull @NonNull
@Override @Override
public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_my_repos, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new MyReposListAdapter.MyReposViewHolder(v); return new MyReposListAdapter.MyReposViewHolder(v);
} }
@ -198,7 +202,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
public void onBindViewHolder(@NonNull MyReposListAdapter.MyReposViewHolder holder, int position) { public void onBindViewHolder(@NonNull MyReposListAdapter.MyReposViewHolder holder, int position) {
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.mTextView2My.setVisibility(View.GONE); holder.repoDescription.setVisibility(View.GONE);
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -216,32 +220,37 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
if (currentItem.getAvatar_url() != null) { if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) { 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.imageMy); 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);
} else { } else {
holder.imageMy.setImageDrawable(drawable); holder.imageAvatar.setImageDrawable(drawable);
} }
} }
else { else {
holder.imageMy.setImageDrawable(drawable); holder.imageAvatar.setImageDrawable(drawable);
} }
holder.mTextView1My.setText(currentItem.getName()); holder.repoName.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.mTextView2My.setVisibility(View.VISIBLE); holder.repoDescription.setVisibility(View.VISIBLE);
holder.mTextView2My.setText(currentItem.getDescription()); holder.repoDescription.setText(currentItem.getDescription());
} }
holder.fullNameMy.setText(currentItem.getFullname()); holder.repoFullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_lock_bold); holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
holder.repoType.setText(R.string.strPrivate); holder.repoType.setText(R.string.strPrivate);
} }
else { else {
holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_public); holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
holder.repoType.setText(R.string.strPublic); holder.repoType.setText(R.string.strPublic);
} }
holder.repoStarsMy.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoForksMy.setText(currentItem.getForks_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCountMy.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
} }

View File

@ -7,8 +7,6 @@ import android.text.Html;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
@ -22,10 +20,6 @@ import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.PullRequests; import org.mian.gitnex.models.PullRequests;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -33,231 +27,220 @@ import java.util.Locale;
* Author M M Arif * Author M M Arif
*/ */
public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable { public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context; private Context context;
private final int TYPE_LOAD = 0; private final int TYPE_LOAD = 0;
private List<PullRequests> prList; private List<PullRequests> prList;
private List<PullRequests> prListFull; private PullRequestsAdapter.OnLoadMoreListener loadMoreListener;
private PullRequestsAdapter.OnLoadMoreListener loadMoreListener; private boolean isLoading = false, isMoreDataAvailable = true;
private boolean isLoading = false, isMoreDataAvailable = true;
public PullRequestsAdapter(Context context, List<PullRequests> prListMain) { public PullRequestsAdapter(Context context, List<PullRequests> prListMain) {
this.context = context; this.context = context;
this.prList = prListMain; this.prList = prListMain;
prListFull = new ArrayList<>(prList);
} }
@NonNull @NonNull
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context); LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD){ if(viewType == TYPE_LOAD) {
return new PullRequestsAdapter.PullRequestsHolder(inflater.inflate(R.layout.list_pr, parent,false)); return new PullRequestsAdapter.PullRequestsHolder(inflater.inflate(R.layout.list_pr, parent, false));
} }
else { else {
return new PullRequestsAdapter.LoadHolder(inflater.inflate(R.layout.row_load,parent,false)); return new PullRequestsAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
} }
} }
@Override @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null) { if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true; isLoading = true;
loadMoreListener.onLoadMore(); loadMoreListener.onLoadMore();
} }
if(getItemViewType(position) == TYPE_LOAD) { if(getItemViewType(position) == TYPE_LOAD) {
((PullRequestsAdapter.PullRequestsHolder)holder).bindData(prList.get(position)); ((PullRequestsAdapter.PullRequestsHolder) holder).bindData(prList.get(position));
} }
} }
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
if(prList.get(position).getTitle() != null) { if(prList.get(position).getTitle() != null) {
return TYPE_LOAD; return TYPE_LOAD;
} }
else { else {
return 1; return 1;
} }
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return prList.size(); return prList.size();
} }
class PullRequestsHolder extends RecyclerView.ViewHolder { class PullRequestsHolder extends RecyclerView.ViewHolder {
private TextView prNumber; private TextView prNumber;
private ImageView assigneeAvatar; private TextView prMergeable;
private TextView prTitle; private TextView prHeadBranch;
private TextView prCreatedTime; private TextView prIsFork;
private TextView prCommentsCount; private TextView prForkFullName;
private ImageView assigneeAvatar;
private TextView prTitle;
private TextView prCreatedTime;
private TextView prCommentsCount;
PullRequestsHolder(View itemView) { PullRequestsHolder(View itemView) {
super(itemView); super(itemView);
prNumber = itemView.findViewById(R.id.prNumber); prNumber = itemView.findViewById(R.id.prNumber);
assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); prMergeable = itemView.findViewById(R.id.prMergeable);
prTitle = itemView.findViewById(R.id.prTitle); prHeadBranch = itemView.findViewById(R.id.prHeadBranch);
prCommentsCount = itemView.findViewById(R.id.prCommentsCount); prIsFork = itemView.findViewById(R.id.prIsFork);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount); prForkFullName = itemView.findViewById(R.id.prForkFullName);
prCreatedTime = itemView.findViewById(R.id.prCreatedTime); 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(new View.OnClickListener() { prTitle.setOnClickListener(v -> {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class); Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", prNumber.getText()); intent.putExtra("issueNumber", prNumber.getText());
intent.putExtra("prMergeable", prMergeable.getText());
intent.putExtra("prHeadBranch", prHeadBranch.getText());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", prNumber.getText().toString()); tinyDb.putString("issueNumber", prNumber.getText().toString());
tinyDb.putString("issueType", "pr"); tinyDb.putString("prMergeable", prMergeable.getText().toString());
context.startActivity(intent); tinyDb.putString("prHeadBranch", prHeadBranch.getText().toString());
tinyDb.putString("prIsFork", prIsFork.getText().toString());
tinyDb.putString("prForkFullName", prForkFullName.getText().toString());
tinyDb.putString("issueType", "pr");
context.startActivity(intent);
} });
}); frameCommentsCount.setOnClickListener(v -> {
frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class); Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", prNumber.getText()); intent.putExtra("issueNumber", prNumber.getText());
intent.putExtra("prMergeable", prMergeable.getText());
intent.putExtra("prHeadBranch", prHeadBranch.getText());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", prNumber.getText().toString()); tinyDb.putString("issueNumber", prNumber.getText().toString());
tinyDb.putString("issueType", "pr"); tinyDb.putString("prMergeable", prMergeable.getText().toString());
context.startActivity(intent); tinyDb.putString("prHeadBranch", prHeadBranch.getText().toString());
tinyDb.putString("prIsFork", prIsFork.getText().toString());
tinyDb.putString("prForkFullName", prForkFullName.getText().toString());
tinyDb.putString("issueType", "pr");
context.startActivity(intent);
} });
});
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
void bindData(PullRequests prModel){ void bindData(PullRequests prModel) {
final TinyDB tinyDb = new TinyDB(context); final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale"); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
if (!prModel.getUser().getFull_name().equals("")) { if(!prModel.getUser().getFull_name().equals("")) {
assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getFull_name(), context)); assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getFull_name(), context));
} else { }
assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getLogin(), context)); else {
} assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getLogin(), context));
}
if (prModel.getUser().getAvatar_url() != null) { if(prModel.getUser().getAvatar_url() != null) {
PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
} else { }
PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); else {
} PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
}
String prNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + prModel.getNumber() + "</font>"; String prNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + prModel.getNumber() + "</font>";
prTitle.setText(Html.fromHtml(prNumber_ + " " + prModel.getTitle())); prTitle.setText(Html.fromHtml(prNumber_ + " " + prModel.getTitle()));
prNumber.setText(String.valueOf(prModel.getNumber())); prNumber.setText(String.valueOf(prModel.getNumber()));
prCommentsCount.setText(String.valueOf(prModel.getComments())); prMergeable.setText(String.valueOf(prModel.isMergeable()));
prHeadBranch.setText(prModel.getHead().getRef());
prIsFork.setText(String.valueOf(prModel.getHead().getRepo().isFork()));
prForkFullName.setText(prModel.getHead().getRepo().getFull_name());
prCommentsCount.setText(String.valueOf(prModel.getComments()));
prCreatedTime.setText(TimeHelper.formatTime(prModel.getCreated_at(), new Locale(locale), timeFormat, context)); prCreatedTime.setText(TimeHelper.formatTime(prModel.getCreated_at(), new Locale(locale), timeFormat, context));
if(timeFormat.equals("pretty")) { if(timeFormat.equals("pretty")) {
prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context)); prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context));
} }
} }
} }
static class LoadHolder extends RecyclerView.ViewHolder { static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) { LoadHolder(View itemView) {
super(itemView);
}
} super(itemView);
}
public void setMoreDataAvailable(boolean moreDataAvailable) { }
isMoreDataAvailable = moreDataAvailable; public void setMoreDataAvailable(boolean moreDataAvailable) {
} isMoreDataAvailable = moreDataAvailable;
public void notifyDataChanged() { }
notifyDataSetChanged(); public void notifyDataChanged() {
isLoading = false;
} notifyDataSetChanged();
isLoading = false;
public interface OnLoadMoreListener { }
void onLoadMore(); public interface OnLoadMoreListener {
} void onLoadMore();
public void setLoadMoreListener(PullRequestsAdapter.OnLoadMoreListener loadMoreListener) { }
this.loadMoreListener = loadMoreListener; public void setLoadMoreListener(PullRequestsAdapter.OnLoadMoreListener loadMoreListener) {
} this.loadMoreListener = loadMoreListener;
@Override }
public Filter getFilter() {
return prFilter;
}
private Filter prFilter = new Filter() { public void updateList(List<PullRequests> list) {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<PullRequests> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) { prList = list;
filteredList.addAll(prList); notifyDataSetChanged();
} else { }
String filterPattern = constraint.toString().toLowerCase().trim();
for (PullRequests item : prList) {
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getBody().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
prList.clear();
prList.addAll((List) results.values);
notifyDataSetChanged();
}
};
} }

View File

@ -27,7 +27,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository; import org.mian.gitnex.models.WatchInfo;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -95,16 +95,16 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
final String repoName = parts[1]; final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository(); WatchInfo watch = new WatchInfo();
Call<WatchRepository> call; Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() { call.enqueue(new Callback<WatchInfo>() {
@Override @Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) { public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.isSuccessful()) { if(response.isSuccessful()) {
@ -126,7 +126,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
} }
@Override @Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
@ -199,7 +199,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
@Override @Override
public ReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repos, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new ReposViewHolder(v); return new ReposViewHolder(v);
} }

View File

@ -25,7 +25,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository; import org.mian.gitnex.models.WatchInfo;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -92,16 +92,16 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
final String repoName = parts[1]; final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository(); WatchInfo watch = new WatchInfo();
Call<WatchRepository> call; Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() { call.enqueue(new Callback<WatchInfo>() {
@Override @Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) { public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.isSuccessful()) { if(response.isSuccessful()) {
@ -123,7 +123,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
} }
@Override @Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
@ -194,7 +194,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
@NonNull @NonNull
@Override @Override
public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories_by_org, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new RepositoriesByOrgAdapter.OrgReposViewHolder(v); return new RepositoriesByOrgAdapter.OrgReposViewHolder(v);
} }

View File

@ -25,7 +25,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository; import org.mian.gitnex.models.WatchInfo;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -92,16 +92,16 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
final String repoName = parts[1]; final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository(); WatchInfo watch = new WatchInfo();
Call<WatchRepository> call; Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() { call.enqueue(new Callback<WatchInfo>() {
@Override @Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) { public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.isSuccessful()) { if(response.isSuccessful()) {
@ -123,7 +123,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
} }
@Override @Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
@ -195,7 +195,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
@NonNull @NonNull
@Override @Override
public StarredReposListAdapter.StarredReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public StarredReposListAdapter.StarredReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_starred_repos, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new StarredReposListAdapter.StarredReposViewHolder(v); return new StarredReposListAdapter.StarredReposViewHolder(v);
} }

View File

@ -0,0 +1,184 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter<UserSearchForTeamMemberAdapter.UserSearchViewHolder> {
private List<UserInfo> usersSearchList;
private Context mCtx;
private int teamId;
public UserSearchForTeamMemberAdapter(List<UserInfo> dataList, Context mCtx, int teamId) {
this.mCtx = mCtx;
this.usersSearchList = dataList;
this.teamId = teamId;
}
static 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 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);
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(),
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()));
});
addMemberButtonRemove.setOnClickListener(v -> {
Context context = v.getContext();
AlertDialogs.removeMemberDialog(context, userNameMain.getText().toString(),
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()));
});
}
}
@NonNull
@Override
public UserSearchForTeamMemberAdapter.UserSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_collaborators_search, parent, false);
return new UserSearchForTeamMemberAdapter.UserSearchViewHolder(v);
}
@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));
if (!currentItem.getFullname().equals("")) {
holder.userFullName.setText(currentItem.getFullname());
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
}
else {
holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
holder.userName.setText(mCtx.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);
}
if(getItemCount() > 0) {
TinyDB tinyDb = new TinyDB(mCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<UserInfo> call = RetrofitClient
.getInstance(instanceUrl, mCtx)
.getApiInterface()
.checkTeamMember(Authorization.returnAuthentication(mCtx, loginUid, instanceToken), teamId, currentItem.getLogin());
call.enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(@NonNull Call<UserInfo> call, @NonNull Response<UserInfo> response) {
if(response.code() == 200) {
if(!currentItem.getLogin().equals(loginUid) && !currentItem.getLogin().equals(repoOwner)) {
holder.addMemberButtonRemove.setVisibility(View.VISIBLE);
}
else {
holder.addMemberButtonRemove.setVisibility(View.GONE);
}
}
else if(response.code() == 404) {
if(!currentItem.getLogin().equals(loginUid) && !currentItem.getLogin().equals(repoOwner)) {
holder.addMemberButtonAdd.setVisibility(View.VISIBLE);
}
else {
holder.addMemberButtonAdd.setVisibility(View.GONE);
}
}
else {
holder.addMemberButtonRemove.setVisibility(View.GONE);
holder.addMemberButtonAdd.setVisibility(View.GONE);
}
}
@Override
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Toasty.error(mCtx, mCtx.getResources().getString(R.string.genericServerResponseError));
}
});
}
}
@Override
public int getItemCount() {
return usersSearchList.size();
}
}

View File

@ -2,20 +2,18 @@ package org.mian.gitnex.clients;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import org.mian.gitnex.helpers.FilesData;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager; import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.security.SecureRandom; import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import okhttp3.Cache; import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor; import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
@ -24,13 +22,14 @@ import retrofit2.converter.gson.GsonConverterFactory;
* Author M M Arif * Author M M Arif
*/ */
public class IssuesService { public class AppApiService {
public static <S> S createService(Class<S> serviceClass, String instanceURL, Context ctx) { public static <S> S createService(Class<S> serviceClass, String instanceURL, Context ctx) {
TinyDB tinyDb = new TinyDB(ctx);
final boolean connToInternet = AppUtil.haveNetworkConnection(ctx); final boolean connToInternet = AppUtil.haveNetworkConnection(ctx);
File httpCacheDirectory = new File(ctx.getCacheDir(), "responses"); File httpCacheDirectory = new File(ctx.getCacheDir(), "responses");
int cacheSize = 50 * 1024 * 1024; // 50MB int cacheSize = FilesData.returnOnlyNumber(tinyDb.getString("cacheSizeStr")) * 1024 * 1024;
Cache cache = new Cache(httpCacheDirectory, cacheSize); Cache cache = new Cache(httpCacheDirectory, cacheSize);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
@ -48,22 +47,18 @@ public class IssuesService {
//.addInterceptor(logging) //.addInterceptor(logging)
.sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager) .sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager)
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier())) .hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()))
.addInterceptor(new Interceptor() { .addInterceptor(chain -> {
@NonNull Request request = chain.request();
@Override if(connToInternet) {
public Response intercept(@NonNull Chain chain) throws IOException { request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
}
else {
request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build();
}
return chain.proceed(request);
Request request = chain.request(); }).build();
if(connToInternet) {
request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
}
else {
request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build();
}
return chain.proceed(request);
}
}).build();
Retrofit.Builder builder = new Retrofit.Builder() Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(instanceURL) .baseUrl(instanceURL)

View File

@ -49,7 +49,7 @@ public class PicassoService {
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
cachePath.mkdirs(); cachePath.mkdirs();
picasso = builder.memoryCache(new PicassoCache(cachePath)).build(); picasso = builder.memoryCache(new PicassoCache(cachePath, context)).build();
} }
catch(Exception e) { catch(Exception e) {

View File

@ -1,83 +0,0 @@
package org.mian.gitnex.clients;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.util.AppUtil;
import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Author M M Arif
*/
public class PullRequestsService {
public static <S> S createService(Class<S> serviceClass, String instanceURL, Context ctx) {
final boolean connToInternet = AppUtil.haveNetworkConnection(ctx);
File httpCacheDirectory = new File(ctx.getCacheDir(), "responses");
int cacheSize = 50 * 1024 * 1024; // 50MB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(ctx);
sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom());
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cache(cache)
//.addInterceptor(logging)
.sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager)
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()))
.addInterceptor(new Interceptor() {
@NonNull
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request request = chain.request();
if(connToInternet) {
request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
}
else {
request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build();
}
return chain.proceed(request);
}
}).build();
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(instanceURL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
return retrofit.create(serviceClass);
}
catch(Exception e) {
Log.e("onFailure", e.toString());
}
return null;
}
}

View File

@ -2,10 +2,12 @@ package org.mian.gitnex.clients;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import org.mian.gitnex.helpers.FilesData;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.interfaces.WebInterface; import org.mian.gitnex.interfaces.WebInterface;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.io.File; import java.io.File;
import java.security.SecureRandom; import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
@ -29,8 +31,9 @@ public class RetrofitClient {
private RetrofitClient(String instanceUrl, Context ctx) { private RetrofitClient(String instanceUrl, Context ctx) {
TinyDB tinyDb = new TinyDB(ctx);
final boolean connToInternet = AppUtil.haveNetworkConnection(ctx); final boolean connToInternet = AppUtil.haveNetworkConnection(ctx);
int cacheSize = 50 * 1024 * 1024; // 50MB int cacheSize = FilesData.returnOnlyNumber(tinyDb.getString("cacheSizeStr")) * 1024 * 1024;
File httpCacheDirectory = new File(ctx.getCacheDir(), "responses"); File httpCacheDirectory = new File(ctx.getCacheDir(), "responses");
Cache cache = new Cache(httpCacheDirectory, cacheSize); Cache cache = new Cache(httpCacheDirectory, cacheSize);
@ -44,12 +47,9 @@ public class RetrofitClient {
MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(ctx); MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(ctx);
sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom()); sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom());
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder() OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder().cache(cache)
.cache(cache)
//.addInterceptor(logging) //.addInterceptor(logging)
.sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager) .sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager).hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier())).addInterceptor(chain -> {
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()))
.addInterceptor(chain -> {
Request request = chain.request(); Request request = chain.request();
if(connToInternet) { if(connToInternet) {
@ -61,11 +61,7 @@ public class RetrofitClient {
return chain.proceed(request); return chain.proceed(request);
}); });
Retrofit.Builder builder = new Retrofit.Builder() Retrofit.Builder builder = new Retrofit.Builder().baseUrl(instanceUrl).client(okHttpClient.build()).addConverterFactory(ScalarsConverterFactory.create()).addConverterFactory(GsonConverterFactory.create());
.baseUrl(instanceUrl)
.client(okHttpClient.build())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create());
retrofit = builder.build(); retrofit = builder.build();
@ -77,15 +73,18 @@ public class RetrofitClient {
} }
public static synchronized RetrofitClient getInstance(String instanceUrl, Context ctx) { public static synchronized RetrofitClient getInstance(String instanceUrl, Context ctx) {
return new RetrofitClient(instanceUrl, ctx); return new RetrofitClient(instanceUrl, ctx);
} }
public ApiInterface getApiInterface() { public ApiInterface getApiInterface() {
return retrofit.create(ApiInterface.class); return retrofit.create(ApiInterface.class);
} }
public WebInterface getWebInterface() { public WebInterface getWebInterface() {
return retrofit.create(WebInterface.class);
} return retrofit.create(WebInterface.class);
}
} }

View File

@ -0,0 +1,35 @@
package org.mian.gitnex.fragments;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.AdminGetUsersActivity;
import org.mian.gitnex.util.TinyDB;
/**
* Author M M Arif
*/
public class AdministrationFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_administration, container, false);
TinyDB tinyDb = new TinyDB(getContext());
TextView adminUsers = v.findViewById(R.id.adminUsers);
adminUsers.setOnClickListener(v1 -> startActivity(new Intent(getContext(), AdminGetUsersActivity.class)));
return v;
}
}

View File

@ -22,7 +22,7 @@ public class BottomSheetAdminUsersFragment extends BottomSheetDialogFragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_admin_users_layout, container, false); View v = inflater.inflate(R.layout.bottom_sheet_admin_users, container, false);
TextView createNewUser = v.findViewById(R.id.createNewUser); TextView createNewUser = v.findViewById(R.id.createNewUser);

View File

@ -0,0 +1,63 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R;
/**
* Author M M Arif
*/
public class BottomSheetIssuesFilterFragment extends BottomSheetDialogFragment {
private BottomSheetIssuesFilterFragment.BottomSheetListener bmListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_issues_filter, container, false);
TextView openIssues = v.findViewById(R.id.openIssues);
TextView closedIssues = v.findViewById(R.id.closedIssues);
openIssues.setOnClickListener(v1 -> {
bmListener.onButtonClicked("openIssues");
dismiss();
});
closedIssues.setOnClickListener(v12 -> {
bmListener.onButtonClicked("closedIssues");
dismiss();
});
return v;
}
public interface BottomSheetListener {
void onButtonClicked(String text);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
bmListener = (BottomSheetIssuesFilterFragment.BottomSheetListener) context;
}
catch(ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement BottomSheetListener");
}
}
}

View File

@ -0,0 +1,64 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R;
/**
* Author M M Arif
*/
public class BottomSheetMilestonesFilterFragment extends BottomSheetDialogFragment {
private BottomSheetMilestonesFilterFragment.BottomSheetListener bmListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_milestones_filter, container, false);
TextView openMilestone = v.findViewById(R.id.openMilestone);
TextView closedMilestone = v.findViewById(R.id.closedMilestone);
openMilestone.setOnClickListener(v1 -> {
bmListener.onButtonClicked("openMilestone");
dismiss();
});
closedMilestone.setOnClickListener(v12 -> {
bmListener.onButtonClicked("closedMilestone");
dismiss();
});
return v;
}
public interface BottomSheetListener {
void onButtonClicked(String text);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
bmListener = (BottomSheetMilestonesFilterFragment.BottomSheetListener) context;
}
catch(ClassCastException e) {
Log.e("MilestonesFilterBs", e.toString());
}
}
}

View File

@ -1,39 +0,0 @@
package org.mian.gitnex.fragments;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.AdminGetUsersActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Author M M Arif
*/
public class BottomSheetNavSubMenuFragment extends BottomSheetDialogFragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_nav_sub_menu_layout, container, false);
TextView adminUsers = v.findViewById(R.id.adminUsers);
adminUsers.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getContext(), AdminGetUsersActivity.class));
dismiss();
}
});
return v;
}
}

View File

@ -22,7 +22,7 @@ public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_organization_layout, container, false); View v = inflater.inflate(R.layout.bottom_sheet_organization, container, false);
TextView createTeam = v.findViewById(R.id.createTeam); TextView createTeam = v.findViewById(R.id.createTeam);
TextView createRepository = v.findViewById(R.id.createRepository); TextView createRepository = v.findViewById(R.id.createRepository);

View File

@ -0,0 +1,58 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R;
/**
* Author M M Arif
*/
public class BottomSheetOrganizationTeamsFragment extends BottomSheetDialogFragment {
private BottomSheetOrganizationTeamsFragment.BottomSheetListener bmListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_organization_teams, container, false);
TextView addNewMember = v.findViewById(R.id.addNewMember);
addNewMember.setOnClickListener(v1 -> {
bmListener.onButtonClicked("newMember");
dismiss();
});
return v;
}
public interface BottomSheetListener {
void onButtonClicked(String text);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
bmListener = (BottomSheetOrganizationTeamsFragment.BottomSheetListener) context;
}
catch (ClassCastException e) {
Log.e("BsOrganizationTeams", e.toString());
}
}
}

View File

@ -21,7 +21,7 @@ public class BottomSheetProfileFragment extends BottomSheetDialogFragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_profile_layout, container, false); View v = inflater.inflate(R.layout.bottom_sheet_profile, container, false);
TextView addNewEmailAddress = v.findViewById(R.id.addNewEmailAddress); TextView addNewEmailAddress = v.findViewById(R.id.addNewEmailAddress);

View File

@ -0,0 +1,63 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R;
/**
* Author M M Arif
*/
public class BottomSheetPullRequestFilterFragment extends BottomSheetDialogFragment {
private BottomSheetPullRequestFilterFragment.BottomSheetListener bmListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_pull_request_filter, container, false);
TextView openPr = v.findViewById(R.id.openPr);
TextView closedPr = v.findViewById(R.id.closedPr);
openPr.setOnClickListener(v1 -> {
bmListener.onButtonClicked("openPr");
dismiss();
});
closedPr.setOnClickListener(v12 -> {
bmListener.onButtonClicked("closedPr");
dismiss();
});
return v;
}
public interface BottomSheetListener {
void onButtonClicked(String text);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
bmListener = (BottomSheetPullRequestFilterFragment.BottomSheetListener) context;
}
catch(ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement BottomSheetListener");
}
}
}

View File

@ -24,7 +24,7 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_repo_layout, container, false); View v = inflater.inflate(R.layout.bottom_sheet_repo, container, false);
final TinyDB tinyDb = new TinyDB(getContext()); final TinyDB tinyDb = new TinyDB(getContext());

View File

@ -1,5 +1,7 @@
package org.mian.gitnex.fragments; package org.mian.gitnex.fragments;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -7,6 +9,8 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.IssueActions; import org.mian.gitnex.actions.IssueActions;
@ -15,18 +19,10 @@ import org.mian.gitnex.activities.AddRemoveLabelsActivity;
import org.mian.gitnex.activities.EditIssueActivity; import org.mian.gitnex.activities.EditIssueActivity;
import org.mian.gitnex.activities.FileDiffActivity; import org.mian.gitnex.activities.FileDiffActivity;
import org.mian.gitnex.activities.MergePullRequestActivity; import org.mian.gitnex.activities.MergePullRequestActivity;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.content.ClipboardManager;
import android.content.ClipData;
import java.util.Objects; import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -34,221 +30,225 @@ import retrofit2.Callback;
public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_single_issue_layout, container, false); View v = inflater.inflate(R.layout.bottom_sheet_single_issue, container, false);
final Context ctx = getContext(); final Context ctx = getContext();
final TinyDB tinyDB = new TinyDB(ctx); final TinyDB tinyDB = new TinyDB(ctx);
TextView editIssue = v.findViewById(R.id.editIssue); TextView editIssue = v.findViewById(R.id.editIssue);
TextView editLabels = v.findViewById(R.id.editLabels); TextView editLabels = v.findViewById(R.id.editLabels);
TextView closeIssue = v.findViewById(R.id.closeIssue); TextView closeIssue = v.findViewById(R.id.closeIssue);
TextView reOpenIssue = v.findViewById(R.id.reOpenIssue); TextView reOpenIssue = v.findViewById(R.id.reOpenIssue);
TextView addRemoveAssignees = v.findViewById(R.id.addRemoveAssignees); TextView addRemoveAssignees = v.findViewById(R.id.addRemoveAssignees);
TextView copyIssueUrl = v.findViewById(R.id.copyIssueUrl); TextView copyIssueUrl = v.findViewById(R.id.copyIssueUrl);
TextView openFilesDiff = v.findViewById(R.id.openFilesDiff); TextView openFilesDiff = v.findViewById(R.id.openFilesDiff);
TextView mergePullRequest = v.findViewById(R.id.mergePullRequest); TextView mergePullRequest = v.findViewById(R.id.mergePullRequest);
TextView shareIssue = v.findViewById(R.id.shareIssue); TextView shareIssue = v.findViewById(R.id.shareIssue);
TextView subscribeIssue = v.findViewById(R.id.subscribeIssue); TextView subscribeIssue = v.findViewById(R.id.subscribeIssue);
TextView unsubscribeIssue = v.findViewById(R.id.unsubscribeIssue); TextView unsubscribeIssue = v.findViewById(R.id.unsubscribeIssue);
if(tinyDB.getString("issueType").equals("pr")) { if(tinyDB.getString("issueType").equals("pr")) {
editIssue.setText(R.string.editPrText); editIssue.setText(R.string.editPrText);
copyIssueUrl.setText(R.string.copyPrUrlText); copyIssueUrl.setText(R.string.copyPrUrlText);
shareIssue.setText(R.string.sharePr); shareIssue.setText(R.string.sharePr);
if(tinyDB.getBoolean("prMerged")) { if(tinyDB.getBoolean("prMerged") || tinyDB.getString("repoPrState").equals("closed")) {
mergePullRequest.setVisibility(View.GONE); mergePullRequest.setVisibility(View.GONE);
} }
else { else {
mergePullRequest.setVisibility(View.VISIBLE); mergePullRequest.setVisibility(View.VISIBLE);
} }
if(tinyDB.getString("repoType").equals("public")) { if(tinyDB.getString("repoType").equals("public")) {
openFilesDiff.setVisibility(View.VISIBLE); openFilesDiff.setVisibility(View.VISIBLE);
} }
else { else {
openFilesDiff.setVisibility(View.GONE); openFilesDiff.setVisibility(View.GONE);
} }
} }
else { else {
mergePullRequest.setVisibility(View.GONE); mergePullRequest.setVisibility(View.GONE);
} }
mergePullRequest.setOnClickListener(new View.OnClickListener() { mergePullRequest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(ctx, MergePullRequestActivity.class)); @Override
dismiss(); public void onClick(View v) {
} startActivity(new Intent(ctx, MergePullRequestActivity.class));
}); dismiss();
openFilesDiff.setOnClickListener(new View.OnClickListener() { }
@Override });
public void onClick(View v) {
startActivity(new Intent(ctx, FileDiffActivity.class)); openFilesDiff.setOnClickListener(new View.OnClickListener() {
dismiss();
} @Override
}); public void onClick(View v) {
editIssue.setOnClickListener(new View.OnClickListener() { startActivity(new Intent(ctx, FileDiffActivity.class));
@Override dismiss();
public void onClick(View v) {
startActivity(new Intent(ctx, EditIssueActivity.class)); }
dismiss(); });
} editIssue.setOnClickListener(new View.OnClickListener() {
});
editLabels.setOnClickListener(new View.OnClickListener() { @Override
@Override public void onClick(View v) {
public void onClick(View v) {
startActivity(new Intent(ctx, AddRemoveLabelsActivity.class)); startActivity(new Intent(ctx, EditIssueActivity.class));
dismiss(); dismiss();
} }
}); });
addRemoveAssignees.setOnClickListener(new View.OnClickListener() { editLabels.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(ctx, AddRemoveAssigneesActivity.class)); @Override
dismiss(); public void onClick(View v) {
} startActivity(new Intent(ctx, AddRemoveLabelsActivity.class));
}); dismiss();
shareIssue.setOnClickListener(v1 -> { }
});
// get url of repo addRemoveAssignees.setOnClickListener(new View.OnClickListener() {
String repoFullName = tinyDB.getString("repoFullName");
String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw");
if (!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol");
}
// get issue Url @Override
String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber"); public void onClick(View v) {
// share issue startActivity(new Intent(ctx, AddRemoveAssigneesActivity.class));
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); dismiss();
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, issueUrl);
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle")));
dismiss(); }
});
}); shareIssue.setOnClickListener(v1 -> {
copyIssueUrl.setOnClickListener(new View.OnClickListener() { // get url of repo
@Override String repoFullName = tinyDB.getString("repoFullName");
public void onClick(View v) { String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw");
if(!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol");
}
// get url of repo // get issue Url
String repoFullName = tinyDB.getString("repoFullName"); String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber");
String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw");
if (!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol");
}
// get issue Url // share issue
String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber"); Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, issueUrl);
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle")));
// copy to clipboard dismiss();
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(android.content.Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("issueUrl", issueUrl);
assert clipboard != null;
clipboard.setPrimaryClip(clip);
dismiss(); });
Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg)); copyIssueUrl.setOnClickListener(new View.OnClickListener() {
} @Override
}); public void onClick(View v) {
if(tinyDB.getString("issueType").equals("issue")) { // get url of repo
String repoFullName = tinyDB.getString("repoFullName");
String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw");
if(!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol");
}
if (tinyDB.getString("issueState").equals("open")) { // close issue // get issue Url
String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber");
reOpenIssue.setVisibility(View.GONE); // copy to clipboard
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(android.content.Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("issueUrl", issueUrl);
assert clipboard != null;
clipboard.setPrimaryClip(clip);
closeIssue.setOnClickListener(new View.OnClickListener() { dismiss();
@Override
public void onClick(View v) {
IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "closed"); Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg));
dismiss();
} }
}); });
} if(tinyDB.getString("issueType").equals("issue")) {
else if (tinyDB.getString("issueState").equals("closed")) {
closeIssue.setVisibility(View.GONE); if(tinyDB.getString("issueState").equals("open")) { // close issue
reOpenIssue.setOnClickListener(new View.OnClickListener() { reOpenIssue.setVisibility(View.GONE);
@Override closeIssue.setVisibility(View.VISIBLE);
public void onClick(View v) {
IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "open"); closeIssue.setOnClickListener(closeSingleIssue -> {
dismiss();
} IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "closed");
}); dismiss();
} });
} }
else { else if(tinyDB.getString("issueState").equals("closed")) {
reOpenIssue.setVisibility(View.GONE); closeIssue.setVisibility(View.GONE);
closeIssue.setVisibility(View.GONE); reOpenIssue.setVisibility(View.VISIBLE);
} reOpenIssue.setOnClickListener(reOpenSingleIssue -> {
subscribeIssue.setOnClickListener(new View.OnClickListener() { IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "open");
@Override dismiss();
public void onClick(View v) {
IssueActions.subscribe(ctx, subscribeIssue, unsubscribeIssue); });
} }
});
unsubscribeIssue.setOnClickListener(new View.OnClickListener() { }
@Override else {
public void onClick(View v) {
IssueActions.unsubscribe(ctx, subscribeIssue, unsubscribeIssue); reOpenIssue.setVisibility(View.GONE);
closeIssue.setVisibility(View.GONE);
} }
});
//if RepoWatch True Provide Unsubscribe first subscribeIssue.setOnClickListener(subscribeToIssue -> {
// ToDo: API to check if user is subscribed to an issue (do not exist can be guessed by many api endpoints :/)
if (tinyDB.getBoolean("repoWatch")) {
subscribeIssue.setVisibility(View.GONE);
unsubscribeIssue.setVisibility(View.VISIBLE);
}
return v; IssueActions.subscribe(ctx);
} dismiss();
});
unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> {
IssueActions.unsubscribe(ctx);
dismiss();
});
if(new Version(tinyDB.getString("giteaVersion")).less("1.12.0")) {
subscribeIssue.setVisibility(View.GONE);
unsubscribeIssue.setVisibility(View.GONE);
}
else if(tinyDB.getBoolean("issueSubscribed")) {
subscribeIssue.setVisibility(View.GONE);
unsubscribeIssue.setVisibility(View.VISIBLE);
}
else {
subscribeIssue.setVisibility(View.VISIBLE);
unsubscribeIssue.setVisibility(View.GONE);
}
return v;
}
} }

View File

@ -4,14 +4,6 @@ import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
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 android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -22,12 +14,19 @@ import android.view.inputmethod.EditorInfo;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; 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 org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.FileViewActivity; import org.mian.gitnex.activities.FileViewActivity;
import org.mian.gitnex.adapters.FilesAdapter; import org.mian.gitnex.adapters.FilesAdapter;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.Files; import org.mian.gitnex.models.Files;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.FilesViewModel; import org.mian.gitnex.viewmodels.FilesViewModel;
import java.util.ArrayList; import java.util.ArrayList;
@ -44,268 +43,275 @@ import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem;
public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapterListener { public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapterListener {
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
private FilesAdapter adapter; private FilesAdapter adapter;
private RecyclerView mRecyclerView; private RecyclerView mRecyclerView;
private TextView noDataFiles; private TextView noDataFiles;
private LinearLayout filesFrame; private LinearLayout filesFrame;
private TextView fileStructure; private TextView fileStructure;
private static String repoNameF = "param2"; private static String repoNameF = "param2";
private static String repoOwnerF = "param1"; private static String repoOwnerF = "param1";
private BreadcrumbsView mBreadcrumbsView; private BreadcrumbsView mBreadcrumbsView;
private String repoName; private String repoName;
private String repoOwner; private String repoOwner;
private OnFragmentInteractionListener mListener; private OnFragmentInteractionListener mListener;
public FilesFragment() { public FilesFragment() {
}
public static FilesFragment newInstance(String param1, String param2) { }
FilesFragment fragment = new FilesFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
fragment.setArguments(args);
return fragment;
}
@Override public static FilesFragment newInstance(String param1, String param2) {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
repoName = getArguments().getString(repoNameF);
repoOwner = getArguments().getString(repoOwnerF);
}
}
@Override FilesFragment fragment = new FilesFragment();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle args = new Bundle();
Bundle savedInstanceState) { args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
fragment.setArguments(args);
return fragment;
}
View v = inflater.inflate(R.layout.fragment_files, container, false); @Override
setHasOptionsMenu(true); public void onCreate(Bundle savedInstanceState) {
TinyDB tinyDb = new TinyDB(getContext()); super.onCreate(savedInstanceState);
final String instanceUrl = tinyDb.getString("instanceUrl"); if(getArguments() != null) {
final String loginUid = tinyDb.getString("loginUid"); repoName = getArguments().getString(repoNameF);
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); repoOwner = getArguments().getString(repoOwnerF);
}
}
noDataFiles = v.findViewById(R.id.noDataFiles); @Override
filesFrame = v.findViewById(R.id.filesFrame); public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fileStructure = v.findViewById(R.id.fileStructure); View v = inflater.inflate(R.layout.fragment_files, container, false);
mRecyclerView = v.findViewById(R.id.recyclerView); setHasOptionsMenu(true);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), TinyDB tinyDb = new TinyDB(getContext());
DividerItemDecoration.VERTICAL); final String instanceUrl = tinyDb.getString("instanceUrl");
mRecyclerView.addItemDecoration(dividerItemDecoration); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
mProgressBar = v.findViewById(R.id.progress_bar); noDataFiles = v.findViewById(R.id.noDataFiles);
filesFrame = v.findViewById(R.id.filesFrame);
mBreadcrumbsView = v.findViewById(R.id.breadcrumbs_view); fileStructure = v.findViewById(R.id.fileStructure);
mBreadcrumbsView.setItems(new ArrayList<>(Arrays.asList( mRecyclerView = v.findViewById(R.id.recyclerView);
BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot)) mRecyclerView.setHasFixedSize(true);
))); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
return v; mProgressBar = v.findViewById(R.id.progress_bar);
}
@Override mBreadcrumbsView = v.findViewById(R.id.breadcrumbs_view);
public void onResume() { mBreadcrumbsView.setItems(new ArrayList<>(Arrays.asList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot)))));
super.onResume();
}
private static BreadcrumbItem createItem(String title) { fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
List<String> list = new ArrayList<>();
list.add(title);
return new BreadcrumbItem(list);
}
@Override return v;
public void onClickDir(String dirName) { }
TinyDB tinyDb = new TinyDB(getContext()); @Override
final String instanceUrl = tinyDb.getString("instanceUrl"); public void onResume() {
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
StringBuilder breadcrumbBuilder = new StringBuilder(); super.onResume();
}
breadcrumbBuilder.append(fileStructure.getText().toString()).append("/").append(dirName); private static BreadcrumbItem createItem(String title) {
fileStructure.setText(breadcrumbBuilder); List<String> list = new ArrayList<>();
list.add(title);
return new BreadcrumbItem(list);
}
String dirName_ = fileStructure.getText().toString(); @Override
dirName_ = dirName_.startsWith("/") ? dirName_.substring(1) : dirName_; public void onClickDir(String dirName) {
final String finalDirName_ = dirName_;
mBreadcrumbsView.addItem(createItem(dirName)); TinyDB tinyDb = new TinyDB(getContext());
//noinspection unchecked final String instanceUrl = tinyDb.getString("instanceUrl");
mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() { final String loginUid = tinyDb.getString("loginUid");
@SuppressLint("SetTextI18n") final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@Override
public void onNavigateBack(BreadcrumbItem item, int position) {
if(position == 0) { StringBuilder breadcrumbBuilder = new StringBuilder();
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
fileStructure.setText("");
return;
}
String filterDir = fileStructure.getText().toString(); breadcrumbBuilder.append(fileStructure.getText().toString()).append("/").append(dirName);
String result = filterDir.substring(0, filterDir.indexOf(item.getSelectedItem()));
fileStructure.setText(result + item.getSelectedItem());
String currentIndex = (result + item.getSelectedItem()).substring(1); fileStructure.setText(breadcrumbBuilder);
fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, currentIndex); String dirName_ = fileStructure.getText().toString();
dirName_ = dirName_.startsWith("/") ? dirName_.substring(1) : dirName_;
final String finalDirName_ = dirName_;
} mBreadcrumbsView.addItem(createItem(dirName));
//noinspection unchecked
mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() {
@Override @SuppressLint("SetTextI18n")
public void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition) { @Override
public void onNavigateBack(BreadcrumbItem item, int position) {
} if(position == 0) {
}); fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
fileStructure.setText("");
return;
}
fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, finalDirName_); String filterDir = fileStructure.getText().toString();
String result = filterDir.substring(0, filterDir.indexOf(item.getSelectedItem()));
fileStructure.setText(result + item.getSelectedItem());
} String currentIndex = (result + item.getSelectedItem()).substring(1);
@Override fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, currentIndex);
public void onClickFile(String fileName) {
Intent intent = new Intent(getContext(), FileViewActivity.class); }
if(!fileStructure.getText().toString().equals("Root")) { @Override
public void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition) {
intent.putExtra("singleFileName", fileStructure.getText().toString()+"/"+fileName); }
} });
else {
intent.putExtra("singleFileName", fileName); fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, finalDirName_);
}
Objects.requireNonNull(getContext()).startActivity(intent); }
}
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { @Override
public void onClickFile(String fileName) {
mRecyclerView.setVisibility(View.GONE); Intent intent = new Intent(getContext(), FileViewActivity.class);
mProgressBar.setVisibility(View.VISIBLE);
FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); if(!fileStructure.getText().toString().equals("Root")) {
filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer<List<Files>>() { intent.putExtra("singleFileName", fileStructure.getText().toString() + "/" + fileName);
@Override }
public void onChanged(@Nullable List<Files> filesListMain) { else {
adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this);
mBreadcrumbsView.removeItemAfter(1); intent.putExtra("singleFileName", fileName);
if(adapter.getItemCount() > 0) { }
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(adapter);
filesFrame.setVisibility(View.VISIBLE);
noDataFiles.setVisibility(View.GONE);
}
else {
mRecyclerView.setVisibility(View.VISIBLE);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
filesFrame.setVisibility(View.VISIBLE);
noDataFiles.setVisibility(View.VISIBLE);
}
filesFrame.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
});
} Objects.requireNonNull(getContext()).startActivity(intent);
}
private void fetchDataAsyncSub(String instanceUrl, String instanceToken, String owner, String repo, String filesDir) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
mRecyclerView.setVisibility(View.GONE); mRecyclerView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.VISIBLE);
FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class); FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class);
filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, getContext()).observe(this, new Observer<List<Files>>() { filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer<List<Files>>() {
@Override
public void onChanged(@Nullable List<Files> filesListMain2) {
adapter = new FilesAdapter(getContext(), filesListMain2, FilesFragment.this);
if(adapter.getItemCount() > 0) {
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(adapter);
filesFrame.setVisibility(View.VISIBLE);
noDataFiles.setVisibility(View.GONE);
}
else {
mRecyclerView.setVisibility(View.VISIBLE);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
filesFrame.setVisibility(View.VISIBLE);
noDataFiles.setVisibility(View.VISIBLE);
}
filesFrame.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
});
} @Override
public void onChanged(@Nullable List<Files> filesListMain) {
@Override adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this);
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext())); mBreadcrumbsView.removeItemAfter(1);
if(adapter.getItemCount() > 0) {
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(adapter);
filesFrame.setVisibility(View.VISIBLE);
noDataFiles.setVisibility(View.GONE);
}
else {
mRecyclerView.setVisibility(View.VISIBLE);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
filesFrame.setVisibility(View.VISIBLE);
noDataFiles.setVisibility(View.VISIBLE);
}
filesFrame.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
});
inflater.inflate(R.menu.search_menu, menu); }
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search); private void fetchDataAsyncSub(String instanceUrl, String instanceToken, String owner, String repo, String filesDir) {
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
//searchView.setQueryHint(getContext().getString(R.string.search));
/*if(!connToInternet) { mRecyclerView.setVisibility(View.GONE);
return; mProgressBar.setVisibility(View.VISIBLE);
}*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class);
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, getContext()).observe(this, new Observer<List<Files>>() {
public boolean onQueryTextChange(String newText) {
if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
} @Override
public void onChanged(@Nullable List<Files> filesListMain2) {
public void onButtonPressed(Uri uri) { adapter = new FilesAdapter(getContext(), filesListMain2, FilesFragment.this);
if (mListener != null) { if(adapter.getItemCount() > 0) {
mListener.onFragmentInteraction(uri); mRecyclerView.setVisibility(View.VISIBLE);
} mRecyclerView.setAdapter(adapter);
} filesFrame.setVisibility(View.VISIBLE);
noDataFiles.setVisibility(View.GONE);
}
else {
mRecyclerView.setVisibility(View.VISIBLE);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
filesFrame.setVisibility(View.VISIBLE);
noDataFiles.setVisibility(View.VISIBLE);
}
filesFrame.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
});
@Override }
public void onDetach() {
super.onDetach(); @Override
mListener = null; public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
}
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
}
public void onButtonPressed(Uri uri) {
if(mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
} }

View File

@ -1,311 +0,0 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.adapters.IssuesAdapter;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.mikepenz.fastadapter.IItemAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
/**
* Author M M Arif
*/
public class IssuesClosedFragment extends Fragment implements ItemFilterListener<IssuesAdapter> {
private Context ctx;
private ProgressBar mProgressBarClosed;
private boolean loadNextFlag = false;
private String TAG = StaticGlobalVariables.tagIssuesListClosed;
private TextView noDataIssuesClosed;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private String requestType = StaticGlobalVariables.issuesRequestType;
private String issueState = StaticGlobalVariables.issueStateClosed;
private List<IssuesAdapter> items = new ArrayList<>();
private FastItemAdapter<IssuesAdapter> fastItemAdapter;
private ItemAdapter footerAdapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_issues_closed, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
if (VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
noDataIssuesClosed = v.findViewById(R.id.noDataIssuesClosed);
mProgressBarClosed = v.findViewById(R.id.progress_barClosed);
final SwipeRefreshLayout swipeRefreshLayout = v.findViewById(R.id.pullToRefreshClosed);
RecyclerView recyclerView = v.findViewById(R.id.recyclerViewClosed);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
fastItemAdapter = new FastItemAdapter<>();
fastItemAdapter.withSelectable(true);
footerAdapter = items();
//noinspection unchecked
fastItemAdapter.addAdapter(StaticGlobalVariables.issuesPageInit, footerAdapter);
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<IssuesAdapter>) (item, constraint) -> item.getIssueTitle().toLowerCase().contains(constraint.toString().toLowerCase()));
fastItemAdapter.getItemFilter().withItemFilterListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(fastItemAdapter);
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
@Override
public void onLoadMore(final int currentPage) {
loadNext(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, issueState, requestType, currentPage);
}
};
swipeRefreshLayout.setOnRefreshListener(() -> {
mProgressBarClosed.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
swipeRefreshLayout.setRefreshing(false);
});
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, issueState, resultLimit, requestType);
fastItemAdapter.withEventHook(new IssuesAdapter.IssueTitleClickEvent());
assert savedInstanceState != null;
fastItemAdapter.withSavedInstanceState(savedInstanceState);
return v;
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
if(tinyDb.getBoolean("resumeClosedIssues")) {
mProgressBarClosed.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
tinyDb.putBoolean("resumeClosedIssues", false);
}
}
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String issueState, int resultLimit, String requestType) {
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getClosedIssues(token, repoOwner, repoName, 1, issueState, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
if(response.body().size() == resultLimit) {
loadNextFlag = true;
}
for(int i = 0; i < response.body().size(); i++) {
items.add(new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
fastItemAdapter.add(items);
noDataIssuesClosed.setVisibility(View.GONE);
}
else {
noDataIssuesClosed.setVisibility(View.VISIBLE);
}
mProgressBarClosed.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String issueState, String requestType, final int currentPage) {
footerAdapter.clear();
//noinspection unchecked
footerAdapter.add(new ProgressItem().withEnabled(false));
Handler handler = new Handler();
handler.postDelayed(() -> {
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getClosedIssues(token, repoOwner, repoName, currentPage + 1, issueState, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
loadNextFlag = response.body().size() == resultLimit;
for(int i = 0; i < response.body().size(); i++) {
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
footerAdapter.clear();
mProgressBarClosed.setVisibility(View.GONE);
}
else {
footerAdapter.clear();
}
mProgressBarClosed.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.i(TAG, t.toString());
}
});
}, 1000);
if(!loadNextFlag) {
footerAdapter.clear();
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
fastItemAdapter.filter(newText);
return true;
}
});
endlessRecyclerOnScrollListener.enable();
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<IssuesAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}
@Override
public void onReset() {
endlessRecyclerOnScrollListener.enable();
}
}

View File

@ -0,0 +1,336 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.adapters.IssuesAdapter;
import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class IssuesFragment extends Fragment {
private Menu menu;
private RecyclerView recyclerView;
private List<Issues> issuesList;
private IssuesAdapter adapter;
private ApiInterface api;
private Context context;
private int pageSize = StaticGlobalVariables.issuesPageInit;
private ProgressBar mProgressBar;
private String TAG = StaticGlobalVariables.tagIssuesList;
private TextView noDataIssues;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private String requestType = StaticGlobalVariables.issuesRequestType;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_issues, container, false);
setHasOptionsMenu(true);
context = getContext();
TinyDB tinyDb = new TinyDB(getContext());
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
// if gitea is 1.12 or higher use the new limit
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
recyclerView = v.findViewById(R.id.recyclerView);
issuesList = new ArrayList<>();
mProgressBar = v.findViewById(R.id.progress_bar);
noDataIssues = v.findViewById(R.id.noDataIssues);
swipeRefresh.setOnRefreshListener(() -> new Handler().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.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
}
}));
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListener(issueState -> {
if(issueState.equals("closed")) {
menu.getItem(1).setIcon(R.drawable.ic_filter_closed);
}
else {
menu.getItem(1).setIcon(R.drawable.ic_filter);
}
issuesList.clear();
adapter = new IssuesAdapter(getContext(), issuesList);
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
if(issuesList.size() == resultLimit || pageSize == resultLimit) {
int page = (issuesList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
}
}));
tinyDb.putString("repoIssuesState", issueState);
mProgressBar.setVisibility(View.VISIBLE);
noDataIssues.setVisibility(View.GONE);
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType, issueState);
recyclerView.setAdapter(adapter);
});
api = AppApiService.createService(ApiInterface.class, instanceUrl, getContext());
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState"));
return v;
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("resumeIssues")) {
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), 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) {
Call<List<Issues>> call = api.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) {
//add loading progress view
issuesList.add(new Issues("load"));
adapter.notifyItemInserted((issuesList.size() - 1));
Call<List<Issues>> call = api.getIssues(token, repoOwner, repoName, page, 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) {
//remove loading view
issuesList.remove(issuesList.size() - 1);
List<Issues> result = response.body();
assert result != null;
if(result.size() > 0) {
pageSize = result.size();
issuesList.addAll(result);
}
else {
Toasty.info(context, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}
adapter.notifyDataChanged();
}
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());
}
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
this.menu = menu;
inflater.inflate(R.menu.search_menu, menu);
inflater.inflate(R.menu.filter_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
TinyDB tinyDb = new TinyDB(context);
if(tinyDb.getString("repoIssuesState").equals("closed")) {
menu.getItem(1).setIcon(R.drawable.ic_filter_closed);
}
else {
menu.getItem(1).setIcon(R.drawable.ic_filter);
}
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
return false;
}
});
}
private void filter(String text) {
List<Issues> arr = new ArrayList<>();
for(Issues d : issuesList) {
if(d.getTitle().toLowerCase().contains(text) || d.getBody().toLowerCase().contains(text)) {
arr.add(d);
}
}
adapter.updateList(arr);
}
}

View File

@ -1,155 +0,0 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.android.material.tabs.TabLayout;
import org.mian.gitnex.R;
import org.mian.gitnex.util.TinyDB;
import java.util.Objects;
/**
* Author M M Arif
*/
public class IssuesMainFragment extends Fragment {
private Context ctx;
public IssuesMainFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_issues_main, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
SectionsPagerAdapter mSectionsPagerAdapter = new IssuesMainFragment.SectionsPagerAdapter(getChildFragmentManager());
ViewPager mViewPager = v.findViewById(R.id.issuesContainer);
mViewPager.setAdapter(mSectionsPagerAdapter);
Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf");
}
else if (tinyDb.getInt("customFontId") == 1) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/manroperegular.ttf");
}
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf");
}
TabLayout tabLayout = v.findViewById(R.id.tabs);
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);
}
}
}
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
return v;
}
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0: // open issues
fragment = new IssuesOpenFragment();
break;
case 1: // closed issues
fragment = new IssuesClosedFragment();
break;
}
assert fragment != null;
return fragment;
}
@Override
public int getCount() {
return 2;
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.repo_dotted_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
return true;
case R.id.repoMenu:
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment();
bottomSheet.show(getChildFragmentManager(), "repoBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

View File

@ -1,308 +0,0 @@
package org.mian.gitnex.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.mikepenz.fastadapter.IItemAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.adapters.IssuesAdapter;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
/**
* Author M M Arif
*/
public class IssuesOpenFragment extends Fragment implements ItemFilterListener<IssuesAdapter> {
private ProgressBar mProgressBar;
private boolean loadNextFlag = false;
private String TAG = StaticGlobalVariables.tagIssuesListOpen;
private TextView noDataIssues;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private String requestType = StaticGlobalVariables.issuesRequestType;
private List<IssuesAdapter> items = new ArrayList<>();
private FastItemAdapter<IssuesAdapter> fastItemAdapter;
private ItemAdapter footerAdapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_issues, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
if (VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
noDataIssues = v.findViewById(R.id.noDataIssues);
mProgressBar = v.findViewById(R.id.progress_bar);
final SwipeRefreshLayout swipeRefreshLayout = v.findViewById(R.id.pullToRefresh);
RecyclerView recyclerView = v.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
fastItemAdapter = new FastItemAdapter<>();
fastItemAdapter.withSelectable(true);
footerAdapter = items();
//noinspection unchecked
fastItemAdapter.addAdapter(StaticGlobalVariables.issuesPageInit, footerAdapter);
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<IssuesAdapter>) (item, constraint) -> item.getIssueTitle().toLowerCase().contains(constraint.toString().toLowerCase()));
fastItemAdapter.getItemFilter().withItemFilterListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(fastItemAdapter);
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
@Override
public void onLoadMore(final int currentPage) {
loadNext(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, requestType, currentPage);
}
};
swipeRefreshLayout.setOnRefreshListener(() -> {
mProgressBar.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
swipeRefreshLayout.setRefreshing(false);
});
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, requestType);
fastItemAdapter.withEventHook(new IssuesAdapter.IssueTitleClickEvent());
assert savedInstanceState != null;
fastItemAdapter.withSavedInstanceState(savedInstanceState);
return v;
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
if(tinyDb.getBoolean("resumeIssues")) {
mProgressBar.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
tinyDb.putBoolean("resumeIssues", false);
}
}
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String requestType) {
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getIssues(token, repoOwner, repoName, 1, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
if(response.body().size() == resultLimit) {
loadNextFlag = true;
}
for(int i = 0; i < response.body().size(); i++) {
items.add(new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
fastItemAdapter.add(items);
noDataIssues.setVisibility(View.GONE);
}
else {
noDataIssues.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String requestType, final int currentPage) {
footerAdapter.clear();
//noinspection unchecked
footerAdapter.add(new ProgressItem().withEnabled(false));
Handler handler = new Handler();
handler.postDelayed(() -> {
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getIssues(token, repoOwner, repoName, currentPage + 1, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
loadNextFlag = response.body().size() == resultLimit;
for(int i = 0; i < response.body().size(); i++) {
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
footerAdapter.clear();
noDataIssues.setVisibility(View.GONE);
}
else {
footerAdapter.clear();
}
mProgressBar.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.i(TAG, t.toString());
}
});
}, 1000);
if(!loadNextFlag) {
footerAdapter.clear();
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
fastItemAdapter.filter(newText);
return true;
}
});
endlessRecyclerOnScrollListener.enable();
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<IssuesAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}
@Override
public void onReset() {
endlessRecyclerOnScrollListener.enable();
}
}

View File

@ -1,17 +1,9 @@
package org.mian.gitnex.fragments; package org.mian.gitnex.fragments;
import android.net.Uri; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
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 android.os.Handler; import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -19,17 +11,27 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar; import androidx.annotation.NonNull;
import android.widget.TextView; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.adapters.MilestonesAdapter; import org.mian.gitnex.adapters.MilestonesAdapter;
import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.databinding.FragmentMilestonesBinding;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.MilestonesViewModel; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -37,89 +39,113 @@ import java.util.Objects;
public class MilestonesFragment extends Fragment { public class MilestonesFragment extends Fragment {
private ProgressBar mProgressBar; private FragmentMilestonesBinding viewBinding;
private Menu menu;
private List<Milestones> dataList;
private MilestonesAdapter adapter; private MilestonesAdapter adapter;
private RecyclerView mRecyclerView; private ApiInterface api;
private TextView noDataMilestone; private Context ctx;
private static String repoNameF = "param2"; private int pageSize = StaticGlobalVariables.milestonesPageInit;
private static String repoOwnerF = "param1"; private String TAG = StaticGlobalVariables.tagMilestonesFragment;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private String repoName;
private String repoOwner;
private String msState = "all";
private OnFragmentInteractionListener mListener;
public MilestonesFragment() {
}
public static MilestonesFragment newInstance(String param1, String param2) {
MilestonesFragment fragment = new MilestonesFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
fragment.setArguments(args);
return fragment;
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
repoName = getArguments().getString(repoNameF);
repoOwner = getArguments().getString(repoOwnerF);
}
}
@Override viewBinding = FragmentMilestonesBinding.inflate(inflater, container, false);
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_milestones, container, false);
setHasOptionsMenu(true); setHasOptionsMenu(true);
ctx = getContext();
TinyDB tinyDb = new TinyDB(getContext()); TinyDB tinyDb = new TinyDB(getContext());
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
noDataMilestone = v.findViewById(R.id.noDataMilestone);
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); viewBinding.recyclerView.setHasFixedSize(true);
viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView = v.findViewById(R.id.recyclerView); // if gitea is 1.12 or higher use the new limit
mRecyclerView.setHasFixedSize(true); if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), dataList = new ArrayList<>();
DividerItemDecoration.VERTICAL); adapter = new MilestonesAdapter(ctx, dataList);
mRecyclerView.addItemDecoration(dividerItemDecoration);
mProgressBar = v.findViewById(R.id.progress_bar); adapter.setLoadMoreListener(() -> viewBinding.recyclerView.post(() -> {
if(dataList.size() == resultLimit || pageSize == resultLimit) {
int page = (dataList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, tinyDb.getString("milestoneState"));
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, msState, getContext());
}
}, 50);
} }
}));
viewBinding.recyclerView.setHasFixedSize(true);
viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
viewBinding.recyclerView.setAdapter(adapter);
viewBinding.pullToRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
dataList.clear();
viewBinding.pullToRefresh.setRefreshing(false);
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState"));
adapter.updateList(dataList);
}, 50));
((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListenerMilestone(milestoneState -> {
if(milestoneState.equals("closed")) {
menu.getItem(1).setIcon(R.drawable.ic_filter_closed);
}
else {
menu.getItem(1).setIcon(R.drawable.ic_filter);
}
dataList.clear();
adapter = new MilestonesAdapter(ctx, dataList);
adapter.setLoadMoreListener(() -> viewBinding.recyclerView.post(() -> {
if(dataList.size() == resultLimit || pageSize == resultLimit) {
int page = (dataList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, milestoneState);
}
}));
tinyDb.putString("milestoneState", milestoneState);
viewBinding.progressBar.setVisibility(View.VISIBLE);
viewBinding.noDataMilestone.setVisibility(View.GONE);
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, milestoneState);
viewBinding.recyclerView.setAdapter(adapter);
}); });
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); api = AppApiService.createService(ApiInterface.class, instanceUrl, ctx);
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState"));
return viewBinding.getRoot();
return v;
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
final TinyDB tinyDb = new TinyDB(getContext()); TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
@ -128,82 +154,168 @@ public class MilestonesFragment extends Fragment {
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("milestoneCreated")) { if(tinyDb.getBoolean("milestoneCreated")) {
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, msState, getContext());
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState"));
tinyDb.putBoolean("milestoneCreated", false); tinyDb.putBoolean("milestoneCreated", false);
} }
} }
public void onButtonPressed(Uri uri) { private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String milestoneState) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override Call<List<Milestones>> call = api.getMilestones(token, repoOwner, repoName, 1, resultLimit, milestoneState);
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener { call.enqueue(new Callback<List<Milestones>>() {
void onFragmentInteraction(Uri uri);
}
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
MilestonesViewModel msModel = new ViewModelProvider(this).get(MilestonesViewModel.class);
msModel.getMilestonesList(instanceUrl, instanceToken, owner, repo, msState, getContext()).observe(getViewLifecycleOwner(), new Observer<List<Milestones>>() {
@Override @Override
public void onChanged(@Nullable List<Milestones> msListMain) { public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull Response<List<Milestones>> response) {
adapter = new MilestonesAdapter(getContext(), msListMain);
if(adapter.getItemCount() > 0) { if(response.isSuccessful()) {
mRecyclerView.setAdapter(adapter);
noDataMilestone.setVisibility(View.GONE); assert response.body() != null;
if(response.body().size() > 0) {
dataList.clear();
dataList.addAll(response.body());
adapter.notifyDataChanged();
viewBinding.noDataMilestone.setVisibility(View.GONE);
}
else {
dataList.clear();
adapter.notifyDataChanged();
viewBinding.noDataMilestone.setVisibility(View.VISIBLE);
}
viewBinding.progressBar.setVisibility(View.GONE);
} }
else { else {
adapter.notifyDataSetChanged(); Log.e(TAG, String.valueOf(response.code()));
mRecyclerView.setAdapter(adapter);
noDataMilestone.setVisibility(View.VISIBLE);
} }
mProgressBar.setVisibility(View.GONE);
} }
@Override
public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
}); });
} }
private void loadMore(String token, String repoOwner, String repoName, int page, int resultLimit, String milestoneState) {
//add loading progress view
dataList.add(new Milestones("load"));
adapter.notifyItemInserted((dataList.size() - 1));
Call<List<Milestones>> call = api.getMilestones(token, repoOwner, repoName, page, resultLimit, milestoneState);
call.enqueue(new Callback<List<Milestones>>() {
@Override
public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull Response<List<Milestones>> response) {
if(response.isSuccessful()) {
//remove loading view
dataList.remove(dataList.size() - 1);
List<Milestones> result = response.body();
assert result != null;
if(result.size() > 0) {
pageSize = result.size();
dataList.addAll(result);
}
else {
Toasty.info(ctx, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}
adapter.notifyDataChanged();
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
@Override @Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext())); this.menu = menu;
inflater.inflate(R.menu.search_menu, menu); inflater.inflate(R.menu.search_menu, menu);
inflater.inflate(R.menu.filter_menu_milestone, menu);
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
TinyDB tinyDb = new TinyDB(ctx);
if(tinyDb.getString("milestoneState").equals("closed")) {
menu.getItem(1).setIcon(R.drawable.ic_filter_closed);
}
else {
menu.getItem(1).setIcon(R.drawable.ic_filter);
}
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
//searchView.setQueryHint(getContext().getString(R.string.strFilter));
/*if(!connToInternet) {
return;
}*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override @Override
public boolean onQueryTextSubmit(String query) { public boolean onQueryTextSubmit(String query) {
return false; return false;
} }
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText); filter(newText);
}
return false; return false;
} }
}); });
} }
private void filter(String text) {
List<Milestones> arr = new ArrayList<>();
for(Milestones d : dataList) {
if(d.getTitle().toLowerCase().contains(text) || d.getDescription().toLowerCase().contains(text)) {
arr.add(d);
}
}
adapter.updateList(arr);
}
} }

View File

@ -2,13 +2,6 @@ package org.mian.gitnex.fragments;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
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;
import android.os.Handler; import android.os.Handler;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -20,14 +13,23 @@ import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; 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;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.adapters.PullRequestsAdapter; import org.mian.gitnex.adapters.PullRequestsAdapter;
import org.mian.gitnex.clients.PullRequestsService; import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.PullRequests; import org.mian.gitnex.models.PullRequests;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -42,254 +44,300 @@ import retrofit2.Response;
public class PullRequestsFragment extends Fragment { public class PullRequestsFragment extends Fragment {
private ProgressBar mProgressBar; private Menu menu;
private RecyclerView recyclerView; private ProgressBar mProgressBar;
private List<PullRequests> prList; private RecyclerView recyclerView;
private PullRequestsAdapter adapter; private List<PullRequests> prList;
private ApiInterface apiPR; private PullRequestsAdapter adapter;
private String TAG = "PullRequestsListFragment - "; private ApiInterface apiPR;
private Context context; private String TAG = StaticGlobalVariables.tagPullRequestsList;
private int pageSize = 1; private Context context;
private TextView noData; private int pageSize = StaticGlobalVariables.prPageInit;
private String prState = "open"; private TextView noData;
private int resultLimit = 50; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_pull_requests, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext()); @Nullable
String repoFullName = tinyDb.getString("repoFullName"); @Override
//Log.i("repoFullName", tinyDb.getString("repoFullName")); public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); final View v = inflater.inflate(R.layout.fragment_pull_requests, container, false);
setHasOptionsMenu(true);
context = getContext();
context = getContext(); TinyDB tinyDb = new TinyDB(getContext());
recyclerView = v.findViewById(R.id.recyclerView); String repoFullName = tinyDb.getString("repoFullName");
prList = new ArrayList<>(); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
mProgressBar = v.findViewById(R.id.progress_bar); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
noData = v.findViewById(R.id.noData);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { // if gitea is 1.12 or higher use the new limit
@Override if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
public void onRefresh() { resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
new Handler().postDelayed(new Runnable() { }
@Override
public void run() {
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, pageSize, prState, resultLimit);
adapter.notifyDataChanged();
}
}, 200);
}
});
adapter = new PullRequestsAdapter(getContext(), prList);
adapter.setLoadMoreListener(new PullRequestsAdapter.OnLoadMoreListener() {
@Override
public void onLoadMore() {
recyclerView.post(new Runnable() { recyclerView = v.findViewById(R.id.recyclerView);
@Override prList = new ArrayList<>();
public void run() {
if(prList.size() == 10 || pageSize == 10) {
int page = (prList.size() + 10) / 10; mProgressBar = v.findViewById(R.id.progress_bar);
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, prState, resultLimit); noData = v.findViewById(R.id.noData);
} swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
/*else {
Toasty.info(context, getString(R.string.noMoreData)); swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit);
adapter.notifyDataChanged();
}*/ }, 200));
}
});
} adapter = new PullRequestsAdapter(getContext(), prList);
}); adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), if(prList.size() == 10 || pageSize == resultLimit) {
DividerItemDecoration.VERTICAL);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
apiPR = PullRequestsService.createService(ApiInterface.class, instanceUrl, getContext()); int page = (prList.size() + resultLimit) / resultLimit;
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit); loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit);
return v; }
} }));
@Override DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
public void onResume() { recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
super.onResume(); ((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListenerPr(prState -> {
TinyDB tinyDb = new TinyDB(getContext());
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("resumePullRequests")) { if(prState.equals("closed")) {
menu.getItem(1).setIcon(R.drawable.ic_filter_closed);
}
else {
menu.getItem(1).setIcon(R.drawable.ic_filter);
}
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit); prList.clear();
tinyDb.putBoolean("resumePullRequests", false);
tinyDb.putBoolean("prMerged", false);
} adapter = new PullRequestsAdapter(context, prList);
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
} if(prList.size() == 10 || pageSize == resultLimit) {
private void loadInitial(String token, String repoOwner, String repoName, int page, String prState, int resultLimit) { int page = (prList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit);
Call<List<PullRequests>> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); }
call.enqueue(new Callback<List<PullRequests>>() { }));
@Override tinyDb.putString("repoPrState", prState);
public void onResponse(@NonNull Call<List<PullRequests>> call, @NonNull Response<List<PullRequests>> response) {
if(response.isSuccessful()) { mProgressBar.setVisibility(View.VISIBLE);
noData.setVisibility(View.GONE);
assert response.body() != null; loadInitial(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit);
if(response.body().size() > 0) { recyclerView.setAdapter(adapter);
prList.clear(); });
prList.addAll(response.body());
adapter.notifyDataChanged();
noData.setVisibility(View.GONE);
} apiPR = AppApiService.createService(ApiInterface.class, instanceUrl, context);
else { loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit);
prList.clear();
adapter.notifyDataChanged();
noData.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
Log.i("http", String.valueOf(response.code())); return v;
} }
@Override @Override
public void onFailure(@NonNull Call<List<PullRequests>> call, @NonNull Throwable t) { public void onResume() {
Log.e(TAG, t.toString());
}
}); super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
} if(tinyDb.getBoolean("resumePullRequests")) {
private void loadMore(String token, String repoOwner, String repoName, int page, String prState, int resultLimit){ loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit);
tinyDb.putBoolean("resumePullRequests", false);
tinyDb.putBoolean("prMerged", false);
//add loading progress view }
prList.add(new PullRequests("load"));
adapter.notifyItemInserted((prList.size() - 1));
Call<List<PullRequests>> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); }
call.enqueue(new Callback<List<PullRequests>>() { private void loadInitial(String token, String repoOwner, String repoName, int page, String prState, int resultLimit) {
@Override Call<List<PullRequests>> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit);
public void onResponse(@NonNull Call<List<PullRequests>> call, @NonNull Response<List<PullRequests>> response) {
if(response.isSuccessful()){ call.enqueue(new Callback<List<PullRequests>>() {
//remove loading view @Override
prList.remove(prList.size()-1); public void onResponse(@NonNull Call<List<PullRequests>> call, @NonNull Response<List<PullRequests>> response) {
List<PullRequests> result = response.body(); if(response.code() == 200) {
assert result != null; assert response.body() != null;
if(result.size() > 0) { if(response.body().size() > 0) {
pageSize = result.size(); prList.clear();
prList.addAll(result); prList.addAll(response.body());
adapter.notifyDataChanged();
noData.setVisibility(View.GONE);
} }
else { else {
Toasty.info(context, getString(R.string.noMoreData)); prList.clear();
adapter.setMoreDataAvailable(false); adapter.notifyDataChanged();
noData.setVisibility(View.VISIBLE);
} }
adapter.notifyDataChanged(); mProgressBar.setVisibility(View.GONE);
} }
else { else if(response.code() == 404) {
Log.e(TAG, String.valueOf(response.code())); noData.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
} }
else {
} Log.i(TAG, String.valueOf(response.code()));
@Override }
public void onFailure(@NonNull Call<List<PullRequests>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString()); Log.i(TAG, String.valueOf(response.code()));
} }
}); @Override
} public void onFailure(@NonNull Call<List<PullRequests>> call, @NonNull Throwable t) {
@Override Log.e(TAG, t.toString());
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { }
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext())); });
inflater.inflate(R.menu.search_menu, menu); }
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search); private void loadMore(String token, String repoOwner, String repoName, int page, String prState, int resultLimit) {
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
//searchView.setQueryHint(getContext().getString(R.string.strFilter));
/*if(!connToInternet) { //add loading progress view
return; prList.add(new PullRequests("load"));
}*/ adapter.notifyItemInserted((prList.size() - 1));
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { Call<List<PullRequests>> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit);
@Override call.enqueue(new Callback<List<PullRequests>>() {
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override @Override
public boolean onQueryTextChange(String newText) { public void onResponse(@NonNull Call<List<PullRequests>> call, @NonNull Response<List<PullRequests>> response) {
adapter.getFilter().filter(newText); if(response.code() == 200) {
return false;
} //remove loading view
prList.remove(prList.size() - 1);
}); List<PullRequests> result = response.body();
} assert result != null;
if(result.size() > 0) {
pageSize = result.size();
prList.addAll(result);
}
else {
Toasty.info(context, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}
adapter.notifyDataChanged();
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<PullRequests>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
this.menu = menu;
inflater.inflate(R.menu.search_menu, menu);
inflater.inflate(R.menu.filter_menu_pr, menu);
super.onCreateOptionsMenu(menu, inflater);
TinyDB tinyDb = new TinyDB(context);
if(tinyDb.getString("repoPrState").equals("closed")) {
menu.getItem(1).setIcon(R.drawable.ic_filter_closed);
}
else {
menu.getItem(1).setIcon(R.drawable.ic_filter);
}
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
return false;
}
});
}
private void filter(String text) {
List<PullRequests> arr = new ArrayList<>();
for(PullRequests d : prList) {
if(d.getTitle().toLowerCase().contains(text) || d.getBody().toLowerCase().contains(text)) {
arr.add(d);
}
}
adapter.updateList(arr);
}
} }

View File

@ -317,6 +317,8 @@ public class RepoInfoFragment extends Fragment {
tinyDb.putBoolean("hasIssues", true); tinyDb.putBoolean("hasIssues", true);
} }
tinyDb.putString("repoHtmlUrl", repoInfo.getHtml_url());
mProgressBar.setVisibility(View.GONE); mProgressBar.setVisibility(View.GONE);
pageContent.setVisibility(View.VISIBLE); pageContent.setVisibility(View.VISIBLE);

View File

@ -1,23 +1,20 @@
package org.mian.gitnex.fragments; package org.mian.gitnex.fragments;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.activities.SettingsAppearanceActivity;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.activities.SettingsFileViewerActivity;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager; import org.mian.gitnex.activities.SettingsReportsActivity;
import org.mian.gitnex.activities.SettingsSecurityActivity;
import org.mian.gitnex.activities.SettingsTranslationActivity;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.Objects; import java.util.Objects;
@ -27,518 +24,44 @@ import java.util.Objects;
public class SettingsFragment extends Fragment { public class SettingsFragment extends Fragment {
private Context ctx = null;
private static String[] langList = {"Arabic", "Chinese", "English", "Finnish", "French", "German", "Italian", "Latvian", "Persian", "Polish", "Portuguese/Brazilian", "Russian", "Serbian", "Spanish", "Turkish", "Ukrainian"};
private static int langSelectedChoice = 0;
private static String[] timeList = {"Pretty", "Normal"};
private static int timeSelectedChoice = 0;
private static String[] codeBlockList = {"Green - Black", "White - Black", "Grey - Black", "White - Grey", "Dark - White"};
private static int codeBlockSelectedChoice = 0;
private static String[] homeScreenList = {"My Repositories", "Starred Repositories", "Organizations", "Repositories", "Profile"};
private static int homeScreenSelectedChoice = 0;
private static String[] customFontList = {"Roboto", "Manrope", "Source Code Pro"};
private static int customFontSelectedChoice = 0;
private static String[] themeList = {"Dark", "Light", "Auto (Day/Night)"};
private static int themeSelectedChoice = 0;
private static String[] fileveiwerSourceCodeThemesList = {"Sublime", "Arduino Light", "Github", "Far ", "Ir Black", "Android Studio"};
private static int fileveiwerSourceCodeThemesSelectedChoice = 0;
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_settings, container, false); View v = inflater.inflate(R.layout.fragment_settings, container, false);
final TinyDB tinyDb = new TinyDB(getContext());
final TextView tvLanguageSelected = v.findViewById(R.id.tvLanguageSelected); // setter for en, fr LinearLayout appearanceFrame = v.findViewById(R.id.appearanceFrame);
final TextView tvDateTimeSelected = v.findViewById(R.id.tvDateTimeSelected); // setter for time LinearLayout fileViewerFrame = v.findViewById(R.id.fileViewerFrame);
final TextView codeBlockSelected = v.findViewById(R.id.codeBlockSelected); // setter for code block LinearLayout securityFrame = v.findViewById(R.id.securityFrame);
final TextView homeScreenSelected = v.findViewById(R.id.homeScreenSelected); // setter for home screen LinearLayout languagesFrame = v.findViewById(R.id.languagesFrame);
final TextView customFontSelected = v.findViewById(R.id.customFontSelected); // setter for custom font LinearLayout reportsFrame = v.findViewById(R.id.reportsFrame);
final TextView themeSelected = v.findViewById(R.id.themeSelected); // setter for theme
final TextView fileveiwerSourceCodeThemesSelected = v.findViewById(R.id.sourceCodeThemeSelected); // setter for fileviewer theme
LinearLayout langFrame = v.findViewById(R.id.langFrame); appearanceFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsAppearanceActivity.class)));
LinearLayout timeFrame = v.findViewById(R.id.timeFrame);
LinearLayout codeBlockFrame = v.findViewById(R.id.codeBlockFrame);
LinearLayout homeScreenFrame = v.findViewById(R.id.homeScreenFrame);
LinearLayout customFontFrame = v.findViewById(R.id.customFontFrame);
LinearLayout themeFrame = v.findViewById(R.id.themeSelectionFrame);
LinearLayout certsFrame = v.findViewById(R.id.certsFrame);
LinearLayout sourceCodeThemeFrame = v.findViewById(R.id.sourceCodeThemeFrame);
Switch counterBadgesSwitch = v.findViewById(R.id.switchCounterBadge); fileViewerFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsFileViewerActivity.class)));
Switch pdfModeSwitch = v.findViewById(R.id.switchPdfMode);
Switch crashReportsSwitch = v.findViewById(R.id.crashReportsSwitch);
TextView helpTranslate = v.findViewById(R.id.helpTranslate);
helpTranslate.setOnClickListener(v12 -> { securityFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsSecurityActivity.class)));
Intent intent = new Intent(); languagesFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsTranslationActivity.class)));
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse(getResources().getString(R.string.crowdInLink)));
startActivity(intent);
}); reportsFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsReportsActivity.class)));
if(!tinyDb.getString("localeStr").isEmpty()) {
tvLanguageSelected.setText(tinyDb.getString("localeStr"));
}
if(!tinyDb.getString("timeStr").isEmpty()) {
tvDateTimeSelected.setText(tinyDb.getString("timeStr"));
}
if(!tinyDb.getString("codeBlockStr").isEmpty()) {
codeBlockSelected.setText(tinyDb.getString("codeBlockStr"));
}
if(!tinyDb.getString("homeScreenStr").isEmpty()) {
homeScreenSelected.setText(tinyDb.getString("homeScreenStr"));
}
if(!tinyDb.getString("customFontStr").isEmpty()) {
customFontSelected.setText(tinyDb.getString("customFontStr"));
}
if(!tinyDb.getString("themeStr").isEmpty()) {
themeSelected.setText(tinyDb.getString("themeStr"));
}
if(!tinyDb.getString("fileviewerSourceCodeThemeStr").isEmpty()) {
fileveiwerSourceCodeThemesSelected.setText(tinyDb.getString("fileviewerSourceCodeThemeStr"));
}
if(langSelectedChoice == 0) {
langSelectedChoice = tinyDb.getInt("langId");
}
if(timeSelectedChoice == 0) {
timeSelectedChoice = tinyDb.getInt("timeId");
}
if(codeBlockSelectedChoice == 0) {
codeBlockSelectedChoice = tinyDb.getInt("codeBlockId");
}
if(homeScreenSelectedChoice == 0) {
homeScreenSelectedChoice = tinyDb.getInt("homeScreenId");
}
if(customFontSelectedChoice == 0) {
customFontSelectedChoice = tinyDb.getInt("customFontId", 1);
}
if(themeSelectedChoice == 0) {
themeSelectedChoice = tinyDb.getInt("themeId");
}
if(fileveiwerSourceCodeThemesSelectedChoice == 0) {
fileveiwerSourceCodeThemesSelectedChoice = tinyDb.getInt("fileviewerThemeId");
}
if(tinyDb.getBoolean("enableCounterBadges")) {
counterBadgesSwitch.setChecked(true);
}
else {
counterBadgesSwitch.setChecked(false);
}
if(tinyDb.getBoolean("enablePdfMode")) {
pdfModeSwitch.setChecked(true);
}
else {
pdfModeSwitch.setChecked(false);
}
if(tinyDb.getBoolean("crashReportingEnabled")) {
crashReportsSwitch.setChecked(true);
}
else {
crashReportsSwitch.setChecked(false);
}
// fileviewer srouce code theme selection dialog
sourceCodeThemeFrame.setOnClickListener(view -> {
AlertDialog.Builder fvtsBuilder = new AlertDialog.Builder(ctx);
fvtsBuilder.setTitle(R.string.fileviewerSourceCodeThemeSelectorDialogTitle);
if(fileveiwerSourceCodeThemesSelectedChoice != -1) {
fvtsBuilder.setCancelable(true);
}
else {
fvtsBuilder.setCancelable(false);
}
fvtsBuilder.setSingleChoiceItems(fileveiwerSourceCodeThemesList, fileveiwerSourceCodeThemesSelectedChoice, (dialogInterfaceTheme, i) -> {
fileveiwerSourceCodeThemesSelectedChoice = i;
fileveiwerSourceCodeThemesSelected.setText(fileveiwerSourceCodeThemesList[i]);
tinyDb.putString("fileviewerSourceCodeThemeStr", fileveiwerSourceCodeThemesList[i]);
tinyDb.putInt("fileviewerSourceCodeThemeId", i);
Objects.requireNonNull(getActivity()).recreate();
getActivity().overridePendingTransition(0, 0);
dialogInterfaceTheme.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = fvtsBuilder.create();
cfDialog.show();
});
// certs deletion
certsFrame.setOnClickListener(v1 -> {
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle(getResources().getString(R.string.settingsCertsPopupTitle));
builder.setMessage(getResources().getString(R.string.settingsCertsPopupMessage));
builder.setPositiveButton(R.string.menuDeleteText, (dialog, which) -> {
ctx.getSharedPreferences(MemorizingTrustManager.KEYSTORE_NAME, Context.MODE_PRIVATE).edit().remove(MemorizingTrustManager.KEYSTORE_KEY).apply();
MainActivity.logout(Objects.requireNonNull(getActivity()), ctx);
});
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
builder.create().show();
});
// counter badge switcher
counterBadgesSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (isChecked) {
tinyDb.putBoolean("enableCounterBadges", true);
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
else {
tinyDb.putBoolean("enableCounterBadges", false);
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
});
// pdf night mode switcher
pdfModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked) {
tinyDb.putBoolean("enablePdfMode", true);
tinyDb.putString("enablePdfModeInit", "yes");
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
else {
tinyDb.putBoolean("enablePdfMode", false);
tinyDb.putString("enablePdfModeInit", "yes");
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
});
// crash reports switcher
crashReportsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked) {
tinyDb.putBoolean("crashReportingEnabled", true);
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
else {
tinyDb.putBoolean("crashReportingEnabled", false);
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
});
// theme selection dialog
themeFrame.setOnClickListener(view -> {
AlertDialog.Builder tsBuilder = new AlertDialog.Builder(ctx);
tsBuilder.setTitle(R.string.themeSelectorDialogTitle);
if(themeSelectedChoice != -1) {
tsBuilder.setCancelable(true);
}
else {
tsBuilder.setCancelable(false);
}
tsBuilder.setSingleChoiceItems(themeList, themeSelectedChoice, (dialogInterfaceTheme, i) -> {
themeSelectedChoice = i;
themeSelected.setText(themeList[i]);
tinyDb.putString("themeStr", themeList[i]);
tinyDb.putInt("themeId", i);
Objects.requireNonNull(getActivity()).recreate();
getActivity().overridePendingTransition(0, 0);
dialogInterfaceTheme.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = tsBuilder.create();
cfDialog.show();
});
// custom font dialog
customFontFrame.setOnClickListener(view -> {
AlertDialog.Builder cfBuilder = new AlertDialog.Builder(ctx);
cfBuilder.setTitle(R.string.settingsCustomFontSelectorDialogTitle);
if(customFontSelectedChoice != -1) {
cfBuilder.setCancelable(true);
}
else {
cfBuilder.setCancelable(false);
}
cfBuilder.setSingleChoiceItems(customFontList, customFontSelectedChoice, (dialogInterfaceCustomFont, i) -> {
customFontSelectedChoice = i;
customFontSelected.setText(customFontList[i]);
tinyDb.putString("customFontStr", customFontList[i]);
tinyDb.putInt("customFontId", i);
Objects.requireNonNull(getActivity()).recreate();
getActivity().overridePendingTransition(0, 0);
dialogInterfaceCustomFont.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = cfBuilder.create();
cfDialog.show();
});
// home screen dialog
homeScreenFrame.setOnClickListener(view -> {
AlertDialog.Builder hsBuilder = new AlertDialog.Builder(ctx);
hsBuilder.setTitle(R.string.settingshomeScreenSelectorDialogTitle);
if(homeScreenSelectedChoice != -1) {
hsBuilder.setCancelable(true);
}
else {
hsBuilder.setCancelable(false);
}
hsBuilder.setSingleChoiceItems(homeScreenList, homeScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> {
homeScreenSelectedChoice = i;
homeScreenSelected.setText(homeScreenList[i]);
tinyDb.putString("homeScreenStr", homeScreenList[i]);
tinyDb.putInt("homeScreenId", i);
dialogInterfaceHomeScreen.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
});
AlertDialog hsDialog = hsBuilder.create();
hsDialog.show();
});
// code block dialog
codeBlockFrame.setOnClickListener(view -> {
AlertDialog.Builder cBuilder = new AlertDialog.Builder(ctx);
cBuilder.setTitle(R.string.settingsCodeBlockSelectorDialogTitle);
if(codeBlockSelectedChoice != -1) {
cBuilder.setCancelable(true);
}
else {
cBuilder.setCancelable(false);
}
cBuilder.setSingleChoiceItems(codeBlockList, codeBlockSelectedChoice, (dialogInterfaceCodeBlock, i) -> {
codeBlockSelectedChoice = i;
codeBlockSelected.setText(codeBlockList[i]);
tinyDb.putString("codeBlockStr", codeBlockList[i]);
tinyDb.putInt("codeBlockId", i);
switch(codeBlockList[i]) {
case "White - Black":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
case "Grey - Black":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorAccent));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
case "White - Grey":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorAccent));
break;
case "Dark - White":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorPrimary));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.white));
break;
default:
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
}
dialogInterfaceCodeBlock.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
});
AlertDialog cDialog = cBuilder.create();
cDialog.show();
});
// language dialog
langFrame.setOnClickListener(view -> {
AlertDialog.Builder lBuilder = new AlertDialog.Builder(ctx);
lBuilder.setTitle(R.string.settingsLanguageSelectorDialogTitle);
if(langSelectedChoice != -1) {
lBuilder.setCancelable(true);
}
else {
lBuilder.setCancelable(false);
}
lBuilder.setSingleChoiceItems(langList, langSelectedChoice, (dialogInterface, i) -> {
langSelectedChoice = i;
tvLanguageSelected.setText(langList[i]);
tinyDb.putString("localeStr", langList[i]);
tinyDb.putInt("langId", i);
switch(langList[i]) {
case "Arabic":
tinyDb.putString("locale", "ar");
break;
case "Chinese":
tinyDb.putString("locale", "zh");
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;
}
dialogInterface.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
Objects.requireNonNull(getActivity()).recreate();
getActivity().overridePendingTransition(0, 0);
});
lBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> dialog.dismiss());
AlertDialog lDialog = lBuilder.create();
lDialog.show();
});
// time n date dialog
timeFrame.setOnClickListener(view -> {
AlertDialog.Builder tBuilder = new AlertDialog.Builder(ctx);
tBuilder.setTitle(R.string.settingsTimeSelectorDialogTitle);
if(timeSelectedChoice != -1) {
tBuilder.setCancelable(true);
}
else {
tBuilder.setCancelable(false);
}
tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, (dialogInterfaceTime, i) -> {
timeSelectedChoice = i;
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");
}
dialogInterfaceTime.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
});
AlertDialog tDialog = tBuilder.create();
tDialog.show();
});
return v; return v;
} }
@Override @Override
public void onAttach(@NonNull Context context) { public void onResume() {
super.onAttach(context); super.onResume();
ctx = context;
TinyDB tinyDb = new TinyDB(getContext());
if(tinyDb.getBoolean("refreshParent")) {
Objects.requireNonNull(getActivity()).recreate();
getActivity().overridePendingTransition(0, 0);
tinyDb.putBoolean("refreshParent", false);
}
} }

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.TeamActions;
import org.mian.gitnex.activities.CreateLabelActivity; import org.mian.gitnex.activities.CreateLabelActivity;
import org.mian.gitnex.activities.LoginActivity; import org.mian.gitnex.activities.LoginActivity;
import org.mian.gitnex.actions.CollaboratorActions; import org.mian.gitnex.actions.CollaboratorActions;
@ -25,25 +26,17 @@ public class AlertDialogs {
.setMessage(message) .setMessage(message)
.setCancelable(true) .setCancelable(true)
.setIcon(R.drawable.ic_warning) .setIcon(R.drawable.ic_warning)
.setNegativeButton(copyNegativeButton, new DialogInterface.OnClickListener() { .setNegativeButton(copyNegativeButton, (dialog, which) -> dialog.dismiss())
@Override .setPositiveButton(copyPositiveButton, (dialog, which) -> {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton(copyPositiveButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final TinyDB tinyDb = new TinyDB(context); final TinyDB tinyDb = new TinyDB(context);
tinyDb.putBoolean("loggedInMode", false); tinyDb.putBoolean("loggedInMode", false);
tinyDb.remove("basicAuthPassword"); tinyDb.remove("basicAuthPassword");
tinyDb.putBoolean("basicAuthFlag", false); tinyDb.putBoolean("basicAuthFlag", false);
Intent intent = new Intent(context, LoginActivity.class); Intent intent = new Intent(context, LoginActivity.class);
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); dialog.dismiss();
}
}); });
AlertDialog alertDialog = alertDialogBuilder.create(); AlertDialog alertDialog = alertDialogBuilder.create();
@ -56,15 +49,14 @@ public class AlertDialogs {
.setTitle(title + labelTitle) .setTitle(title + labelTitle)
.setMessage(message) .setMessage(message)
.setIcon(R.drawable.ic_delete) .setIcon(R.drawable.ic_delete)
.setPositiveButton(positiveButton, new DialogInterface.OnClickListener() { .setPositiveButton(positiveButton, (dialog, whichButton) -> {
public void onClick(DialogInterface dialog, int whichButton) {
Intent intent = new Intent(context, CreateLabelActivity.class); Intent intent = new Intent(context, CreateLabelActivity.class);
intent.putExtra("labelId", labelId); intent.putExtra("labelId", labelId);
intent.putExtra("labelAction", "delete"); intent.putExtra("labelAction", "delete");
context.startActivity(intent); context.startActivity(intent);
}}) })
.setNegativeButton(negativeButton, null).show(); .setNegativeButton(negativeButton, null).show();
} }
@ -74,13 +66,27 @@ public class AlertDialogs {
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setTitle(title + userNameMain) .setTitle(title + userNameMain)
.setMessage(message) .setMessage(message)
.setIcon(R.drawable.ic_warning) .setPositiveButton(positiveButton, (dialog, whichButton) -> CollaboratorActions.deleteCollaborator(context, searchKeyword, userNameMain))
.setPositiveButton(positiveButton, new DialogInterface.OnClickListener() { .setNegativeButton(negativeButton, null).show();
public void onClick(DialogInterface dialog, int whichButton) {
CollaboratorActions.deleteCollaborator(context, searchKeyword, userNameMain); }
}}) public static void addMemberDialog(final Context context, final String userNameMain, String title, String message, String positiveButton, String negativeButton, int teamId) {
new AlertDialog.Builder(context)
.setTitle(title + userNameMain)
.setMessage(message)
.setPositiveButton(positiveButton, (dialog, whichButton) -> TeamActions.addTeamMember(context, userNameMain, teamId))
.setNegativeButton(negativeButton, null).show();
}
public static void removeMemberDialog(final Context context, final String userNameMain, String title, String message, String positiveButton, String negativeButton, int teamId) {
new AlertDialog.Builder(context)
.setTitle(title + userNameMain)
.setMessage(message)
.setPositiveButton(positiveButton, (dialog, whichButton) -> TeamActions.removeTeamMember(context, userNameMain, teamId))
.setNegativeButton(negativeButton, null).show(); .setNegativeButton(negativeButton, null).show();
} }

View File

@ -0,0 +1,77 @@
package org.mian.gitnex.helpers;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
/**
* Author opyale
*/
public class DeprecationDialog extends AlertDialog.Builder {
private Context context;
private String title;
private String message;
public DeprecationDialog(@NonNull Context context) {
super(context);
this.context = context;
setup();
}
public DeprecationDialog(@NonNull Context context, int themeResId) {
super(context, themeResId);
this.context = context;
setup();
}
@NonNull
@SuppressLint("InflateParams")
@Override
public AlertDialog create() {
setCancelable(false);
setPositiveButton(context.getResources().getString(R.string.okButton), (dialog, which) -> dialog.dismiss());
View view = LayoutInflater.from(context).inflate(R.layout.layout_deprecation_dialog, null);
TextView customTitle = view.findViewById(R.id.customTitle);
TextView customMessage = view.findViewById(R.id.customMessage);
customTitle.setText(title);
customMessage.setText(message);
setView(view);
return super.create();
}
private void setup() {
this.message = "";
this.title = context.getResources().getString(R.string.featureDeprecated);
}
public void setMessage(String message) {
this.message = message;
}
public void setTitle(String title) {
this.title = title;
}
}

View File

@ -0,0 +1,64 @@
package org.mian.gitnex.helpers;
import android.content.Context;
import android.util.AttributeSet;
/**
* Author opyale
*/
public class DiffTextView extends androidx.appcompat.widget.AppCompatTextView {
private int initialBackgroundColor;
private int currentBackgroundColor;
private long position;
public DiffTextView(Context context) {
super(context);
}
public DiffTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DiffTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setBackgroundColor(int color) {
currentBackgroundColor = color;
super.setBackgroundColor(color);
}
public void setInitialBackgroundColor(int initialBackgroundColor) {
setBackgroundColor(initialBackgroundColor);
this.initialBackgroundColor = initialBackgroundColor;
}
public int getInitialBackgroundColor() {
return initialBackgroundColor;
}
public int getCurrentBackgroundColor() {
return currentBackgroundColor;
}
public long getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
}

View File

@ -0,0 +1,84 @@
package org.mian.gitnex.helpers;
import java.io.File;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
* Author M M Arif
*/
public class FilesData {
public static int returnOnlyNumber(String fileSize) {
return Integer.parseInt(fileSize.substring(0, fileSize.indexOf(" ")));
}
public static long getFileSizeRecursively(Set<File> alreadySeen, File dirDirectory) {
long fileSize = 0;
for (File filItem : Objects.requireNonNull(dirDirectory.listFiles())) {
if (filItem.isDirectory()) {
fileSize += getFileSize(filItem);
}
else {
alreadySeen.add(new File(filItem.getName()));
fileSize += filItem.length();
}
}
return fileSize;
}
private static long getFileSize(File subDirectory) {
long fileSize = 0;
Deque<File> unprocessedDirs = new ArrayDeque<>();
unprocessedDirs.add(subDirectory);
Set<File> alreadySeen = new HashSet<>();
while (!unprocessedDirs.isEmpty()) {
File dir = unprocessedDirs.removeFirst();
for (File filItem : Objects.requireNonNull(dir.listFiles())) {
if (filItem.isDirectory()) {
unprocessedDirs.addFirst(filItem);
}
else {
if (! alreadySeen.contains(filItem.getName())) {
alreadySeen.add(new File(filItem.getName()));
fileSize += filItem.length();
}
}
}
}
return fileSize;
}
}

View File

@ -1,9 +1,11 @@
package org.mian.gitnex.helpers; package org.mian.gitnex.helpers;
import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.util.Log; import android.util.Log;
import com.squareup.picasso.Cache; import com.squareup.picasso.Cache;
import org.mian.gitnex.util.TinyDB;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -20,21 +22,26 @@ import java.util.UUID;
public class PicassoCache implements Cache { public class PicassoCache implements Cache {
private Context ctx;
private String TAG = "PicassoCache"; private String TAG = "PicassoCache";
private static final Bitmap.CompressFormat COMPRESS_FORMAT = Bitmap.CompressFormat.PNG; private static final Bitmap.CompressFormat COMPRESS_FORMAT = Bitmap.CompressFormat.PNG;
private static final int COMPRESSION_QUALITY = 0; // 0 = high compression (low file size) | 100 = no compression private static final int COMPRESSION_QUALITY = 50; // 0 = high compression (low file size) | 100 = no compression
private final int CACHE_SIZE;
private static final String CACHE_MAP_FILE = "cacheMap"; private static final String CACHE_MAP_FILE = "cacheMap";
private static final int CACHE_SIZE = 25 * 1024 * 1024; // Cache can hold twenty-five megabytes
private File cachePath; private File cachePath;
private HashMap<String, String> cacheMap; private HashMap<String, String> cacheMap;
public PicassoCache(File cachePath) throws IOException, ClassNotFoundException { public PicassoCache(File cachePath, Context ctx) throws IOException, ClassNotFoundException {
TinyDB tinyDb = new TinyDB(ctx);
CACHE_SIZE = FilesData.returnOnlyNumber(tinyDb.getString("cacheSizeImagesStr")) * 1024 * 1024;
this.cachePath = cachePath; this.cachePath = cachePath;
cacheMap = new HashMap<>(); cacheMap = new HashMap<>();
this.ctx = ctx;
if(cacheMapExists(cachePath)) { if(cacheMapExists(cachePath)) {

View File

@ -6,13 +6,24 @@ package org.mian.gitnex.helpers;
public interface StaticGlobalVariables { public interface StaticGlobalVariables {
// issues variables // generic values
String tagIssuesListOpen = "IssuesListOpenFragment - ";
String tagIssuesListClosed = "IssuesListClosedFragment - ";
int issuesPageInit = 1;
int resultLimitNewGiteaInstances = 25; // Gitea 1.12 and above int resultLimitNewGiteaInstances = 25; // Gitea 1.12 and above
int resultLimitOldGiteaInstances = 10; // Gitea 1.11 and below int resultLimitOldGiteaInstances = 10; // Gitea 1.11 and below
// tags
String tagMilestonesFragment = "MilestonesFragment";
String tagPullRequestsList = "PullRequestsListFragment";
String tagIssuesList = "IssuesListFragment";
String tagMilestonesAdapter = "MilestonesAdapter";
// issues variables
int issuesPageInit = 1;
String issuesRequestType = "issues"; String issuesRequestType = "issues";
String issueStateClosed = "closed";
// pull request
int prPageInit = 1;
// milestone
int milestonesPageInit = 1;
} }

View File

@ -0,0 +1,228 @@
package org.mian.gitnex.helpers;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Author 6543
*/
public class Version {
// the raw String
private String raw;
// the version numbers in its order (dot separated)
private List<Integer> values;
public Version(String value) {
raw = value;
this.init();
}
/**
* init parse and store values for other functions of an Version instance
* it use the raw variable as base
*
* @return if parse was successfully
*/
private void init() {
final Pattern pattern_valid = Pattern.compile("^[v,V]?(\\d+)+(\\.(\\d+))*([_,\\-,+][\\w,\\d,_,\\-,+]*)?$");
final Pattern pattern_number_dot_number = Pattern.compile("^\\d+(\\.(\\d)+)*");
if(!pattern_valid.matcher(raw).find()) {
throw new IllegalArgumentException("Invalid version format");
}
if(raw.charAt(0) == 'v' || raw.charAt(0) == 'V') {
raw = raw.substring(1);
}
values = new ArrayList<Integer>();
Matcher match = pattern_number_dot_number.matcher(raw);
match.find();
for(String i : match.group().split("\\.")) {
values.add(Integer.parseInt(i));
}
}
/**
* equal return true if version is the same
*
* @param value
* @return true/false
*/
public boolean equal(String value) {
return this.equal(new Version(value));
}
/**
* equal return true if version is the same
*
* @param v
* @return
*/
public boolean equal(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(this.values.get(i) != v.values.get(i)) {
return false;
}
}
return true;
}
/**
* less return true if version is less
*
* @param value
* @return true/false
*/
public boolean less(String value) {
return this.less(new Version(value));
}
/**
* less return true if version is less
*
* @param v
* @return
*/
public boolean less(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(i + 1 == rounds) {
if(this.values.get(i) >= v.values.get(i)) {
return false;
}
}
else {
if(this.values.get(i) > v.values.get(i)) {
return false;
}
else if(this.values.get(i) < v.values.get(i)) {
return true;
}
}
}
return true;
}
/**
* higher return true if version is higher
*
* @param value
* @return true/false
*/
public boolean higher(String value) {
return this.higher(new Version(value));
}
/**
* higher return true if version is higher
*
* @param v
* @return
*/
public boolean higher(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(i + 1 == rounds) {
if(this.values.get(i) <= v.values.get(i)) {
return false;
}
}
else {
if(this.values.get(i) < v.values.get(i)) {
return false;
}
else if(this.values.get(i) > v.values.get(i)) {
return true;
}
}
}
return true;
}
/**
* lessOrEqual return true if version is less or equal
*
* @param value
* @return true/false
*/
public boolean lessOrEqual(String value) {
return this.lessOrEqual(new Version(value));
}
/**
* lessOrEqual return true if version is less or equal
*
* @param v
* @return
*/
public boolean lessOrEqual(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(this.values.get(i) > v.values.get(i)) {
return false;
}
}
return true;
}
/**
* higherOrEqual return true if version is higher or equal
*
* @param value
* @return true/false
*/
public boolean higherOrEqual(String value) {
return this.higherOrEqual(new Version(value));
}
/**
* higherOrEqual return true if version is higher or equal
*
* @param v
* @return
*/
public boolean higherOrEqual(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(this.values.get(i) < v.values.get(i)) {
return false;
}
}
return true;
}
}

View File

@ -1,151 +0,0 @@
package org.mian.gitnex.helpers;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Author 6543
*/
public enum VersionCheck {
UNKNOWN,
SUPPORTED_LATEST,
SUPPORTED_OLD,
DEVELOPMENT,
UNSUPPORTED_OLD,
UNSUPPORTED_NEW;
public static VersionCheck check(String min, String last, String value) {
final Pattern pattern_stable_release = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)$");
final Pattern pattern_dev_release = Pattern.compile("^(\\d).(\\d+).(\\d+)(\\D)(.+)");
Matcher match;
if (!pattern_stable_release.matcher(min).find() || !pattern_stable_release.matcher(last).find()) {
throw new IllegalArgumentException("VersionCheck: wrong format for min or last version given");
}
match = pattern_stable_release.matcher(value);
if (match.find()) {
switch (correlate(min, last, match.group())){
case 0:
return UNSUPPORTED_OLD;
case 1:
return SUPPORTED_OLD;
case 2:
return SUPPORTED_LATEST;
default:
return UNSUPPORTED_NEW;
}
}
match = pattern_dev_release.matcher(value);
if (match.find()) {
match = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)").matcher(value);
match.find();
if (correlate(min, last, match.group())>0) {
return DEVELOPMENT;
}
else {
return UNSUPPORTED_OLD;
}
}
return UNKNOWN;
}
//helper
// 0 to less
// 1 in range
// 2 at the top
// 3 above
private static int correlate(String min, String last, String value){
int min_check = compareVersion(value,min);
int max_check = compareVersion(value,last);
int range_check = compareVersion(min,last);
switch (range_check) {
case 2:
throw new IllegalArgumentException("Minimum Version higher than Last Version");
case 1: //min == last
switch (min_check) {
case 0:
return 0;
case 1:
return 2;
default:
return 3;
}
default:
if (max_check >1) return 3;
if (max_check == 1) return 2;
if (min_check < 1) return 0;
return 1;
}
}
/**
* @description compare doted formatted Versions
* @param A doted formatted Versions
* @param B doted formatted Versions
* @return 0|1|2
* 0 = less
* 1 = same
* 2 = more
*/
public static int compareVersion(String A, String B) {
final Pattern pattern_stable_release = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)");
final Pattern pattern_dev_release = Pattern.compile("^(\\d).(\\d+).(\\d+)(\\D)(.+)");
Matcher match;
match = pattern_dev_release.matcher(A);
if (match.find()) {
match = pattern_stable_release.matcher(A);
match.find();
A = match.group();
}
match = pattern_dev_release.matcher(B);
if (match.find()) {
match = pattern_stable_release.matcher(B);
match.find();
B = match.group();
}
//throw new IllegalArgumentException
if((!A.matches("[0-9]+(\\.[0-9]+)*")) || (!B.matches("[0-9]+(\\.[0-9]+)*"))) throw new IllegalArgumentException("Invalid version format");
if (A.contains(".") || B.contains(".")) {
// example 2 vs 1.3
if (!(A.contains(".") && B.contains("."))) {
if (A.contains(".")) {
return compareVersion(A,B + ".0");
}
if (B.contains(".")) {
return compareVersion(A + ".0",B);
}
}
//normal compare
int a = Integer.parseInt(A.substring(0,A.indexOf(".")));
int b = Integer.parseInt(B.substring(0,B.indexOf(".")));
if (a < b) return 0;
if (a == b) return compareVersion(A.substring(A.indexOf(".")+1),B.substring(B.indexOf(".")+1));
return 2; //if (a > b)
}
else {
int a = Integer.parseInt(A);
int b = Integer.parseInt(B);
if (a < b) return 0;
if (a == b) return 1;
return 2; //if (a > b)
}
}
}

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