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
210 changed files with 11184 additions and 7656 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 251 versionCode 295
versionName "2.5.1" 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;
@ -38,10 +36,7 @@ public class IssueActions {
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>() {
@ -53,16 +48,13 @@ public class IssueActions {
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) {
@ -85,6 +77,7 @@ public class IssueActions {
@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());
} }
}); });
@ -105,10 +98,7 @@ public class IssueActions {
UpdateIssueState issueStatJson = new UpdateIssueState(issueState); UpdateIssueState issueStatJson = new UpdateIssueState(issueState);
Call<JsonElement> call; Call<JsonElement> call;
call = RetrofitClient call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().closeReopenIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson);
.getInstance(instanceUrl, ctx)
.getApiInterface()
.closeReopenIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson);
call.enqueue(new Callback<JsonElement>() { call.enqueue(new Callback<JsonElement>() {
@ -138,10 +128,7 @@ public class IssueActions {
} }
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) {
@ -164,32 +151,29 @@ public class IssueActions {
@Override @Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
} }
public static void subscribe(final Context ctx, final TextView subscribeIssue, final TextView unsubscribeIssue) { public static void subscribe(final Context ctx) {
final TinyDB tinyDB = new TinyDB(ctx); final TinyDB tinyDB = new TinyDB(ctx);
final String instanceUrl = tinyDB.getString("instanceUrl"); final String instanceUrl = tinyDB.getString("instanceUrl");
String repoFullName = tinyDB.getString("repoFullName"); String[] repoFullName = tinyDB.getString("repoFullName").split("/");
String[] parts = repoFullName.split("/"); if(repoFullName.length != 2) {
final String repoOwner = parts[0]; return;
final String repoName = parts[1]; }
final String loginUid = tinyDB.getString("loginUid");
final String userLogin = tinyDB.getString("userLogin"); final String userLogin = tinyDB.getString("userLogin");
final String token = "token " + tinyDB.getString(loginUid + "-token"); final String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber")); final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
Call<Void> call; Call<Void> call;
call = RetrofitClient call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().addIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin);
.getInstance(instanceUrl, ctx)
.getApiInterface()
.addIssueSubscriber(token, repoOwner, repoName, issueNr, userLogin);
call.enqueue(new Callback<Void>() { call.enqueue(new Callback<Void>() {
@ -200,25 +184,26 @@ public class IssueActions {
if(response.code() == 201) { if(response.code() == 201) {
unsubscribeIssue.setVisibility(View.VISIBLE); Toasty.info(ctx, ctx.getString(R.string.subscribedSuccessfully));
subscribeIssue.setVisibility(View.GONE); tinyDB.putBoolean("issueSubscribed", true);
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtion));
tinyDB.putString("issueSubscriptionState", "unsubscribeToIssue"); }
else if(response.code() == 200) {
tinyDB.putBoolean("issueSubscribed", true);
Toasty.info(ctx, ctx.getString(R.string.alreadySubscribed));
} }
} }
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 { else {
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtionError)); Toasty.info(ctx, ctx.getString(R.string.subscribtionError));
} }
@ -226,32 +211,29 @@ public class IssueActions {
@Override @Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) { 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.unsubscribedSuccessfully));
} }
}); });
} }
public static void unsubscribe(final Context ctx, final TextView subscribeIssue, final TextView unsubscribeIssue) { public static void unsubscribe(final Context ctx) {
final TinyDB tinyDB = new TinyDB(ctx); final TinyDB tinyDB = new TinyDB(ctx);
final String instanceUrl = tinyDB.getString("instanceUrl"); final String instanceUrl = tinyDB.getString("instanceUrl");
String repoFullName = tinyDB.getString("repoFullName"); String[] repoFullName = tinyDB.getString("repoFullName").split("/");
String[] parts = repoFullName.split("/"); if(repoFullName.length != 2) {
final String repoOwner = parts[0]; return;
final String repoName = parts[1]; }
final String loginUid = tinyDB.getString("loginUid");
final String userLogin = tinyDB.getString("userLogin"); final String userLogin = tinyDB.getString("userLogin");
final String token = "token " + tinyDB.getString(loginUid + "-token"); final String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber")); final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
Call<Void> call; Call<Void> call;
call = RetrofitClient call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().delIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin);
.getInstance(instanceUrl, ctx)
.getApiInterface()
.delIssueSubscriber(token, repoOwner, repoName, issueNr, userLogin);
call.enqueue(new Callback<Void>() { call.enqueue(new Callback<Void>() {
@ -262,25 +244,26 @@ public class IssueActions {
if(response.code() == 201) { if(response.code() == 201) {
unsubscribeIssue.setVisibility(View.GONE); Toasty.info(ctx, ctx.getString(R.string.unsubscribedSuccessfully));
subscribeIssue.setVisibility(View.VISIBLE); tinyDB.putBoolean("issueSubscribed", false);
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtion));
tinyDB.putString("issueSubscriptionState", "subscribeToIssue"); }
else if(response.code() == 200) {
tinyDB.putBoolean("issueSubscribed", false);
Toasty.info(ctx, ctx.getString(R.string.alreadyUnsubscribed));
} }
} }
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 { else {
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtionError)); Toasty.info(ctx, ctx.getString(R.string.unsubscribtionError));
} }
@ -288,7 +271,8 @@ public class IssueActions {
@Override @Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtionError));
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(), getApplicationContext(), loginUid); loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), 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

@ -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")) {
case 1:
setTheme(R.style.AppThemeLight); setTheme(R.style.AppThemeLight);
} break;
else if(tinyDb.getInt("themeId") == 2) {
boolean timeSetterFlag = TimeHelper.timeBetweenHours(18, 6); // 6pm to 6am case 2:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
if(timeSetterFlag) {
setTheme(R.style.AppTheme); setTheme(R.style.AppTheme);
} }
else { else {
setTheme(R.style.AppThemeLight); 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,52 +14,49 @@ 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 {
final Context ctx = this;
private Context appCtx;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TextView noData; private TextView noData;
private ProgressBar progressBar; private ProgressBar progressBar;
private SwipeRefreshLayout swipeRefreshLayout; private String TAG = "CommitsActivity";
private String TAG = "CommitsActivity - "; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private int resultLimit = 50; private int pageSize = 1;
private boolean loadNextFlag = false;
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; return R.layout.activity_commits;
} }
@ -66,10 +64,11 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
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);
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,95 +86,72 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
noData = findViewById(R.id.noDataCommits); noData = findViewById(R.id.noDataCommits);
progressBar = findViewById(R.id.progress_bar); progressBar = findViewById(R.id.progress_bar);
swipeRefreshLayout = findViewById(R.id.pullToRefresh); SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setHasFixedSize(true);
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);
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, branchName);
assert savedInstanceState != null;
fastItemAdapter.withSavedInstanceState(savedInstanceState);
} }
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String branchName) { private void loadInitial(String token, String repoOwner, String repoName, String branchName) {
Call<List<Commits>> call = RetrofitClient Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, 1, branchName);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getRepositoryCommits(token, repoOwner, repoName, 1, branchName);
call.enqueue(new Callback<List<Commits>>() { call.enqueue(new Callback<List<Commits>>() {
@Override @Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) { public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
if (response.isSuccessful()) { if(response.isSuccessful()) {
assert response.body() != null; assert response.body() != null;
if(response.body().size() > 0) { if(response.body().size() > 0) {
if(response.body().size() == resultLimit) { commitsList.clear();
loadNextFlag = true; commitsList.addAll(response.body());
} adapter.notifyDataChanged();
noData.setVisibility(View.GONE);
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(),
response.body().get(i).getCommit().getCommitter().getName(), response.body().get(i).getCommit().getCommitter().getDate()));
}
fastItemAdapter.add(items);
} }
else { else {
commitsList.clear();
adapter.notifyDataChanged();
noData.setVisibility(View.VISIBLE); noData.setVisibility(View.VISIBLE);
} }
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
@ -193,57 +169,47 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString()); Log.e(TAG, t.toString());
} }
}); });
} }
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, final int currentPage, String branchName) { private void loadMore(String token, String repoOwner, String repoName, final int page, String branchName) {
footerAdapter.clear(); //add loading progress view
//noinspection unchecked commitsList.add(new Commits("load"));
footerAdapter.add(new ProgressItem().withEnabled(false)); adapter.notifyItemInserted((commitsList.size() - 1));
Handler handler = new Handler();
handler.postDelayed(() -> { Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, page, branchName);
Call<List<Commits>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getRepositoryCommits(token, repoOwner, repoName, currentPage + 1, branchName);
call.enqueue(new Callback<List<Commits>>() { call.enqueue(new Callback<List<Commits>>() {
@Override @Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) { public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
if (response.isSuccessful()) { if(response.isSuccessful()) {
assert response.body() != null; //remove loading view
commitsList.remove(commitsList.size() - 1);
if (response.body().size() > 0) { List<Commits> result = response.body();
loadNextFlag = response.body().size() == resultLimit; assert result != null;
if(result.size() > 0) {
for (int i = 0; i < response.body().size(); i++) { pageSize = result.size();
commitsList.addAll(result);
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(),
response.body().get(i).getHtml_url(), response.body().get(i).getCommit().getCommitter().getName(),
response.body().get(i).getCommit().getCommitter().getDate()));
}
footerAdapter.clear();
} }
else { else {
footerAdapter.clear(); Toasty.info(ctx, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
} }
progressBar.setVisibility(View.GONE); adapter.notifyDataChanged();
} }
else { else {
@ -263,14 +229,6 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
}); });
}, 1000);
if(!loadNextFlag) {
footerAdapter.clear();
}
} }
@Override @Override
@ -287,33 +245,38 @@ public class CommitsActivity extends BaseActivity implements ItemFilterListener<
@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) {
fastItemAdapter.filter(newText);
filter(newText);
return true; return true;
} }
}); });
endlessRecyclerOnScrollListener.enable();
return super.onCreateOptionsMenu(menu); return super.onCreateOptionsMenu(menu);
} }
@Override private void filter(String text) {
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<CommitsAdapter> results) {
endlessRecyclerOnScrollListener.disable(); List<Commits> arr = new ArrayList<>();
for(Commits d : commitsList) {
if(d.getCommit().getMessage().toLowerCase().contains(text) || d.getSha().toLowerCase().contains(text)) {
arr.add(d);
}
} }
@Override adapter.updateList(arr);
public void onReset() {
endlessRecyclerOnScrollListener.enable();
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> { onClickListener = view -> {
getIntent().removeExtra("branchName"); getIntent().removeExtra("branchName");
finish(); 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>>() {
@ -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>>() {
@ -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);

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);

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;
@ -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,20 +1,17 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint;
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;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
@ -24,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;
@ -59,17 +55,16 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TextView singleFileContents; private TextView singleFileContents;
private LinearLayout singleFileContentsFrame; private LinearLayout singleFileContentsFrame;
private LinearLayout highlightJs; 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() {
@ -81,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];
@ -95,8 +92,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
singleFileContents = findViewById(R.id.singleFileContents); singleFileContents = findViewById(R.id.singleFileContents);
highlightJs = findViewById(R.id.highlightJs); singleCodeContents = findViewById(R.id.singleCodeContents);
//singleCodeContents = findViewById(R.id.singleCodeContents);
imageView = findViewById(R.id.imageView); imageView = findViewById(R.id.imageView);
mProgressBar = findViewById(R.id.progress_bar); mProgressBar = findViewById(R.id.progress_bar);
pdfView = findViewById(R.id.pdfView); pdfView = findViewById(R.id.pdfView);
@ -135,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>() {
@ -161,8 +157,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if(appUtil.imageExtension(fileExtension)) { // file is image if(appUtil.imageExtension(fileExtension)) { // file is image
singleFileContentsFrame.setVisibility(View.GONE); singleFileContentsFrame.setVisibility(View.GONE);
highlightJs.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
//singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE); imageView.setVisibility(View.VISIBLE);
@ -173,19 +168,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
else if(appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode else if(appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode
pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
if(Build.VERSION.SDK_INT > 23) {
highlightJs.setVisibility(View.VISIBLE);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
assert inflater != null;
@SuppressLint("InflateParams") View mView = inflater.inflate(R.layout.custom_highlightjs, null);
HighlightJsView singleCodeContents = mView.findViewById(R.id.singleCodeContents);
highlightJs.addView(mView);
singleFileContentsFrame.setVisibility(View.GONE); singleFileContentsFrame.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.VISIBLE); singleCodeContents.setVisibility(View.VISIBLE);
switch(tinyDb.getInt("fileviewerSourceCodeThemeId")) { switch(tinyDb.getInt("fileviewerSourceCodeThemeId")) {
@ -208,24 +193,14 @@ 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()));
}
else {
singleFileContents.setVisibility(View.VISIBLE);
singleFileContents.setText(appUtil.decodeBase64(response.body().getContent()));
}
} }
else if(appUtil.pdfExtension(fileExtension)) { // file is pdf else if(appUtil.pdfExtension(fileExtension)) { // file is pdf
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE); singleFileContentsFrame.setVisibility(View.GONE);
highlightJs.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
//singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.VISIBLE); pdfViewFrame.setVisibility(View.VISIBLE);
pdfNightMode = tinyDb.getBoolean("enablePdfMode"); pdfNightMode = tinyDb.getBoolean("enablePdfMode");
@ -237,8 +212,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
else if(appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded else if(appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
highlightJs.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
//singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE); singleFileContentsFrame.setVisibility(View.VISIBLE);
@ -250,8 +224,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
else { // file type not known - plain text view else { // file type not known - plain text view
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
highlightJs.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
//singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE); singleFileContentsFrame.setVisibility(View.VISIBLE);
@ -283,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));
} }
@ -328,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) {
if(checkPermission()) {
requestFileDownload(); requestFileDownload();
}
else {
requestPermission();
}
}
else {
requestFileDownload();
}
break;
} }
@ -350,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
public void onClick(View view) {
getIntent().removeExtra("singleFileName"); getIntent().removeExtra("singleFileName");
finish(); finish();
}
}; };
} }

View File

@ -1,32 +1,5 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
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 io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
@ -47,9 +20,19 @@ import android.view.View;
import android.widget.HorizontalScrollView; import android.widget.HorizontalScrollView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
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 com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
@ -59,15 +42,17 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment; import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment;
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.ClickListener;
import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.LabelWidthCalculator; import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.models.IssueComments;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.helpers.ColorInverter; import org.mian.gitnex.models.WatchInfo;
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.mian.gitnex.viewmodels.IssueCommentsViewModel; import org.mian.gitnex.viewmodels.IssueCommentsViewModel;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -76,6 +61,24 @@ 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 io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -98,11 +101,15 @@ public class IssueDetailActivity extends BaseActivity {
private TextView issueModified; private TextView issueModified;
private ImageView createNewComment; private ImageView createNewComment;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private LinearLayout labelsLayout; private LinearLayout labelsLayout;
private LinearLayout assigneesLayout; private LinearLayout assigneesLayout;
private View divider;
private ProgressBar progressBar;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId() {
return R.layout.activity_issue_detail; return R.layout.activity_issue_detail;
} }
@ -110,8 +117,9 @@ public class IssueDetailActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
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");
@ -137,6 +145,8 @@ public class IssueDetailActivity extends BaseActivity {
createNewComment = findViewById(R.id.addNewComment); createNewComment = findViewById(R.id.addNewComment);
labelsLayout = findViewById(R.id.frameLabels); labelsLayout = findViewById(R.id.frameLabels);
assigneesLayout = findViewById(R.id.frameAssignees); assigneesLayout = findViewById(R.id.frameAssignees);
divider = findViewById(R.id.divider);
progressBar = findViewById(R.id.progressBar);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
@ -148,7 +158,7 @@ public class IssueDetailActivity extends BaseActivity {
mRecyclerView = findViewById(R.id.recyclerView); mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setNestedScrollingEnabled(false); mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
@ -159,18 +169,18 @@ public class IssueDetailActivity extends BaseActivity {
scrollViewComments.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { scrollViewComments.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if ((scrollY - oldScrollY) > 0 && createNewComment.isShown()) { if((scrollY - oldScrollY) > 0 && createNewComment.isShown()) {
createNewComment.setVisibility(View.GONE); createNewComment.setVisibility(View.GONE);
} }
else if ((scrollY - oldScrollY) < 0) { else if((scrollY - oldScrollY) < 0) {
createNewComment.setVisibility(View.VISIBLE); createNewComment.setVisibility(View.VISIBLE);
} }
if (!scrollViewComments.canScrollVertically(1)) { // bottom if(!scrollViewComments.canScrollVertically(1)) { // bottom
createNewComment.setVisibility(View.GONE); createNewComment.setVisibility(View.GONE);
} }
if (!scrollViewComments.canScrollVertically(-1)) { // top if(!scrollViewComments.canScrollVertically(-1)) { // top
createNewComment.setVisibility(View.VISIBLE); createNewComment.setVisibility(View.VISIBLE);
} }
@ -181,7 +191,7 @@ public class IssueDetailActivity extends BaseActivity {
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> { swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setRefreshing(false); swipeRefresh.setRefreshing(false);
IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, getApplicationContext()); IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, ctx);
}, 500)); }, 500));
@ -190,15 +200,15 @@ public class IssueDetailActivity extends BaseActivity {
switch(tinyDb.getInt("customFontId", -1)) { switch(tinyDb.getInt("customFontId", -1)) {
case 1: case 1:
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/manroperegular.ttf"); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(ctx).getAssets(), "fonts/manroperegular.ttf");
break; break;
case 2: case 2:
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/sourcecodeproregular.ttf"); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(ctx).getAssets(), "fonts/sourcecodeproregular.ttf");
break; break;
default: default:
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf"); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(ctx).getAssets(), "fonts/roboto.ttf");
break; break;
} }
@ -213,6 +223,7 @@ public class IssueDetailActivity extends BaseActivity {
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu); inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
return true; return true;
@ -223,7 +234,7 @@ public class IssueDetailActivity extends BaseActivity {
int id = item.getItemId(); int id = item.getItemId();
switch (id) { switch(id) {
case android.R.id.home: case android.R.id.home:
finish(); finish();
return true; return true;
@ -239,8 +250,9 @@ public class IssueDetailActivity extends BaseActivity {
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
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");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -251,57 +263,48 @@ public class IssueDetailActivity extends BaseActivity {
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
if(tinyDb.getBoolean("commentPosted")) { if(tinyDb.getBoolean("commentPosted")) {
scrollViewComments.post(new Runnable() { scrollViewComments.post(() -> {
@Override
public void run() {
IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, getApplicationContext());
new Handler().postDelayed(new Runnable() { IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, ctx);
@Override
public void run() { new Handler().postDelayed(() -> scrollViewComments.fullScroll(ScrollView.FOCUS_DOWN), 1000);
scrollViewComments.fullScroll(ScrollView.FOCUS_DOWN);
}
}, 1000);
tinyDb.putBoolean("commentPosted", false); tinyDb.putBoolean("commentPosted", false);
}
}); });
} }
if(tinyDb.getBoolean("commentEdited")) { if(tinyDb.getBoolean("commentEdited")) {
scrollViewComments.post(new Runnable() { scrollViewComments.post(() -> {
@Override
public void run() { IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, ctx);
IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, getApplicationContext());
tinyDb.putBoolean("commentEdited", false); tinyDb.putBoolean("commentEdited", false);
}
}); });
} }
if(tinyDb.getBoolean("singleIssueUpdate")) { if(tinyDb.getBoolean("singleIssueUpdate")) {
new Handler().postDelayed(new Runnable() { new Handler().postDelayed(() -> {
@Override
public void run() {
assigneesLayout.removeAllViews(); assigneesLayout.removeAllViews();
labelsLayout.removeAllViews(); labelsLayout.removeAllViews();
getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
tinyDb.putBoolean("singleIssueUpdate", false); tinyDb.putBoolean("singleIssueUpdate", false);
}
}, 500); }, 500);
} }
if(tinyDb.getBoolean("issueEdited")) { if(tinyDb.getBoolean("issueEdited")) {
new Handler().postDelayed(new Runnable() { new Handler().postDelayed(() -> {
@Override
public void run() {
assigneesLayout.removeAllViews(); assigneesLayout.removeAllViews();
labelsLayout.removeAllViews(); labelsLayout.removeAllViews();
getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
tinyDb.putBoolean("issueEdited", false); tinyDb.putBoolean("issueEdited", false);
}
}, 500); }, 500);
} }
@ -312,11 +315,19 @@ public class IssueDetailActivity extends BaseActivity {
IssueCommentsViewModel issueCommentsModel = new ViewModelProvider(this).get(IssueCommentsViewModel.class); IssueCommentsViewModel issueCommentsModel = new ViewModelProvider(this).get(IssueCommentsViewModel.class);
issueCommentsModel.getIssueCommentList(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), owner, repo, index, getApplicationContext()).observe(this, new Observer<List<IssueComments>>() { issueCommentsModel.getIssueCommentList(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), owner, repo, index, ctx).observe(this, new Observer<List<IssueComments>>() {
@Override @Override
public void onChanged(@Nullable List<IssueComments> issueCommentsMain) { public void onChanged(@Nullable List<IssueComments> issueCommentsMain) {
adapter = new IssueCommentsAdapter(getApplicationContext(), issueCommentsMain);
assert issueCommentsMain != null;
if(issueCommentsMain.size() > 0) {
divider.setVisibility(View.VISIBLE);
}
adapter = new IssueCommentsAdapter(ctx, issueCommentsMain);
mRecyclerView.setAdapter(adapter); mRecyclerView.setAdapter(adapter);
} }
}); });
@ -324,37 +335,29 @@ public class IssueDetailActivity extends BaseActivity {
private void getSingleIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid) { private void getSingleIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<Issues> call = RetrofitClient Call<Issues> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
call.enqueue(new Callback<Issues>() { call.enqueue(new Callback<Issues>() {
@Override @Override
public void onResponse(@NonNull Call<Issues> call, @NonNull Response<Issues> response) { public void onResponse(@NonNull Call<Issues> call, @NonNull Response<Issues> response) {
if (response.isSuccessful()) { if(response.code() == 200) {
if (response.code() == 200) {
Issues singleIssue = response.body(); Issues singleIssue = response.body();
assert singleIssue != null; assert singleIssue != null;
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getApplicationContext())) final Markwon markwon = Markwon.builder(Objects.requireNonNull(ctx)).usePlugin(CorePlugin.create()).usePlugin(ImagesPlugin.create(plugin -> {
.usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> {
plugin.addSchemeHandler(new SchemeHandler() { plugin.addSchemeHandler(new SchemeHandler() {
@NonNull @NonNull
@Override @Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = getApplicationContext().getResources().getIdentifier( final int resourceId = ctx.getResources().getIdentifier(raw.substring("drawable://".length()), "drawable", ctx.getPackageName());
raw.substring("drawable://".length()),
"drawable",
getApplicationContext().getPackageName());
final Drawable drawable = getApplicationContext().getDrawable(resourceId); final Drawable drawable = ctx.getDrawable(resourceId);
assert drawable != null; assert drawable != null;
return ImageItem.withResult(drawable); return ImageItem.withResult(drawable);
@ -363,65 +366,59 @@ public class IssueDetailActivity extends BaseActivity {
@NonNull @NonNull
@Override @Override
public Collection<String> supportedSchemes() { public Collection<String> supportedSchemes() {
return Collections.singleton("drawable"); return Collections.singleton("drawable");
} }
}); });
plugin.placeholderProvider(drawable -> null); plugin.placeholderProvider(drawable -> null);
plugin.addMediaDecoder(GifMediaDecoder.create(false)); plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(getApplicationContext().getResources())); plugin.addMediaDecoder(SvgMediaDecoder.create(ctx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create()); plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getApplicationContext().getResources())); plugin.defaultMediaDecoder(DefaultMediaDecoder.create(ctx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
})) })).usePlugin(new AbstractMarkwonPlugin() {
.usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) { public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(getApplicationContext()))
.usePlugin(TaskListPlugin.create(getApplicationContext()))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
TinyDB tinyDb = new TinyDB(getApplicationContext()); builder.codeTextColor(tinyDb.getInt("codeBlockColor")).codeBackgroundColor(tinyDb.getInt("codeBlockBackground")).linkColor(getResources().getColor(R.color.lightBlue));
}
}).usePlugin(TablePlugin.create(ctx)).usePlugin(TaskListPlugin.create(ctx)).usePlugin(HtmlPlugin.create()).usePlugin(StrikethroughPlugin.create()).usePlugin(LinkifyPlugin.create()).build();
TinyDB tinyDb = new TinyDB(appCtx);
final String locale = tinyDb.getString("locale"); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
tinyDb.putString("issueState", singleIssue.getState()); tinyDb.putString("issueState", singleIssue.getState());
tinyDb.putString("issueTitle", singleIssue.getTitle()); tinyDb.putString("issueTitle", singleIssue.getTitle());
PicassoService.getInstance(ctx).get().load(singleIssue.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); PicassoService.getInstance(ctx).get().load(singleIssue.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
String issueNumber_ = "<font color='" + getApplicationContext().getResources().getColor(R.color.lightGray) + "'>" + getApplicationContext().getResources().getString(R.string.hash) + singleIssue.getNumber() + "</font>"; String issueNumber_ = "<font color='" + appCtx.getResources().getColor(R.color.lightGray) + "'>" + appCtx.getResources().getString(R.string.hash) + singleIssue.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle())); issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle()));
String cleanIssueDescription = singleIssue.getBody().trim(); String cleanIssueDescription = singleIssue.getBody().trim();
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription)); Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
markwon.setParsedMarkdown(issueDescription, UserMentions.UserMentionsFunc(getApplicationContext(), bodyWithMD, cleanIssueDescription)); markwon.setParsedMarkdown(issueDescription, UserMentions.UserMentionsFunc(ctx, bodyWithMD, cleanIssueDescription));
RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams)issueDescription.getLayoutParams(); RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams) issueDescription.getLayoutParams();
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(80, 80); LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(80, 80);
params1.setMargins(15, 0, 0, 0); params1.setMargins(15, 0, 0, 0);
if(singleIssue.getAssignees() != null) { if(singleIssue.getAssignees() != null) {
assigneesScrollView.setVisibility(View.VISIBLE); assigneesScrollView.setVisibility(View.VISIBLE);
for (int i = 0; i < singleIssue.getAssignees().size(); i++) { for(int i = 0; i < singleIssue.getAssignees().size(); i++) {
ImageView assigneesView = new ImageView(getApplicationContext()); ImageView assigneesView = new ImageView(ctx);
PicassoService.getInstance(ctx).get().load(singleIssue.getAssignees().get(i).getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(100, 100).centerCrop().into(assigneesView); PicassoService.getInstance(ctx).get().load(singleIssue.getAssignees().get(i).getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(100, 100).centerCrop().into(assigneesView);
assigneesLayout.addView(assigneesView); assigneesLayout.addView(assigneesView);
assigneesView.setLayoutParams(params1); assigneesView.setLayoutParams(params1);
if (!singleIssue.getAssignees().get(i).getFull_name().equals("")) { if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) {
assigneesView.setOnClickListener(new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getFull_name()), getApplicationContext())); assigneesView.setOnClickListener(new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getFull_name()), ctx));
} else { }
assigneesView.setOnClickListener(new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getLogin()), getApplicationContext())); else {
assigneesView.setOnClickListener(new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getLogin()), ctx));
} }
} }
@ -436,26 +433,18 @@ public class IssueDetailActivity extends BaseActivity {
if(singleIssue.getLabels() != null) { if(singleIssue.getLabels() != null) {
labelsScrollView.setVisibility(View.VISIBLE); labelsScrollView.setVisibility(View.VISIBLE);
int width = 25; int width = 25;
for (int i = 0; i < singleIssue.getLabels().size(); i++) { for(int i = 0; i < singleIssue.getLabels().size(); i++) {
String labelColor = singleIssue.getLabels().get(i).getColor(); String labelColor = singleIssue.getLabels().get(i).getColor();
String labelName = singleIssue.getLabels().get(i).getName(); String labelName = singleIssue.getLabels().get(i).getName();
int color = Color.parseColor("#" + labelColor); int color = Color.parseColor("#" + labelColor);
ImageView labelsView = new ImageView(getApplicationContext()); ImageView labelsView = new ImageView(ctx);
labelsLayout.setOrientation(LinearLayout.HORIZONTAL); labelsLayout.setOrientation(LinearLayout.HORIZONTAL);
labelsLayout.setGravity(Gravity.START | Gravity.TOP); labelsLayout.setGravity(Gravity.START | Gravity.TOP);
labelsView.setLayoutParams(params); labelsView.setLayoutParams(params);
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).textColor(new ColorInverter().getContrastColor(color)).fontSize(30).width(LabelWidthCalculator.calculateLabelWidth(labelName, Typeface.DEFAULT, 30, 15)).height(50).endConfig().buildRoundRect(labelName, color, 10);
.beginConfig()
.useFont(Typeface.DEFAULT)
.textColor(new ColorInverter().getContrastColor(color))
.fontSize(30)
.width(LabelWidthCalculator.calculateLabelWidth(labelName, Typeface.DEFAULT, 30, 15))
.height(50)
.endConfig()
.buildRoundRect(labelName, color, 10);
labelsView.setImageDrawable(drawable); labelsView.setImageDrawable(drawable);
labelsLayout.addView(labelsView); labelsLayout.addView(labelsView);
@ -468,15 +457,16 @@ public class IssueDetailActivity extends BaseActivity {
if(singleIssue.getDue_date() != null) { if(singleIssue.getDue_date() != null) {
if (timeFormat.equals("normal") || timeFormat.equals("pretty")) { if(timeFormat.equals("normal") || timeFormat.equals("pretty")) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale)); DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
String dueDate = formatter.format(singleIssue.getDue_date()); String dueDate = formatter.format(singleIssue.getDue_date());
issueDueDate.setText(getString(R.string.dueDate, dueDate)); issueDueDate.setText(dueDate);
issueDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getDue_date()), getApplicationContext())); issueDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getDue_date()), ctx));
} else if (timeFormat.equals("normal1")) { }
else if(timeFormat.equals("normal1")) {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale)); DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
String dueDate = formatter.format(singleIssue.getDue_date()); String dueDate = formatter.format(singleIssue.getDue_date());
issueDueDate.setText(getString(R.string.dueDate, dueDate)); issueDueDate.setText(dueDate);
} }
} }
@ -528,21 +518,20 @@ public class IssueDetailActivity extends BaseActivity {
issueMilestone.setVisibility(View.GONE); issueMilestone.setVisibility(View.GONE);
} }
if (!singleIssue.getUser().getFull_name().equals("")) { if(!singleIssue.getUser().getFull_name().equals("")) {
assigneeAvatar.setOnClickListener(new ClickListener(getApplicationContext().getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), getApplicationContext())); assigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), ctx));
} else {
assigneeAvatar.setOnClickListener(new ClickListener(getApplicationContext().getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), getApplicationContext()));
} }
else {
assigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), ctx));
}
progressBar.setVisibility(View.GONE);
} }
}
else if(response.code() == 401) { else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
@ -550,14 +539,46 @@ public class IssueDetailActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
});
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
Call<WatchInfo> call2 = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkIssueWatchStatus(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
call2.enqueue(new Callback<WatchInfo>() {
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull Response<WatchInfo> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("issueSubscribed", response.body().getSubscribed());
}
else {
tinyDb.putBoolean("issueSubscribed", false);
}
}
@Override
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("issueSubscribed", false);
}
}); });
} }
private void initCloseListener() {
View.OnClickListener onClickListener = view -> finish();
} }
} }

View File

@ -25,7 +25,7 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.NetworkObserver; import org.mian.gitnex.helpers.NetworkObserver;
import org.mian.gitnex.helpers.SnackBar; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.VersionCheck; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.models.UserTokens; import org.mian.gitnex.models.UserTokens;
@ -35,7 +35,6 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import okhttp3.Credentials; import okhttp3.Credentials;
import retrofit2.Call; import retrofit2.Call;
@ -53,11 +52,13 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private TextView otpInfo; private TextView otpInfo;
private RadioGroup loginMethod; private RadioGroup loginMethod;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private String device_id = "token"; private String device_id = "token";
private ScrollView layoutView; private ScrollView layoutView;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId() {
return R.layout.activity_login; return R.layout.activity_login;
} }
@ -65,8 +66,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
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);
NetworkObserver networkMonitor = new NetworkObserver(this); NetworkObserver networkMonitor = new NetworkObserver(this);
loginButton = findViewById(R.id.login_button); loginButton = findViewById(R.id.login_button);
@ -82,13 +84,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
loginTokenCode = findViewById(R.id.loginTokenCode); loginTokenCode = findViewById(R.id.loginTokenCode);
layoutView = findViewById(R.id.loginForm); layoutView = findViewById(R.id.loginForm);
viewTextAppVersion.setText(AppUtil.getAppVersion(getApplicationContext())); viewTextAppVersion.setText(AppUtil.getAppVersion(appCtx));
Resources res = getResources(); Resources res = getResources();
String[] allProtocols = res.getStringArray(R.array.protocolValues); String[] allProtocols = res.getStringArray(R.array.protocolValues);
final ArrayAdapter<String> adapterProtocols = new ArrayAdapter<String>(LoginActivity.this, final ArrayAdapter<String> adapterProtocols = new ArrayAdapter<String>(LoginActivity.this, R.layout.spinner_item, allProtocols);
R.layout.spinner_item, allProtocols);
adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item); adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item);
protocolSpinner.setAdapter(adapterProtocols); protocolSpinner.setAdapter(adapterProtocols);
@ -99,12 +100,13 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
String value = getResources().getStringArray(R.array.protocolValues)[pos]; String value = getResources().getStringArray(R.array.protocolValues)[pos];
if(value.toLowerCase().equals("http")) { if(value.toLowerCase().equals("http")) {
SnackBar.warning(getApplicationContext(), layoutView,getResources().getString(R.string.protocolError)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.protocolError));
} }
} }
public void onNothingSelected(AdapterView<?> parent) { public void onNothingSelected(AdapterView<?> parent) {
} }
}); });
@ -161,11 +163,11 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
if(isAvailable) { if(isAvailable) {
enableProcessButton(); enableProcessButton();
SnackBar.success(getApplicationContext(), layoutView, getResources().getString(R.string.netConnectionIsBack)); SnackBar.success(ctx, layoutView, getResources().getString(R.string.netConnectionIsBack));
} }
else { else {
disableProcessButton(); disableProcessButton();
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.checkNetConnection)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.checkNetConnection));
} }
}); });
@ -200,13 +202,14 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (v.getId() == R.id.login_button) { if(v.getId() == R.id.login_button) {
login(); login();
} }
} }
private View.OnClickListener loginListener = new View.OnClickListener() { private View.OnClickListener loginListener = new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
disableProcessButton(); disableProcessButton();
@ -216,21 +219,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
}; };
private View.OnClickListener infoListener = v -> new Tooltip.Builder(v) private View.OnClickListener infoListener = v -> new Tooltip.Builder(v).setText(R.string.urlInfoTooltip).setTextColor(getResources().getColor(R.color.white)).setBackgroundColor(getResources().getColor(R.color.tooltipBackground)).setCancelable(true).setDismissOnClick(true).setPadding(30).setCornerRadius(R.dimen.tooltipCornor).setGravity(Gravity.BOTTOM).show();
.setText(R.string.urlInfoTooltip)
.setTextColor(getResources().getColor(R.color.white))
.setBackgroundColor(getResources().getColor(R.color.tooltipBackground))
.setCancelable(true)
.setDismissOnClick(true)
.setPadding(30)
.setCornerRadius(R.dimen.tooltipCornor)
.setGravity(Gravity.BOTTOM)
.show();
@SuppressLint("ResourceAsColor") @SuppressLint("ResourceAsColor")
private void login() { private void login() {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
boolean connToInternet = AppUtil.haveNetworkConnection(LoginActivity.this); boolean connToInternet = AppUtil.haveNetworkConnection(LoginActivity.this);
@ -264,7 +258,8 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
URI uri = null; URI uri = null;
try { try {
uri = new URI(instanceUrl); uri = new URI(instanceUrl);
} catch (URISyntaxException e) { }
catch(URISyntaxException e) {
e.printStackTrace(); e.printStackTrace();
} }
assert uri != null; assert uri != null;
@ -294,7 +289,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
if(instanceUrlET.getText().toString().equals("")) { if(instanceUrlET.getText().toString().equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.emptyFieldURL)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.emptyFieldURL));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -302,7 +297,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
if(loginUid.equals("")) { if(loginUid.equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.emptyFieldUsername)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.emptyFieldUsername));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -310,7 +305,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
if(loginPassword.getText().toString().equals("")) { if(loginPassword.getText().toString().equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.emptyFieldPassword)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.emptyFieldPassword));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -326,7 +321,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.loginOTPTypeError)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.loginOTPTypeError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -340,7 +335,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.checkNetConnection)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.checkNetConnection));
} }
@ -355,7 +350,8 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
URI uri = null; URI uri = null;
try { try {
uri = new URI(instanceUrl); uri = new URI(instanceUrl);
} catch (URISyntaxException e) { }
catch(URISyntaxException e) {
e.printStackTrace(); e.printStackTrace();
} }
assert uri != null; assert uri != null;
@ -382,17 +378,17 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
if(connToInternet) { if(connToInternet) {
if (instanceUrlET.getText().toString().equals("")) { if(instanceUrlET.getText().toString().equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.emptyFieldURL)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.emptyFieldURL));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
} }
if (loginToken_.equals("")) { if(loginToken_.equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.loginTokenError)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.loginTokenError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -403,7 +399,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.checkNetConnection)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.checkNetConnection));
} }
@ -414,25 +410,16 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private void versionCheck(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP, final String loginToken_, final int loginType) { private void versionCheck(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP, final String loginToken_, final int loginType) {
Call<GiteaVersion> callVersion; Call<GiteaVersion> callVersion;
if (!loginToken_.isEmpty()) { if(!loginToken_.isEmpty()) {
callVersion = RetrofitClient callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken(loginToken_);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getGiteaVersionWithToken(loginToken_);
} }
else { else {
final String credential = Credentials.basic(loginUid, loginPass, StandardCharsets.UTF_8); final String credential = Credentials.basic(loginUid, loginPass, StandardCharsets.UTF_8);
if (loginOTP != 0) { if(loginOTP != 0) {
callVersion = RetrofitClient callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithOTP(credential, loginOTP);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getGiteaVersionWithOTP(credential,loginOTP);
} }
else { else {
callVersion = RetrofitClient callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithBasic(credential);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getGiteaVersionWithBasic(credential);
} }
} }
@ -441,37 +428,33 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
@Override @Override
public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) { public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) {
if (responseVersion.code() == 200) { if(responseVersion.code() == 200) {
GiteaVersion version = responseVersion.body(); GiteaVersion version = responseVersion.body();
assert version != null; assert version != null;
VersionCheck vt = VersionCheck.check(getString(R.string.versionLow), getString(R.string.versionHigh), version.getVersion()); // init
Version gitea_version = new Version(getString(R.string.versionLow));
try {
gitea_version = new Version(version.getVersion());
}
catch(Error e) {
SnackBar.error(ctx, layoutView, getResources().getString(R.string.versionUnknow));
enableProcessButton();
}
//(getString(R.string.versionLow), getString(), version.getVersion());
switch (vt) { // UNSUPPORTED_OLD
case UNSUPPORTED_NEW: if(gitea_version.less(getString(R.string.versionLow))) {
//SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.versionUnsupportedNew));
case SUPPORTED_LATEST:
case SUPPORTED_OLD:
case DEVELOPMENT:
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
return;
case UNSUPPORTED_OLD:
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx);
alertDialogBuilder alertDialogBuilder.setTitle(getString(R.string.versionAlertDialogHeader)).setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setCancelable(true).setIcon(R.drawable.ic_warning).setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
.setTitle(getString(R.string.versionAlertDialogHeader))
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion()))
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
dialog.dismiss(); dialog.dismiss();
enableProcessButton(); enableProcessButton();
}) }).setPositiveButton(getString(R.string.textContinue), (dialog, which) -> {
.setPositiveButton(getString(R.string.textContinue), (dialog, which) -> {
dialog.dismiss(); dialog.dismiss();
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_); login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
@ -482,14 +465,22 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
alertDialog.show(); alertDialog.show();
return; return;
default: // UNKNOWN
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.versionUnknow));
enableProcessButton();
} }
// SUPPORTED
else if(gitea_version.lessOrEqual(getString(R.string.versionHigh))) {
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
return;
}
// UNSUPPORTED_NEW
else {
SnackBar.info(ctx, layoutView, getResources().getString(R.string.versionUnsupportedNew));
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
return;
}
} }
else if (responseVersion.code() == 403) { else if(responseVersion.code() == 403) {
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_); login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
@ -498,10 +489,10 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private void login(int loginType, String instanceUrl, String loginUid, String loginPass, int loginOTP, String loginToken_) { private void login(int loginType, String instanceUrl, String loginUid, String loginPass, int loginOTP, String loginToken_) {
if (loginType == 1) { if(loginType == 1) {
letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP); letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP);
} }
else if (loginType == 2) { // token else if(loginType == 2) { // token
letTheUserInViaToken(instanceUrl, loginToken_); letTheUserInViaToken(instanceUrl, loginToken_);
} }
@ -511,7 +502,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
public void onFailure(@NonNull Call<GiteaVersion> callVersion, Throwable t) { public void onFailure(@NonNull Call<GiteaVersion> callVersion, Throwable t) {
Log.e("onFailure-version", t.toString()); Log.e("onFailure-version", t.toString());
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.errorOnLogin)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.errorOnLogin));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -523,12 +514,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private void letTheUserInViaToken(String instanceUrl, final String loginToken_) { private void letTheUserInViaToken(String instanceUrl, final String loginToken_) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<UserInfo> call = RetrofitClient Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo("token " + loginToken_);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserInfo("token " + loginToken_);
call.enqueue(new Callback<UserInfo>() { call.enqueue(new Callback<UserInfo>() {
@ -537,9 +525,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
UserInfo userDetails = response.body(); UserInfo userDetails = response.body();
if (response.isSuccessful()) { if(response.isSuccessful()) {
if (response.code() == 200) { if(response.code() == 200) {
tinyDb.putBoolean("loggedInMode", true); tinyDb.putBoolean("loggedInMode", true);
assert userDetails != null; assert userDetails != null;
@ -557,14 +545,14 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else if(response.code() == 401) { else if(response.code() == 401) {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.unauthorizedApiError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.unauthorizedApiError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -576,7 +564,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -592,18 +580,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
Call<List<UserTokens>> call; Call<List<UserTokens>> call;
if(loginOTP != 0) { if(loginOTP != 0) {
call = RetrofitClient call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserTokensWithOTP(credential, loginOTP, loginUid);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserTokensWithOTP(credential, loginOTP, loginUid);
} }
else { else {
call = RetrofitClient call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserTokens(credential, loginUid);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserTokens(credential, loginUid);
} }
@ -613,23 +595,23 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
public void onResponse(@NonNull Call<List<UserTokens>> call, @NonNull retrofit2.Response<List<UserTokens>> response) { public void onResponse(@NonNull Call<List<UserTokens>> call, @NonNull retrofit2.Response<List<UserTokens>> response) {
List<UserTokens> userTokens = response.body(); List<UserTokens> userTokens = response.body();
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final AppUtil appUtil = new AppUtil(); final AppUtil appUtil = new AppUtil();
//Headers responseHeaders = response.headers(); //Headers responseHeaders = response.headers();
if (response.isSuccessful()) { if(response.isSuccessful()) {
if (response.code() == 200) { if(response.code() == 200) {
boolean setTokenFlag = false; boolean setTokenFlag = false;
assert userTokens != null; assert userTokens != null;
if (userTokens.size() > 0) { if(userTokens.size() > 0) {
if(userTokens.get(0).getToken_last_eight() != null) { if(userTokens.get(0).getToken_last_eight() != null) {
for (int i = 0; i < userTokens.size(); i++) { for(int i = 0; i < userTokens.size(); i++) {
if (userTokens.get(i).getToken_last_eight().equals(tinyDb.getString(loginUid + "-token-last-eight"))) { if(userTokens.get(i).getToken_last_eight().equals(tinyDb.getString(loginUid + "-token-last-eight"))) {
setTokenFlag = true; setTokenFlag = true;
break; break;
} }
@ -639,8 +621,8 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
for (int i = 0; i < userTokens.size(); i++) { for(int i = 0; i < userTokens.size(); i++) {
if (userTokens.get(i).getSha1().equals(tinyDb.getString(loginUid + "-token"))) { if(userTokens.get(i).getSha1().equals(tinyDb.getString(loginUid + "-token"))) {
setTokenFlag = true; setTokenFlag = true;
break; break;
} }
@ -658,18 +640,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
Call<UserTokens> callCreateToken; Call<UserTokens> callCreateToken;
if(loginOTP != 0) { if(loginOTP != 0) {
callCreateToken = RetrofitClient callCreateToken = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().createNewTokenWithOTP(credential, loginOTP, loginUid, createUserToken);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.createNewTokenWithOTP(credential, loginOTP, loginUid, createUserToken);
} }
else { else {
callCreateToken = RetrofitClient callCreateToken = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().createNewToken(credential, loginUid, createUserToken);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.createNewToken(credential, loginUid, createUserToken);
} }
@ -686,12 +662,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
assert newToken != null; assert newToken != null;
//Log.i("Tokens-NEW", "new:" + newToken.getSha1()); //Log.i("Tokens-NEW", "new:" + newToken.getSha1());
if (!newToken.getSha1().equals("")) { if(!newToken.getSha1().equals("")) {
Call<UserInfo> call = RetrofitClient Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo("token " + newToken.getSha1());
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserInfo("token " + newToken.getSha1());
call.enqueue(new Callback<UserInfo>() { call.enqueue(new Callback<UserInfo>() {
@ -700,9 +673,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
UserInfo userDetails = response.body(); UserInfo userDetails = response.body();
if (response.isSuccessful()) { if(response.isSuccessful()) {
if (response.code() == 200) { if(response.code() == 200) {
tinyDb.remove("loginPass"); tinyDb.remove("loginPass");
tinyDb.putBoolean("loggedInMode", true); tinyDb.putBoolean("loggedInMode", true);
@ -719,14 +692,14 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else if(response.code() == 401) { else if(response.code() == 401) {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.unauthorizedApiError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.unauthorizedApiError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -738,7 +711,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -752,7 +725,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else if(responseCreate.code() == 500) { else if(responseCreate.code() == 500) {
SnackBar.error(getApplicationContext(), layoutView,getResources().getString(R.string.genericApiStatusError) + responseCreate.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + responseCreate.code());
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -773,10 +746,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<UserInfo> callGetUsername = RetrofitClient Call<UserInfo> callGetUsername = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo(instanceToken);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserInfo(instanceToken);
callGetUsername.enqueue(new Callback<UserInfo>() { callGetUsername.enqueue(new Callback<UserInfo>() {
@ -785,9 +755,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
UserInfo userDetails = response.body(); UserInfo userDetails = response.body();
if (response.isSuccessful()) { if(response.isSuccessful()) {
if (response.code() == 200) { if(response.code() == 200) {
assert userDetails != null; assert userDetails != null;
tinyDb.putString("userLogin", userDetails.getUsername()); tinyDb.putString("userLogin", userDetails.getUsername());
@ -801,14 +771,14 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else if(response.code() == 401) { else if(response.code() == 401) {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.unauthorizedApiError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.unauthorizedApiError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -820,7 +790,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -834,14 +804,14 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else if(response.code() == 500) { else if(response.code() == 500) {
SnackBar.error(getApplicationContext(), layoutView,getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView,getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -853,7 +823,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
public void onFailure(@NonNull Call<List<UserTokens>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<UserTokens>> call, @NonNull Throwable t) {
Log.e("onFailure-login", t.toString()); Log.e("onFailure-login", t.toString());
SnackBar.error(getApplicationContext(), layoutView,getResources().getString(R.string.malformedJson)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.malformedJson));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -866,7 +836,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
loginButton.setEnabled(false); loginButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable(); GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 ); shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.hintColor)); shape.setColor(getResources().getColor(R.color.hintColor));
loginButton.setBackground(shape); loginButton.setBackground(shape);
@ -876,7 +846,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
loginButton.setEnabled(true); loginButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable(); GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 ); shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.btnBackground)); shape.setColor(getResources().getColor(R.color.btnBackground));
loginButton.setBackground(shape); loginButton.setBackground(shape);

View File

@ -4,14 +4,6 @@ import android.app.Activity;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import androidx.annotation.NonNull;
import com.google.android.material.navigation.NavigationView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -22,28 +14,36 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.navigation.NavigationView;
import com.squareup.picasso.NetworkPolicy; import com.squareup.picasso.NetworkPolicy;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.AboutFragment; import org.mian.gitnex.fragments.AboutFragment;
import org.mian.gitnex.fragments.AdministrationFragment;
import org.mian.gitnex.fragments.ExploreRepositoriesFragment; import org.mian.gitnex.fragments.ExploreRepositoriesFragment;
import org.mian.gitnex.fragments.MyRepositoriesFragment; import org.mian.gitnex.fragments.MyRepositoriesFragment;
import org.mian.gitnex.fragments.BottomSheetNavSubMenuFragment;
import org.mian.gitnex.fragments.OrganizationsFragment; import org.mian.gitnex.fragments.OrganizationsFragment;
import org.mian.gitnex.fragments.ProfileFragment;
import org.mian.gitnex.fragments.RepositoriesFragment;
import org.mian.gitnex.fragments.SettingsFragment; import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.fragments.StarredRepositoriesFragment; import org.mian.gitnex.fragments.StarredRepositoriesFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.ChangeLog; import org.mian.gitnex.helpers.ChangeLog;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.fragments.ProfileFragment;
import org.mian.gitnex.fragments.RepositoriesFragment;
import java.util.Objects; import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -60,10 +60,12 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
private ImageView userAvatar; private ImageView userAvatar;
private TextView toolbarTitle; private TextView toolbarTitle;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private Typeface myTypeface; private Typeface myTypeface;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId() {
return R.layout.activity_main; return R.layout.activity_main;
} }
@ -71,7 +73,9 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); appCtx = getApplicationContext();
final TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("noConnection", false); tinyDb.putBoolean("noConnection", false);
//userAvatar = findViewById(R.id.userAvatar); //userAvatar = findViewById(R.id.userAvatar);
@ -96,10 +100,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
tinyDb.putInt("homeScreenId", 0); tinyDb.putInt("homeScreenId", 0);
} }
String appLocale = tinyDb.getString("locale"); boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
AppUtil.setAppLocale(getResources(), appLocale);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
if(!tinyDb.getBoolean("loggedInMode")) { if(!tinyDb.getBoolean("loggedInMode")) {
logout(this, ctx); logout(this, ctx);
@ -130,43 +131,37 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
FragmentManager fm = getSupportFragmentManager(); FragmentManager fm = getSupportFragmentManager();
Fragment fragmentById = fm.findFragmentById(R.id.fragment_container); Fragment fragmentById = fm.findFragmentById(R.id.fragment_container);
if (fragmentById instanceof SettingsFragment) { if(fragmentById instanceof SettingsFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings));
} }
else if (fragmentById instanceof MyRepositoriesFragment) { else if(fragmentById instanceof MyRepositoriesFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
} }
else if (fragmentById instanceof StarredRepositoriesFragment) { else if(fragmentById instanceof StarredRepositoriesFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
} }
else if (fragmentById instanceof OrganizationsFragment) { else if(fragmentById instanceof OrganizationsFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
} }
else if (fragmentById instanceof ExploreRepositoriesFragment) { else if(fragmentById instanceof ExploreRepositoriesFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
} }
else if (fragmentById instanceof ProfileFragment) { else if(fragmentById instanceof ProfileFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
} }
else if (fragmentById instanceof AboutFragment) { else if(fragmentById instanceof AboutFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout)); toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout));
} }
else if(fragmentById instanceof AdministrationFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration));
}
drawer = findViewById(R.id.drawer_layout); drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view); NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this); navigationView.setNavigationItemSelectedListener(this);
final View hView = navigationView.getHeaderView(0); final View hView = navigationView.getHeaderView(0);
ImageView navSubMenu = hView.findViewById(R.id.navSubMenu); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
navSubMenu.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
BottomSheetNavSubMenuFragment bottomSheet = new BottomSheetNavSubMenuFragment();
bottomSheet.show(getSupportFragmentManager(), "adminMenuBottomSheet");
}
});
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.darkGreen)); toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.darkGreen));
drawer.addDrawerListener(toggle); drawer.addDrawerListener(toggle);
@ -181,7 +176,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
public void onDrawerOpened(@NonNull View drawerView) { public void onDrawerOpened(@NonNull View drawerView) {
if(tinyDb.getBoolean("noConnection")) { if(tinyDb.getBoolean("noConnection")) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
tinyDb.putBoolean("noConnection", false); tinyDb.putBoolean("noConnection", false);
} }
@ -190,26 +185,27 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
String userAvatarNav = tinyDb.getString("userAvatar"); String userAvatarNav = tinyDb.getString("userAvatar");
userEmail = hView.findViewById(R.id.userEmail); userEmail = hView.findViewById(R.id.userEmail);
if (!userEmailNav.equals("")) { if(!userEmailNav.equals("")) {
userEmail.setText(userEmailNav); userEmail.setText(userEmailNav);
userEmail.setTypeface(myTypeface); userEmail.setTypeface(myTypeface);
} }
userFullName = hView.findViewById(R.id.userFullname); userFullName = hView.findViewById(R.id.userFullname);
if (!userFullNameNav.equals("")) { if(!userFullNameNav.equals("")) {
userFullName.setText(userFullNameNav); userFullName.setText(userFullNameNav);
userFullName.setTypeface(myTypeface); userFullName.setTypeface(myTypeface);
} }
userAvatar = hView.findViewById(R.id.userAvatar); userAvatar = hView.findViewById(R.id.userAvatar);
if (!userAvatarNav.equals("")) { if(!userAvatarNav.equals("")) {
PicassoService.getInstance(ctx).get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar); PicassoService.getInstance(ctx).get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
} }
userAvatar.setOnClickListener(new View.OnClickListener() { userAvatar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ProfileFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
drawer.closeDrawers(); drawer.closeDrawers();
} }
}); });
@ -232,38 +228,32 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
if(savedInstanceState == null) { if(savedInstanceState == null) {
if(tinyDb.getInt("homeScreenId") == 0) { if(tinyDb.getInt("homeScreenId") == 0) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
new MyRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home); navigationView.setCheckedItem(R.id.nav_home);
} }
else if(tinyDb.getInt("homeScreenId") == 1) { else if(tinyDb.getInt("homeScreenId") == 1) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
new StarredRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_starred_repos); navigationView.setCheckedItem(R.id.nav_starred_repos);
} }
else if(tinyDb.getInt("homeScreenId") == 2) { else if(tinyDb.getInt("homeScreenId") == 2) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
new OrganizationsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_organizations); navigationView.setCheckedItem(R.id.nav_organizations);
} }
else if(tinyDb.getInt("homeScreenId") == 3) { else if(tinyDb.getInt("homeScreenId") == 3) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
new RepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_repositories); navigationView.setCheckedItem(R.id.nav_repositories);
} }
else if(tinyDb.getInt("homeScreenId") == 4) { else if(tinyDb.getInt("homeScreenId") == 4) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
new ProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile); navigationView.setCheckedItem(R.id.nav_profile);
} }
else { else {
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
new MyRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home); navigationView.setCheckedItem(R.id.nav_home);
} }
} }
@ -271,12 +261,13 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
if(!connToInternet) { if(!connToInternet) {
if(!tinyDb.getBoolean("noConnection")) { if(!tinyDb.getBoolean("noConnection")) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
} }
tinyDb.putBoolean("noConnection", true); tinyDb.putBoolean("noConnection", true);
} else { }
else {
displayUserInfo(instanceUrl, instanceToken, loginUid); displayUserInfo(instanceUrl, instanceToken, loginUid);
giteaVersion(instanceUrl); giteaVersion(instanceUrl);
@ -287,15 +278,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
// Changelog popup // Changelog popup
int versionCode = 0; int versionCode = 0;
try { try {
PackageInfo packageInfo = getApplicationContext().getPackageManager() PackageInfo packageInfo = appCtx.getPackageManager().getPackageInfo(appCtx.getPackageName(), 0);
.getPackageInfo(getApplicationContext().getPackageName(), 0);
versionCode = packageInfo.versionCode; versionCode = packageInfo.versionCode;
} }
catch (PackageManager.NameNotFoundException e) { catch(PackageManager.NameNotFoundException e) {
Log.e("changelogDialog", Objects.requireNonNull(e.getMessage())); Log.e("changelogDialog", Objects.requireNonNull(e.getMessage()));
} }
if (versionCode > tinyDb.getInt("versionCode")) { if(versionCode > tinyDb.getInt("versionCode")) {
tinyDb.putInt("versionCode", versionCode); tinyDb.putInt("versionCode", versionCode);
tinyDb.putBoolean("versionFlag", true); tinyDb.putBoolean("versionFlag", true);
ChangeLog changelogDialog = new ChangeLog(this); ChangeLog changelogDialog = new ChangeLog(this);
@ -303,7 +293,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
} }
public void setActionBarTitle (@NonNull String title) { public void setActionBarTitle(@NonNull String title) {
Objects.requireNonNull(getSupportActionBar()).setTitle(title); Objects.requireNonNull(getSupportActionBar()).setTitle(title);
} }
@ -322,32 +313,27 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
@Override @Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) { switch(menuItem.getItemId()) {
case R.id.nav_home: case R.id.nav_home:
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
new MyRepositoriesFragment()).commit();
break; break;
case R.id.nav_organizations: case R.id.nav_organizations:
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
new OrganizationsFragment()).commit();
break; break;
case R.id.nav_profile: case R.id.nav_profile:
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
new ProfileFragment()).commit();
break; break;
case R.id.nav_repositories: case R.id.nav_repositories:
toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
new RepositoriesFragment()).commit();
break; break;
case R.id.nav_settings: case R.id.nav_settings:
toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit();
new SettingsFragment()).commit();
break; break;
case R.id.nav_logout: case R.id.nav_logout:
logout(this, ctx); logout(this, ctx);
@ -355,21 +341,22 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
break; break;
case R.id.nav_about: case R.id.nav_about:
toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout)); toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit();
new AboutFragment()).commit();
break; break;
case R.id.nav_rate_app: case R.id.nav_rate_app:
rateThisApp(); rateThisApp();
break; break;
case R.id.nav_starred_repos: case R.id.nav_starred_repos:
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
new StarredRepositoriesFragment()).commit();
break; break;
case R.id.nav_explore: case R.id.nav_explore:
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreRepositoriesFragment()).commit();
new ExploreRepositoriesFragment()).commit(); break;
case R.id.nav_administration:
toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AdministrationFragment()).commit();
break; break;
} }
@ -379,12 +366,12 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
public void rateThisApp() { public void rateThisApp() {
try { try {
startActivity(new Intent(Intent.ACTION_VIEW, startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName())));
Uri.parse("market://details?id=" + getPackageName()))); }
} catch (ActivityNotFoundException e) { catch(ActivityNotFoundException e) {
startActivity(new Intent(Intent.ACTION_VIEW, startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())));
Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())));
} }
} }
@ -402,21 +389,18 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
private void giteaVersion(final String instanceUrl) { private void giteaVersion(final String instanceUrl) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
Call<GiteaVersion> callVersion = RetrofitClient Call<GiteaVersion> callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken(token);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getGiteaVersionWithToken(token);
callVersion.enqueue(new Callback<GiteaVersion>() { callVersion.enqueue(new Callback<GiteaVersion>() {
@Override @Override
public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) { public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) {
if (responseVersion.code() == 200) { if(responseVersion.code() == 200) {
GiteaVersion version = responseVersion.body(); GiteaVersion version = responseVersion.body();
assert version != null; assert version != null;
@ -440,12 +424,9 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
private void displayUserInfo(String instanceUrl, String token, String loginUid) { private void displayUserInfo(String instanceUrl, String token, String loginUid) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(appCtx);
Call<UserInfo> call = RetrofitClient Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo(Authorization.returnAuthentication(ctx, loginUid, token));
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserInfo(Authorization.returnAuthentication(getApplicationContext(), loginUid, token));
NavigationView navigationView = findViewById(R.id.nav_view); NavigationView navigationView = findViewById(R.id.nav_view);
final View hView = navigationView.getHeaderView(0); final View hView = navigationView.getHeaderView(0);
@ -457,13 +438,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
UserInfo userDetails = response.body(); UserInfo userDetails = response.body();
if (response.isSuccessful()) { if(response.isSuccessful()) {
if (response.code() == 200) { if(response.code() == 200) {
assert userDetails != null; assert userDetails != null;
if(userDetails.getIs_admin() != null) { if(userDetails.getIs_admin() != null) {
tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin()); tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin());
navigationView.getMenu().findItem(R.id.nav_administration).setVisible(userDetails.getIs_admin());
} }
tinyDb.putString("userLogin", userDetails.getLogin()); tinyDb.putString("userLogin", userDetails.getLogin());
tinyDb.putInt("userId", userDetails.getId()); tinyDb.putInt("userId", userDetails.getId());
@ -479,38 +461,42 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
if(userDetails.getLang() != null) { if(userDetails.getLang() != null) {
tinyDb.putString("userLang", userDetails.getLang()); tinyDb.putString("userLang", userDetails.getLang());
} }
else else {
{
tinyDb.putString("userLang", "..."); tinyDb.putString("userLang", "...");
} }
userAvatar = hView.findViewById(R.id.userAvatar); userAvatar = hView.findViewById(R.id.userAvatar);
if (!Objects.requireNonNull(userDetails).getAvatar().equals("")) { if(!Objects.requireNonNull(userDetails).getAvatar().equals("")) {
PicassoService.getInstance(ctx).get().load(userDetails.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar); PicassoService.getInstance(ctx).get().load(userDetails.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
} else { }
else {
userAvatar.setImageResource(R.mipmap.app_logo_round); userAvatar.setImageResource(R.mipmap.app_logo_round);
} }
userFullName = hView.findViewById(R.id.userFullname); userFullName = hView.findViewById(R.id.userFullname);
if (!userDetails.getFullname().equals("")) { if(!userDetails.getFullname().equals("")) {
userFullName.setText(userDetails.getFullname()); userFullName.setText(userDetails.getFullname());
} else if (!userDetails.getLogin().equals("")) { }
else if(!userDetails.getLogin().equals("")) {
userFullName.setText(userDetails.getLogin()); userFullName.setText(userDetails.getLogin());
} else { }
else {
userFullName.setText("..."); userFullName.setText("...");
} }
userEmail = hView.findViewById(R.id.userEmail); userEmail = hView.findViewById(R.id.userEmail);
if (!userDetails.getEmail().equals("")) { if(!userDetails.getEmail().equals("")) {
userEmail.setText(userDetails.getEmail()); userEmail.setText(userDetails.getEmail());
} else { }
else {
userEmail.setText("..."); userEmail.setText("...");
} }
userAvatar.setOnClickListener(new View.OnClickListener() { userAvatar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ProfileFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
drawer.closeDrawers(); drawer.closeDrawers();
} }
}); });
@ -520,16 +506,13 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
else if(response.code() == 401) { else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else { else {
String toastError = getResources().getString(R.string.genericApiStatusError) + String.valueOf(response.code()); String toastError = getResources().getString(R.string.genericApiStatusError) + String.valueOf(response.code());
Toasty.info(getApplicationContext(), toastError); Toasty.info(ctx, toastError);
} }
@ -537,6 +520,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
@Override @Override
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });

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<>(MergePullRequestActivity.this, 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,11 +255,49 @@ public class MergePullRequestActivity extends BaseActivity {
if(response.code() == 200) { if(response.code() == 200) {
Toasty.info(getApplicationContext(), getString(R.string.mergePRSuccessMsg)); if(deleteBranch) {
if(tinyDb.getString("prIsFork").equals("true")) {
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("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true); tinyDb.putBoolean("resumePullRequests", true);
finish(); 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,10 +101,9 @@ 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);
@ -90,17 +113,53 @@ public class OrganizationTeamMembersActivity extends BaseActivity {
mGridView.setAdapter(adapter); mGridView.setAdapter(adapter);
noDataMembers.setVisibility(View.VISIBLE); noDataMembers.setVisibility(View.VISIBLE);
} }
}
}); });
} }
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public boolean onCreateOptionsMenu(Menu menu) {
finish();
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();
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.valueOf(commentId), addComment.getText().toString()); IssueActions.editIssueComment(ctx, Integer.parseInt(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,47 +15,121 @@ 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;
private FragmentRefreshListener fragmentRefreshListener;
private FragmentRefreshListenerPr fragmentRefreshListenerPr;
private FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone;
final Context ctx = this;
private Context appCtx;
// issues interface
public FragmentRefreshListener getFragmentRefreshListener() {
return fragmentRefreshListener;
}
public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) {
this.fragmentRefreshListener = fragmentRefreshListener;
}
public interface FragmentRefreshListener {
void onRefresh(String text);
}
// pr interface
public FragmentRefreshListenerPr getFragmentRefreshListenerPr() {
return fragmentRefreshListenerPr;
}
public void setFragmentRefreshListenerPr(FragmentRefreshListenerPr fragmentRefreshListenerPr) {
this.fragmentRefreshListenerPr = fragmentRefreshListenerPr;
}
public interface FragmentRefreshListenerPr {
void onRefresh(String text);
}
// milestones interface
public FragmentRefreshListenerMilestone getFragmentRefreshListenerMilestone() {
return fragmentRefreshListenerMilestone;
}
public void setFragmentRefreshListenerMilestone(FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone) {
this.fragmentRefreshListenerMilestone = fragmentRefreshListenerMilestone;
}
public interface FragmentRefreshListenerMilestone {
void onRefresh(String text);
}
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId() {
return R.layout.activity_repo_detail; return R.layout.activity_repo_detail;
} }
@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 repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
String repoName1 = parts[1]; String repoName1 = parts[1];
@ -73,6 +139,10 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
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");
tinyDb.putString("repoIssuesState", "open");
tinyDb.putString("repoPrState", "open");
tinyDb.putString("milestoneState", "open");
String appLocale = tinyDb.getString("locale"); String appLocale = tinyDb.getString("locale");
AppUtil.setAppLocale(getResources(), appLocale); AppUtil.setAppLocale(getResources(), appLocale);
@ -95,15 +165,15 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
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;
} }
@ -113,12 +183,12 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0); ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount(); int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) { for(int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j); ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildCount = vgTab.getChildCount(); int tabChildCount = vgTab.getChildCount();
for (int i = 0; i < tabChildCount; i++) { for(int i = 0; i < tabChildCount; i++) {
View tabViewChild = vgTab.getChildAt(i); View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) { if(tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(myTypeface); ((TextView) tabViewChild).setTypeface(myTypeface);
} }
} }
@ -126,7 +196,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
// only show Collaborators if you have permission to // only show Collaborators if you have permission to
final View collaboratorTab = vg.getChildAt(8); final View collaboratorTab = vg.getChildAt(8);
if (tinyDb.getBoolean("isRepoAdmin")) { if(tinyDb.getBoolean("isRepoAdmin")) {
collaboratorTab.setVisibility(View.VISIBLE); collaboratorTab.setVisibility(View.VISIBLE);
} }
else { else {
@ -151,11 +221,11 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
textViewBadgePull.setVisibility(View.GONE); textViewBadgePull.setVisibility(View.GONE);
textViewBadgeRelease.setVisibility(View.GONE); textViewBadgeRelease.setVisibility(View.GONE);
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName1);
ColorStateList textColor = tabLayout.getTabTextColors(); ColorStateList textColor = tabLayout.getTabTextColors();
// issue count // issue count
if (textViewBadgeIssue.getText() != "") { if(textViewBadgeIssue.getText() != "") {
TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2); TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2);
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2); Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2);
assert tabOpenIssues != null; assert tabOpenIssues != null;
@ -164,16 +234,16 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
} }
// pull count // pull count
if (textViewBadgePull.getText() != "") { // only show if API returned a number if(textViewBadgePull.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(4)).setCustomView(tabHeader4); Objects.requireNonNull(tabLayout.getTabAt(3)).setCustomView(tabHeader4);
TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(4); TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(3);
assert tabOpenPulls != null; assert tabOpenPulls != null;
TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText); TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText);
openPullTabView.setTextColor(textColor); openPullTabView.setTextColor(textColor);
} }
// release count // release count
if (VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) { if(new Version("1.11.4").less(tinyDb.getString("giteaVersion"))) {
if(textViewBadgeRelease.getText() != "") { // only show if API returned a number if(textViewBadgeRelease.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6); Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5); TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5);
@ -184,8 +254,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
} }
} }
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName1);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName1);
} }
@ -193,7 +263,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
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");
@ -203,7 +273,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("enableCounterIssueBadge")) { if(tinyDb.getBoolean("enableCounterIssueBadge")) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
} }
} }
@ -222,7 +292,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
int id = item.getItemId(); int id = item.getItemId();
switch (id) { switch(id) {
case android.R.id.home: case android.R.id.home:
finish(); finish();
return true; return true;
@ -230,6 +300,18 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment(); BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment();
bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet");
return true; 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: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -239,9 +321,9 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
@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 "label": case "label":
startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class)); startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class));
break; break;
@ -271,6 +353,36 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
case "newFile": case "newFile":
startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class)); startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class));
break; 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;
} }
} }
@ -278,6 +390,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
public class SectionsPagerAdapter extends FragmentStatePagerAdapter { public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) { SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
} }
@ -285,30 +398,31 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
@Override @Override
public Fragment getItem(int position) { public Fragment getItem(int position) {
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("/");
String repoOwner = parts[0]; String repoOwner = parts[0];
String repoName = parts[1]; String repoName = parts[1];
Fragment fragment = null; Fragment fragment = null;
switch (position) { switch(position) {
case 0: // files case 0: // information
return FilesFragment.newInstance(repoOwner, repoName);
case 1: // information
return RepoInfoFragment.newInstance(repoOwner, repoName); return RepoInfoFragment.newInstance(repoOwner, repoName);
case 1: // files
return FilesFragment.newInstance(repoOwner, repoName);
case 2: // issues case 2: // issues
fragment = new IssuesMainFragment(); fragment = new IssuesFragment();
break; break;
case 3: // branches case 3: // pull requests
return BranchesFragment.newInstance(repoOwner, repoName);
case 4: // pull requests
fragment = new PullRequestsFragment(); fragment = new PullRequestsFragment();
break; break;
case 4: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 5: // releases case 5: // releases
return ReleasesFragment.newInstance(repoOwner, repoName); return ReleasesFragment.newInstance(repoOwner, repoName);
case 6: // milestones case 6: // milestones
return MilestonesFragment.newInstance(repoOwner, repoName); fragment = new MilestonesFragment();
break;
case 7: // labels case 7: // labels
return LabelsFragment.newInstance(repoOwner, repoName); return LabelsFragment.newInstance(repoOwner, repoName);
case 8: // collaborators case 8: // collaborators
@ -320,6 +434,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
@Override @Override
public int getCount() { public int getCount() {
return 9; return 9;
} }
@ -327,12 +442,9 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) { private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
Call<UserRepositories> call = RetrofitClient Call<UserRepositories> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserRepository(token, owner, repo);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserRepository(token, owner, repo);
call.enqueue(new Callback<UserRepositories>() { call.enqueue(new Callback<UserRepositories>() {
@ -341,9 +453,9 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
UserRepositories repoInfo = response.body(); UserRepositories repoInfo = response.body();
if (response.isSuccessful()) { if(response.isSuccessful()) {
if (response.code() == 200) { if(response.code() == 200) {
if(tinyDb.getBoolean("enableCounterBadges")) { if(tinyDb.getBoolean("enableCounterBadges")) {
assert repoInfo != null; assert repoInfo != null;
@ -375,6 +487,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
@Override @Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
@ -386,23 +499,21 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
Call<JsonElement> call; Call<JsonElement> call;
call = RetrofitClient call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoStarStatus(instanceToken, owner, repo);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.checkRepoStarStatus(instanceToken, owner, repo);
call.enqueue(new Callback<JsonElement>() { call.enqueue(new Callback<JsonElement>() {
@Override @Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) { public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putInt("repositoryStarStatus", response.code()); tinyDb.putInt("repositoryStarStatus", response.code());
} }
@Override @Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
@ -411,19 +522,16 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) { private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
Call<WatchRepository> call; Call<WatchInfo> call;
call = RetrofitClient call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoWatchStatus(instanceToken, owner, repo);
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.checkRepoWatchStatus(instanceToken, owner, repo);
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) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(appCtx);
if(response.code() == 200) { if(response.code() == 200) {
assert response.body() != null; assert response.body() != null;
@ -438,7 +546,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
} }
@Override @Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); 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) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
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);
commitTitle = itemView.findViewById(R.id.commitTitleVw);
commitCommitter = itemView.findViewById(R.id.commitCommitterVw);
commitDate = itemView.findViewById(R.id.commitDateVw);
commitHtmlUrl = itemView.findViewById(R.id.commitHtmlUrlVw);
}
@SuppressLint("SetTextI18n")
void bindData(Commits commitsModel) {
final TinyDB tinyDb = new TinyDB(ctx); final TinyDB tinyDb = new TinyDB(ctx);
final String locale = tinyDb.getString("locale"); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
TextView commitTitleVw; commitTitle.setText(commitsModel.getCommit().getMessage());
TextView commitCommitterVw; commitCommitter.setText(ctx.getString(R.string.commitCommittedBy, commitsModel.getCommit().getCommitter().getName()));
TextView commitDateVw;
TextView commitHtmlUrlVw;
public ViewHolder(View itemView) { commitDate.setText(TimeHelper.formatTime(commitsModel.getCommit().getCommitter().getDate(), new Locale(locale), timeFormat, ctx));
super(itemView);
commitTitleVw = itemView.findViewById(R.id.commitTitleVw);
commitCommitterVw = itemView.findViewById(R.id.commitCommitterVw);
commitDateVw = itemView.findViewById(R.id.commitDateVw);
commitHtmlUrlVw = itemView.findViewById(R.id.commitHtmlUrlVw);
}
@Override
public void bindView(CommitsAdapter item, @NonNull List<Object> payloads) {
commitTitleVw.setText(item.getCommitTitle());
commitCommitterVw.setText(ctx.getString(R.string.commitCommittedBy, item.getcommitCommitter()));
commitDateVw.setText(TimeHelper.formatTime(item.getcommitDate(), 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); static class LoadHolder extends RecyclerView.ViewHolder {
commitCommitterVw.setText(null);
commitDateVw.setText(null); LoadHolder(View itemView) {
commitHtmlUrlVw.setText(null);
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,139 +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() {
holder.setIsRecyclable(false); return fileDiffViews.size();
FileDiffView data = dataList.get(position); }
@Override
public Object getItem(int position) {
return fileDiffViews.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint({"ViewHolder", "InflateParams"})
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_files_diffs, null, false);
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);
FileDiffView data = (FileDiffView) getItem(position);
headerFileName.setText(data.getFileName());
if(data.isFileType()) { if(data.isFileType()) {
holder.fileName.setText(data.getFileName()); diffStats.setVisibility(View.GONE);
diffLines.addView(getMessageView(context.getResources().getString(R.string.binaryFileError)));
holder.fileInfo.setVisibility(View.GONE);
//byte[] imageData = Base64.decode(data.getFileContents(), Base64.DEFAULT);
//Drawable imageDrawable = new BitmapDrawable(ctx.getResources(), BitmapFactory.decodeByteArray(imageData, 0, imageData.length));
//holder.fileImage.setImageDrawable(imageDrawable);
holder.fileContentsView.setVisibility(View.GONE);
} }
else { else {
String[] splitData = data.getFileContents().split("\\R"); diffStats.setVisibility(View.VISIBLE);
headerFileInfo.setText(data.getFileInfo());
for (String eachSplit : splitData) { String[] codeLines = getLines(data.getFileContents());
TextView textLine = new TextView(ctx); if(MAXIMUM_LINES > codeLines.length) {
textLine.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
if (eachSplit.startsWith("+")) { for(int l=0; l<codeLines.length; l++) {
textLine.setText(eachSplit); if(codeLines[l].length() > 0) {
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.diffAddedColor)); 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);
boolean isSelected = false;
for(View view : selectedViews.values()) {
if(((DiffTextView) view).getPosition() == uniquePosition) {
diffTextView.setBackgroundColor(COLOR_SELECTED);
isSelected = true;
break;
} }
else if (eachSplit.startsWith("-")) {
textLine.setText(eachSplit); }
holder.allLines.addView(textLine);
textLine.setTextColor(ctx.getResources().getColor(R.color.colorPrimary));
textLine.setPadding(5, 5, 5, 5); if(codeLines[l].startsWith("+")) {
textLine.setBackgroundColor(ctx.getResources().getColor(R.color.diffRemovedColor));
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 { else {
if(eachSplit.length() > 0) { diffTextView.setText(codeLines[l]);
textLine.setText(eachSplit); diffTextView.setTextColor(COLOR_FONT);
holder.allLines.addView(textLine);
textLine.setTextColor(ctx.getResources().getColor(R.color.colorPrimary)); if(!isSelected) {
textLine.setPadding(5, 5, 5, 5);
textLine.setBackgroundColor(ctx.getResources().getColor(R.color.white)); diffTextView.setInitialBackgroundColor(COLOR_NORMAL);
} }
} }
}
holder.fileName.setText(data.getFileName()); diffTextView.setOnClickListener(v -> {
if(!data.getFileInfo().equals("")) {
holder.fileInfo.setText(ctx.getResources().getString(R.string.fileDiffInfoChanges, data.getFileInfo())); if(((DiffTextView) v).getCurrentBackgroundColor() != COLOR_SELECTED) {
selectedViews.put(((DiffTextView) v).getPosition(), v);
v.setBackgroundColor(COLOR_SELECTED);
} }
else { else {
holder.fileInfo.setVisibility(View.GONE);
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);
} }
} }
@Override }
public int getItemCount() { else {
return dataList.size();
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 -> {
deleteIssueComment(ctx, Integer.parseInt(commendId.getText().toString()), getAdapterPosition());
dialog.dismiss(); 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> { }
final TinyDB tinyDb = new TinyDB(ctx); @Override
final String locale = tinyDb.getString("locale"); public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
final String timeFormat = tinyDb.getString("dateFormat");
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
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 -> {
@Override
public void bindView(@NonNull IssuesAdapter item, @NonNull List<Object> payloads) {
if (!item.getUserFullname().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserFullname(), ctx));
}
else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserLogin(), ctx));
}
PicassoService.getInstance(ctx).get().load(item.getIssueAssigneeAvatar()).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>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + item.getIssueTitle()));
issueNumber.setText(String.valueOf(item.getIssueNumber()));
issueCommentsCount.setText(String.valueOf(item.getIssueCommentsCount()));
switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getIssueCreatedTime()), ctx));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
break;
}
}
}
@Override
public void unbindView(@NonNull IssuesAdapter item) {
issueTitle.setText(null);
issueCommentsCount.setText(null);
issueCreatedTime.setText(null);
}
}
public static class IssueTitleClickEvent extends ClickEventHook<IssuesAdapter> {
@Nullable
@Override
public List<View> onBindMany(@NonNull RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof IssuesAdapter.ViewHolder) {
return EventHookUtil.toList(((ViewHolder) viewHolder).issueTitle);
}
return super.onBindMany(viewHolder);
}
@Override
public void onClick(View v, int position, @NonNull FastAdapter<IssuesAdapter> fastAdapter, IssuesAdapter item) {
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", item.getIssueNumber()); intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", String.valueOf(item.getIssueNumber())); tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue"); tinyDb.putString("issueType", "issue");
context.startActivity(intent); 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);
});
} }
@SuppressLint("SetTextI18n")
void bindData(Issues issuesModel) {
final TinyDB tinyDb = new TinyDB(context);
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 {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
}
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='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
issueNumber.setText(String.valueOf(issuesModel.getNumber()));
issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
}
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<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;
@ -73,7 +116,8 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
private ProgressBar msProgress; private ProgressBar msProgress;
private TextView milestoneStatus; private TextView milestoneStatus;
private MilestonesViewHolder(View itemView) { DataHolder(View itemView) {
super(itemView); super(itemView);
milestoneId = itemView.findViewById(R.id.milestoneId); milestoneId = itemView.findViewById(R.id.milestoneId);
@ -118,6 +162,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
MilestoneActions.closeMilestone(ctx, milestoneId_); MilestoneActions.closeMilestone(ctx, milestoneId_);
dialog.dismiss(); dialog.dismiss();
updateAdapter(getAdapterPosition());
}); });
@ -125,40 +170,25 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
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
public MilestonesAdapter.MilestonesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_milestones, parent, false);
return new MilestonesAdapter.MilestonesViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull MilestonesAdapter.MilestonesViewHolder holder, int position) {
final TinyDB tinyDb = new TinyDB(mCtx);
final String locale = tinyDb.getString("locale"); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
Milestones currentItem = milestonesList.get(position); milestoneId.setText(String.valueOf(dataModel.getId()));
milestoneStatus.setText(dataModel.getState());
holder.milestoneId.setText(String.valueOf(currentItem.getId())); final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
holder.milestoneStatus.setText(currentItem.getState());
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> { .usePlugin(ImagesPlugin.create(plugin -> {
plugin.addSchemeHandler(new SchemeHandler() { plugin.addSchemeHandler(new SchemeHandler() {
@ -166,12 +196,12 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
@Override @Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = mCtx.getResources().getIdentifier( final int resourceId = context.getResources().getIdentifier(
raw.substring("drawable://".length()), raw.substring("drawable://".length()),
"drawable", "drawable",
mCtx.getPackageName()); context.getPackageName());
final Drawable drawable = mCtx.getDrawable(resourceId); final Drawable drawable = context.getDrawable(resourceId);
assert drawable != null; assert drawable != null;
return ImageItem.withResult(drawable); return ImageItem.withResult(drawable);
@ -185,9 +215,9 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
}); });
plugin.placeholderProvider(drawable -> null); plugin.placeholderProvider(drawable -> null);
plugin.addMediaDecoder(GifMediaDecoder.create(false)); plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources())); plugin.addMediaDecoder(SvgMediaDecoder.create(context.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create()); plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources())); plugin.defaultMediaDecoder(DefaultMediaDecoder.create(context.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
})) }))
.usePlugin(new AbstractMarkwonPlugin() { .usePlugin(new AbstractMarkwonPlugin() {
@ -196,26 +226,26 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
builder builder
.codeTextColor(tinyDb.getInt("codeBlockColor")) .codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue)); .linkColor(context.getResources().getColor(R.color.lightBlue));
} }
}) })
.usePlugin(TablePlugin.create(mCtx)) .usePlugin(TablePlugin.create(context))
.usePlugin(TaskListPlugin.create(mCtx)) .usePlugin(TaskListPlugin.create(context))
.usePlugin(HtmlPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create()) .usePlugin(LinkifyPlugin.create())
.build(); .build();
Spanned msTitle = markwon.toMarkdown(currentItem.getTitle()); Spanned msTitle_ = markwon.toMarkdown(dataModel.getTitle());
markwon.setParsedMarkdown(holder.msTitle, msTitle); markwon.setParsedMarkdown(msTitle, msTitle_);
if(currentItem.getState().equals("open")) { if(dataModel.getState().equals("open")) {
@SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.releaseStable)); @SuppressLint("ResourceType") int color = Color.parseColor(context.getResources().getString(R.color.releaseStable));
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
//.useFont(Typeface.DEFAULT) //.useFont(Typeface.DEFAULT)
.textColor(mCtx.getResources().getColor(R.color.white)) .textColor(context.getResources().getColor(R.color.white))
.fontSize(30) .fontSize(30)
.toUpperCase() .toUpperCase()
.width(120) .width(120)
@ -223,16 +253,16 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
.endConfig() .endConfig()
.buildRoundRect("open", color, 8); .buildRoundRect("open", color, 8);
holder.msStatus.setImageDrawable(drawable); msStatus.setImageDrawable(drawable);
} }
else if(currentItem.getState().equals("closed")) { else if(dataModel.getState().equals("closed")) {
@SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.colorRed)); @SuppressLint("ResourceType") int color = Color.parseColor(context.getResources().getString(R.color.colorRed));
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
//.useFont(Typeface.DEFAULT) //.useFont(Typeface.DEFAULT)
.textColor(mCtx.getResources().getColor(R.color.white)) .textColor(context.getResources().getColor(R.color.white))
.fontSize(30) .fontSize(30)
.toUpperCase() .toUpperCase()
.width(140) .width(140)
@ -240,123 +270,155 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
.endConfig() .endConfig()
.buildRoundRect("closed", color, 8); .buildRoundRect("closed", color, 8);
holder.msStatus.setImageDrawable(drawable); msStatus.setImageDrawable(drawable);
} }
if (!currentItem.getDescription().equals("")) { if (!dataModel.getDescription().equals("")) {
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getDescription())); final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(dataModel.getDescription()));
holder.msDescription.setText(bodyWithMD); msDescription.setText(bodyWithMD);
} }
else { else {
holder.msDescription.setText(""); msDescription.setText("");
} }
holder.msOpenIssues.setText(String.valueOf(currentItem.getOpen_issues())); msOpenIssues.setText(String.valueOf(dataModel.getOpen_issues()));
holder.msOpenIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneOpenIssues, currentItem.getOpen_issues()), mCtx)); msOpenIssues.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneOpenIssues, dataModel.getOpen_issues()), context));
holder.msClosedIssues.setText(String.valueOf(currentItem.getClosed_issues())); msClosedIssues.setText(String.valueOf(dataModel.getClosed_issues()));
holder.msClosedIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneClosedIssues, currentItem.getClosed_issues()), mCtx)); msClosedIssues.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneClosedIssues, dataModel.getClosed_issues()), context));
if ((currentItem.getOpen_issues() + currentItem.getClosed_issues()) > 0) { if ((dataModel.getOpen_issues() + dataModel.getClosed_issues()) > 0) {
if (currentItem.getOpen_issues() == 0) { if (dataModel.getOpen_issues() == 0) {
holder.msProgress.setProgress(100); msProgress.setProgress(100);
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 100), mCtx)); msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 100), context));
} }
else { else {
int msCompletion = 100 * currentItem.getClosed_issues() / (currentItem.getOpen_issues() + currentItem.getClosed_issues()); int msCompletion = 100 * dataModel.getClosed_issues() / (dataModel.getOpen_issues() + dataModel.getClosed_issues());
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, msCompletion), mCtx)); msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, msCompletion), context));
holder.msProgress.setProgress(msCompletion); msProgress.setProgress(msCompletion);
} }
} }
else { else {
holder.msProgress.setProgress(0); msProgress.setProgress(0);
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 0), mCtx)); msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 0), context));
} }
if(currentItem.getDue_on() != null) { if(dataModel.getDue_on() != null) {
if (timeFormat.equals("normal") || timeFormat.equals("pretty")) { if (timeFormat.equals("normal") || timeFormat.equals("pretty")) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale)); DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
Date date = null; Date date = null;
try { try {
date = formatter.parse(currentItem.getDue_on()); date = formatter.parse(dataModel.getDue_on());
} catch (ParseException e) { }
e.printStackTrace(); catch (ParseException e) {
Log.e(TAG, e.toString());
} }
assert date != null; assert date != null;
String dueDate = formatter.format(date); String dueDate = formatter.format(date);
if(date.before(new Date())) { if(date.before(new Date())) {
holder.msDueDate.setTextColor(mCtx.getResources().getColor(R.color.darkRed)); msDueDate.setTextColor(context.getResources().getColor(R.color.darkRed));
} }
holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate)); msDueDate.setText(dueDate);
holder.msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(currentItem.getDue_on()), mCtx)); msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(dataModel.getDue_on()), context));
}
else if (timeFormat.equals("normal1")) {
} else if (timeFormat.equals("normal1")) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale)); SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
Date date1 = null; Date date1 = null;
try { try {
date1 = formatter.parse(currentItem.getDue_on()); date1 = formatter.parse(dataModel.getDue_on());
} catch (ParseException e) { }
e.printStackTrace(); catch (ParseException e) {
Log.e(TAG, e.toString());
} }
assert date1 != null; assert date1 != null;
String dueDate = formatter.format(date1); String dueDate = formatter.format(date1);
holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate)); msDueDate.setText(dueDate);
} }
} }
else { else {
holder.msDueDate.setText(""); msDueDate.setText("");
}
}
}
private void updateAdapter(int position) {
dataList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, dataList.size());
}
@Override
public int getItemViewType(int position) {
if(dataList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
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() {
@Override
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) {
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
} }
FilterResults results = new FilterResults(); public void setMoreDataAvailable(boolean moreDataAvailable) {
results.values = filteredList;
isMoreDataAvailable = moreDataAvailable;
return results;
} }
@Override public void notifyDataChanged() {
protected void publishResults(CharSequence constraint, FilterResults results) {
milestonesList.clear(); notifyDataSetChanged();
milestonesList.addAll((List) results.values); isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Milestones> list) {
dataList = list;
notifyDataSetChanged(); 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,12 +27,11 @@ 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;
@ -46,7 +39,6 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
this.context = context; this.context = context;
this.prList = prListMain; this.prList = prListMain;
prListFull = new ArrayList<>(prList);
} }
@ -56,11 +48,11 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
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));
} }
} }
@ -68,7 +60,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
@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();
@ -77,7 +69,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
if(getItemViewType(position) == TYPE_LOAD) { if(getItemViewType(position) == TYPE_LOAD) {
((PullRequestsAdapter.PullRequestsHolder)holder).bindData(prList.get(position)); ((PullRequestsAdapter.PullRequestsHolder) holder).bindData(prList.get(position));
} }
@ -105,6 +97,10 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
class PullRequestsHolder extends RecyclerView.ViewHolder { class PullRequestsHolder extends RecyclerView.ViewHolder {
private TextView prNumber; private TextView prNumber;
private TextView prMergeable;
private TextView prHeadBranch;
private TextView prIsFork;
private TextView prForkFullName;
private ImageView assigneeAvatar; private ImageView assigneeAvatar;
private TextView prTitle; private TextView prTitle;
private TextView prCreatedTime; private TextView prCreatedTime;
@ -115,63 +111,75 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
super(itemView); super(itemView);
prNumber = itemView.findViewById(R.id.prNumber); prNumber = itemView.findViewById(R.id.prNumber);
prMergeable = itemView.findViewById(R.id.prMergeable);
prHeadBranch = itemView.findViewById(R.id.prHeadBranch);
prIsFork = itemView.findViewById(R.id.prIsFork);
prForkFullName = itemView.findViewById(R.id.prForkFullName);
assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
prTitle = itemView.findViewById(R.id.prTitle); prTitle = itemView.findViewById(R.id.prTitle);
prCommentsCount = itemView.findViewById(R.id.prCommentsCount); prCommentsCount = itemView.findViewById(R.id.prCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount); LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
prCreatedTime = itemView.findViewById(R.id.prCreatedTime); 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("prMergeable", prMergeable.getText().toString());
tinyDb.putString("prHeadBranch", prHeadBranch.getText().toString());
tinyDb.putString("prIsFork", prIsFork.getText().toString());
tinyDb.putString("prForkFullName", prForkFullName.getText().toString());
tinyDb.putString("issueType", "pr"); tinyDb.putString("issueType", "pr");
context.startActivity(intent); context.startActivity(intent);
}
}); });
frameCommentsCount.setOnClickListener(new View.OnClickListener() { frameCommentsCount.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("prMergeable", prMergeable.getText().toString());
tinyDb.putString("prHeadBranch", prHeadBranch.getText().toString());
tinyDb.putString("prIsFork", prIsFork.getText().toString());
tinyDb.putString("prForkFullName", prForkFullName.getText().toString());
tinyDb.putString("issueType", "pr"); tinyDb.putString("issueType", "pr");
context.startActivity(intent); 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 { }
else {
assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getLogin(), context)); 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 { }
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); 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);
} }
@ -179,6 +187,10 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
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()));
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())); 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));
@ -194,6 +206,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
static class LoadHolder extends RecyclerView.ViewHolder { static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) { LoadHolder(View itemView) {
super(itemView); super(itemView);
} }
@ -224,40 +237,10 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
} }
@Override public void updateList(List<PullRequests> list) {
public Filter getFilter() {
return prFilter;
}
private Filter prFilter = new Filter() { prList = list;
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<PullRequests> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(prList);
} 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(); 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,11 +47,7 @@ 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
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request request = chain.request(); Request request = chain.request();
if(connToInternet) { if(connToInternet) {
@ -62,7 +57,7 @@ public class IssuesService {
request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build(); request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build();
} }
return chain.proceed(request); return chain.proceed(request);
}
}).build(); }).build();
Retrofit.Builder builder = new Retrofit.Builder() Retrofit.Builder builder = new Retrofit.Builder()

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,14 +73,17 @@ 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;
@ -16,11 +20,8 @@ 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.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;
/** /**
@ -33,7 +34,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
@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);
@ -56,7 +57,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
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 {
@ -78,6 +79,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
} }
mergePullRequest.setOnClickListener(new View.OnClickListener() { mergePullRequest.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -88,6 +90,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
}); });
openFilesDiff.setOnClickListener(new View.OnClickListener() { openFilesDiff.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -98,6 +101,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
}); });
editIssue.setOnClickListener(new View.OnClickListener() { editIssue.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -108,6 +112,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
}); });
editLabels.setOnClickListener(new View.OnClickListener() { editLabels.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -118,6 +123,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
}); });
addRemoveAssignees.setOnClickListener(new View.OnClickListener() { addRemoveAssignees.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -132,7 +138,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
// get url of repo // get url of repo
String repoFullName = tinyDB.getString("repoFullName"); String repoFullName = tinyDB.getString("repoFullName");
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");
} }
@ -151,13 +157,14 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
}); });
copyIssueUrl.setOnClickListener(new View.OnClickListener() { copyIssueUrl.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
// get url of repo // get url of repo
String repoFullName = tinyDB.getString("repoFullName"); String repoFullName = tinyDB.getString("repoFullName");
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");
} }
@ -179,7 +186,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
if(tinyDB.getString("issueType").equals("issue")) { if(tinyDB.getString("issueType").equals("issue")) {
if (tinyDB.getString("issueState").equals("open")) { // close issue if(tinyDB.getString("issueState").equals("open")) { // close issue
reOpenIssue.setVisibility(View.GONE); reOpenIssue.setVisibility(View.GONE);
closeIssue.setVisibility(View.VISIBLE); closeIssue.setVisibility(View.VISIBLE);
@ -192,7 +199,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
}); });
} }
else if (tinyDB.getString("issueState").equals("closed")) { else if(tinyDB.getString("issueState").equals("closed")) {
closeIssue.setVisibility(View.GONE); closeIssue.setVisibility(View.GONE);
reOpenIssue.setVisibility(View.VISIBLE); reOpenIssue.setVisibility(View.VISIBLE);
@ -216,24 +223,30 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
subscribeIssue.setOnClickListener(subscribeToIssue -> { subscribeIssue.setOnClickListener(subscribeToIssue -> {
IssueActions.subscribe(ctx, subscribeIssue, unsubscribeIssue); IssueActions.subscribe(ctx);
//dismiss(); dismiss();
}); });
unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> { unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> {
IssueActions.unsubscribe(ctx, subscribeIssue, unsubscribeIssue); IssueActions.unsubscribe(ctx);
//dismiss(); dismiss();
}); });
//if RepoWatch True Provide Unsubscribe first if(new Version(tinyDB.getString("giteaVersion")).less("1.12.0")) {
// ToDo: API to check if user is subscribed to an issue (do not exist can be guessed by many api endpoints :/) subscribeIssue.setVisibility(View.GONE);
if (tinyDB.getBoolean("repoWatch")) { unsubscribeIssue.setVisibility(View.GONE);
}
else if(tinyDB.getBoolean("issueSubscribed")) {
subscribeIssue.setVisibility(View.GONE); subscribeIssue.setVisibility(View.GONE);
unsubscribeIssue.setVisibility(View.VISIBLE); unsubscribeIssue.setVisibility(View.VISIBLE);
} }
else {
subscribeIssue.setVisibility(View.VISIBLE);
unsubscribeIssue.setVisibility(View.GONE);
}
return v; 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;
@ -60,9 +59,11 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
private OnFragmentInteractionListener mListener; private OnFragmentInteractionListener mListener;
public FilesFragment() { public FilesFragment() {
} }
public static FilesFragment newInstance(String param1, String param2) { public static FilesFragment newInstance(String param1, String param2) {
FilesFragment fragment = new FilesFragment(); FilesFragment fragment = new FilesFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(repoOwnerF, param1); args.putString(repoOwnerF, param1);
@ -73,16 +74,16 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (getArguments() != null) { if(getArguments() != null) {
repoName = getArguments().getString(repoNameF); repoName = getArguments().getString(repoNameF);
repoOwner = getArguments().getString(repoOwnerF); repoOwner = getArguments().getString(repoOwnerF);
} }
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_files, container, false); View v = inflater.inflate(R.layout.fragment_files, container, false);
setHasOptionsMenu(true); setHasOptionsMenu(true);
@ -100,16 +101,13 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
mProgressBar = v.findViewById(R.id.progress_bar); mProgressBar = v.findViewById(R.id.progress_bar);
mBreadcrumbsView = v.findViewById(R.id.breadcrumbs_view); mBreadcrumbsView = v.findViewById(R.id.breadcrumbs_view);
mBreadcrumbsView.setItems(new ArrayList<>(Arrays.asList( mBreadcrumbsView.setItems(new ArrayList<>(Arrays.asList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot)))));
BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot))
)));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
@ -118,10 +116,12 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
} }
private static BreadcrumbItem createItem(String title) { private static BreadcrumbItem createItem(String title) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
list.add(title); list.add(title);
return new BreadcrumbItem(list); return new BreadcrumbItem(list);
@ -148,6 +148,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
mBreadcrumbsView.addItem(createItem(dirName)); mBreadcrumbsView.addItem(createItem(dirName));
//noinspection unchecked //noinspection unchecked
mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() { mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@Override @Override
public void onNavigateBack(BreadcrumbItem item, int position) { public void onNavigateBack(BreadcrumbItem item, int position) {
@ -185,7 +186,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
if(!fileStructure.getText().toString().equals("Root")) { if(!fileStructure.getText().toString().equals("Root")) {
intent.putExtra("singleFileName", fileStructure.getText().toString()+"/"+fileName); intent.putExtra("singleFileName", fileStructure.getText().toString() + "/" + fileName);
} }
else { else {
@ -203,8 +204,10 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class);
filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer<List<Files>>() { filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer<List<Files>>() {
@Override @Override
public void onChanged(@Nullable List<Files> filesListMain) { public void onChanged(@Nullable List<Files> filesListMain) {
adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this); adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this);
mBreadcrumbsView.removeItemAfter(1); mBreadcrumbsView.removeItemAfter(1);
@ -236,8 +239,10 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class); FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class);
filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, getContext()).observe(this, new Observer<List<Files>>() { filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, getContext()).observe(this, new Observer<List<Files>>() {
@Override @Override
public void onChanged(@Nullable List<Files> filesListMain2) { public void onChanged(@Nullable List<Files> filesListMain2) {
adapter = new FilesAdapter(getContext(), filesListMain2, FilesFragment.this); adapter = new FilesAdapter(getContext(), filesListMain2, FilesFragment.this);
if(adapter.getItemCount() > 0) { if(adapter.getItemCount() > 0) {
mRecyclerView.setVisibility(View.VISIBLE); mRecyclerView.setVisibility(View.VISIBLE);
@ -262,28 +267,24 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
@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()));
inflater.inflate(R.menu.search_menu, menu); inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
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.search));
/*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) { if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText); adapter.getFilter().filter(newText);
} }
@ -294,18 +295,23 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
} }
public void onButtonPressed(Uri uri) { public void onButtonPressed(Uri uri) {
if (mListener != null) {
if(mListener != null) {
mListener.onFragmentInteraction(uri); mListener.onFragmentInteraction(uri);
} }
} }
@Override @Override
public void onDetach() { public void onDetach() {
super.onDetach(); super.onDetach();
mListener = null; mListener = null;
} }
public interface OnFragmentInteractionListener { public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri); void onFragmentInteraction(Uri uri);
} }
} }

View File

@ -1,305 +0,0 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
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));
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());
}
});
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,302 +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.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));
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());
}
});
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(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
mProgressBar = v.findViewById(R.id.progress_bar);
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);
dataList = new ArrayList<>();
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, tinyDb.getString("milestoneState"));
} }
}));
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) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
} }
private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String milestoneState) {
Call<List<Milestones>> call = api.getMilestones(token, repoOwner, repoName, 1, resultLimit, milestoneState);
call.enqueue(new Callback<List<Milestones>>() {
@Override @Override
public void onDetach() { public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull Response<List<Milestones>> response) {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener { if(response.isSuccessful()) {
void onFragmentInteraction(Uri uri);
}
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { assert response.body() != null;
if(response.body().size() > 0) {
MilestonesViewModel msModel = new ViewModelProvider(this).get(MilestonesViewModel.class); dataList.clear();
dataList.addAll(response.body());
adapter.notifyDataChanged();
viewBinding.noDataMilestone.setVisibility(View.GONE);
msModel.getMilestonesList(instanceUrl, instanceToken, owner, repo, msState, getContext()).observe(getViewLifecycleOwner(), new Observer<List<Milestones>>() {
@Override
public void onChanged(@Nullable List<Milestones> msListMain) {
adapter = new MilestonesAdapter(getContext(), msListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataMilestone.setVisibility(View.GONE);
} }
else { else {
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter); dataList.clear();
noDataMilestone.setVisibility(View.VISIBLE); adapter.notifyDataChanged();
viewBinding.noDataMilestone.setVisibility(View.VISIBLE);
} }
mProgressBar.setVisibility(View.GONE);
viewBinding.progressBar.setVisibility(View.GONE);
} }
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());
}
}); });
} }
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,17 +44,17 @@ import retrofit2.Response;
public class PullRequestsFragment extends Fragment { public class PullRequestsFragment extends Fragment {
private Menu menu;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
private RecyclerView recyclerView; private RecyclerView recyclerView;
private List<PullRequests> prList; private List<PullRequests> prList;
private PullRequestsAdapter adapter; private PullRequestsAdapter adapter;
private ApiInterface apiPR; private ApiInterface apiPR;
private String TAG = "PullRequestsListFragment - "; private String TAG = StaticGlobalVariables.tagPullRequestsList;
private Context context; private Context context;
private int pageSize = 1; private int pageSize = StaticGlobalVariables.prPageInit;
private TextView noData; private TextView noData;
private String prState = "open"; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private int resultLimit = 50;
@Nullable @Nullable
@Override @Override
@ -60,10 +62,10 @@ public class PullRequestsFragment extends Fragment {
final View v = inflater.inflate(R.layout.fragment_pull_requests, container, false); final View v = inflater.inflate(R.layout.fragment_pull_requests, container, false);
setHasOptionsMenu(true); setHasOptionsMenu(true);
context = getContext();
TinyDB tinyDb = new TinyDB(getContext()); TinyDB tinyDb = new TinyDB(getContext());
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
//Log.i("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];
@ -73,63 +75,78 @@ public class PullRequestsFragment extends Fragment {
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
context = getContext(); // 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); recyclerView = v.findViewById(R.id.recyclerView);
prList = new ArrayList<>(); prList = new ArrayList<>();
mProgressBar = v.findViewById(R.id.progress_bar); mProgressBar = v.findViewById(R.id.progress_bar);
noData = v.findViewById(R.id.noData); noData = v.findViewById(R.id.noData);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false); swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, pageSize, prState, resultLimit); loadInitial(instanceToken, repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit);
adapter.notifyDataChanged(); adapter.notifyDataChanged();
} }, 200));
}, 200);
}
});
adapter = new PullRequestsAdapter(getContext(), prList); adapter = new PullRequestsAdapter(getContext(), prList);
adapter.setLoadMoreListener(new PullRequestsAdapter.OnLoadMoreListener() { adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
@Override
public void onLoadMore() {
recyclerView.post(new Runnable() { if(prList.size() == 10 || pageSize == resultLimit) {
@Override
public void run() {
if(prList.size() == 10 || pageSize == 10) {
int page = (prList.size() + 10) / 10; int page = (prList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, prState, resultLimit); loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit);
} }
/*else {
Toasty.info(context, getString(R.string.noMoreData)); }));
}*/ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
}
});
}
});
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
DividerItemDecoration.VERTICAL);
recyclerView.setHasFixedSize(true); recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(dividerItemDecoration); recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
apiPR = PullRequestsService.createService(ApiInterface.class, instanceUrl, getContext()); ((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListenerPr(prState -> {
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit);
if(prState.equals("closed")) {
menu.getItem(1).setIcon(R.drawable.ic_filter_closed);
}
else {
menu.getItem(1).setIcon(R.drawable.ic_filter);
}
prList.clear();
adapter = new PullRequestsAdapter(context, prList);
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
if(prList.size() == 10 || pageSize == resultLimit) {
int page = (prList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit);
}
}));
tinyDb.putString("repoPrState", prState);
mProgressBar.setVisibility(View.VISIBLE);
noData.setVisibility(View.GONE);
loadInitial(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit);
recyclerView.setAdapter(adapter);
});
apiPR = AppApiService.createService(ApiInterface.class, instanceUrl, context);
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit);
return v; return v;
@ -149,7 +166,7 @@ public class PullRequestsFragment extends Fragment {
if(tinyDb.getBoolean("resumePullRequests")) { if(tinyDb.getBoolean("resumePullRequests")) {
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit); loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit);
tinyDb.putBoolean("resumePullRequests", false); tinyDb.putBoolean("resumePullRequests", false);
tinyDb.putBoolean("prMerged", false); tinyDb.putBoolean("prMerged", false);
@ -166,7 +183,7 @@ public class PullRequestsFragment extends Fragment {
@Override @Override
public void onResponse(@NonNull Call<List<PullRequests>> call, @NonNull Response<List<PullRequests>> response) { public void onResponse(@NonNull Call<List<PullRequests>> call, @NonNull Response<List<PullRequests>> response) {
if(response.isSuccessful()) { if(response.code() == 200) {
assert response.body() != null; assert response.body() != null;
if(response.body().size() > 0) { if(response.body().size() > 0) {
@ -178,22 +195,35 @@ public class PullRequestsFragment extends Fragment {
} }
else { else {
prList.clear(); prList.clear();
adapter.notifyDataChanged(); adapter.notifyDataChanged();
noData.setVisibility(View.VISIBLE); noData.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
} }
Log.i("http", String.valueOf(response.code())); mProgressBar.setVisibility(View.GONE);
}
else if(response.code() == 404) {
noData.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
Log.i(TAG, String.valueOf(response.code()));
} }
@Override @Override
public void onFailure(@NonNull Call<List<PullRequests>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<PullRequests>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString()); Log.e(TAG, t.toString());
} }
@ -201,7 +231,7 @@ public class PullRequestsFragment extends Fragment {
} }
private void loadMore(String token, String repoOwner, String repoName, int page, String prState, int resultLimit){ private void loadMore(String token, String repoOwner, String repoName, int page, String prState, int resultLimit) {
//add loading progress view //add loading progress view
prList.add(new PullRequests("load")); prList.add(new PullRequests("load"));
@ -214,10 +244,10 @@ public class PullRequestsFragment extends Fragment {
@Override @Override
public void onResponse(@NonNull Call<List<PullRequests>> call, @NonNull Response<List<PullRequests>> response) { public void onResponse(@NonNull Call<List<PullRequests>> call, @NonNull Response<List<PullRequests>> response) {
if(response.isSuccessful()){ if(response.code() == 200) {
//remove loading view //remove loading view
prList.remove(prList.size()-1); prList.remove(prList.size() - 1);
List<PullRequests> result = response.body(); List<PullRequests> result = response.body();
@ -259,31 +289,36 @@ public class PullRequestsFragment extends Fragment {
@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_pr, menu);
super.onCreateOptionsMenu(menu, inflater); 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); 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) {
adapter.getFilter().filter(newText); filter(newText);
return false; return false;
} }
@ -292,4 +327,17 @@ public class PullRequestsFragment extends Fragment {
} }
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

@ -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,15 +26,8 @@ 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);
@ -43,7 +37,6 @@ public class AlertDialogs {
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)
}
}
}

View File

@ -0,0 +1,112 @@
package org.mian.gitnex.helpers.highlightjs;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import org.mian.gitnex.helpers.highlightjs.models.Language;
import org.mian.gitnex.helpers.highlightjs.models.Theme;
import org.mian.gitnex.helpers.highlightjs.utils.SourceUtils;
/**
* This Class was created by Patrick J
* on 09.06.16. (modified by opyale)
*/
public class HighlightJsView extends WebView {
private Language language = Language.AUTO_DETECT;
private Theme theme = Theme.DEFAULT;
private boolean zoomSupport = false;
private boolean showLineNumbers = true;
private TextWrap textWrap = TextWrap.NO_WRAP;
public HighlightJsView(Context context) {
super(context);
setup();
}
public HighlightJsView(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public HighlightJsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setup();
}
@SuppressLint("SetJavaScriptEnabled")
private void setup() {
WebSettings settings = getSettings();
settings.setJavaScriptEnabled(true);
settings.setBuiltInZoomControls(true);
settings.setSupportZoom(zoomSupport);
settings.setDisplayZoomControls(false);
setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
}
private void changeZoomSettings(boolean enable) {
this.zoomSupport = enable;
getSettings().setSupportZoom(enable);
}
public void setSource(String source) {
source = (source == null) ? " " : source;
String html_content = SourceUtils.generateContent(source, theme.getName(), language.getName(), zoomSupport, showLineNumbers, textWrap);
loadDataWithBaseURL("file:///android_asset/", html_content, "text/html", "utf-8", null);
}
public void refresh() {
super.reload();
}
public void setHighlightLanguage(Language language) {
this.language = language;
}
public void setTheme(Theme theme) {
this.theme = theme;
}
public void setTextWrap(TextWrap textWrap) {
this.textWrap = textWrap;
}
public Language getHighlightLanguage() {
return language;
}
public Theme getTheme() {
return theme;
}
public void setZoomSupportEnabled(boolean supportZoom) {
changeZoomSettings(supportZoom);
}
public void setShowLineNumbers(boolean showLineNumbers) {
this.showLineNumbers = showLineNumbers;
}
public enum TextWrap {
NO_WRAP, WORD_WRAP, BREAK_ALL
}
}

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