Compare commits

...

174 Commits

Author SHA1 Message Date
5999b8ed4a Release 2.2.2 (#170) 2019-10-25 05:44:53 +00:00
2cba285076 Merge branch 'backport_162' of gitnex/GitNex into release-2.2 2019-10-21 17:31:44 +00:00
24a552f0a9 Fix login with email for my repositories 2019-10-21 18:57:52 +02:00
d9a7fa4e44 Merge branch 'bugfix-release-2.2.1' of gitnex/GitNex into release-2.2 2019-10-18 14:55:15 +00:00
9950d4ea65 prepare release 2.2.1 2019-10-18 19:51:56 +05:00
98054b89cc Merge branch 'fix-empty-repo-bug' of gitnex/GitNex into release-2.2 2019-10-18 13:47:00 +00:00
24d56c625e Fix #154 2019-10-18 18:40:54 +05:00
5970995ef0 added file viewer 2019-10-18 10:28:18 +05:00
cf75c61704 release 2.2.0 2019-10-18 10:10:47 +05:00
8ac92a8b3c Merge branch '121-sub-dir-browsing' of gitnex/GitNex into master 2019-10-17 22:49:49 +00:00
f1f92ba494 make CI work 2019-10-18 00:46:19 +02:00
d7b1a226d0 implemented sub dir view 2019-10-17 22:47:27 +05:00
2bebe1e81d Merge branch 'crowdin_2019-10-17' of gitnex/GitNex into master 2019-10-17 15:54:59 +00:00
f5d560c601 Update Crowdin 2019-10-17 16:09:40 +02:00
d27000d481 Merge branch 'minor-fixes' of gitnex/GitNex into master 2019-10-17 13:57:55 +00:00
9aff1cb42a Minor ui fixes 2019-10-16 18:28:24 +05:00
7fe376fa44 Merge branch 'improve-ci' of gitnex/GitNex into master 2019-10-14 10:02:31 +00:00
6da4398369 dont run with empty task 2019-10-14 11:27:04 +02:00
dac0f690d8 more precise name 2019-10-14 11:06:46 +02:00
8a7031e7f5 Merge branch 'translation_add-Serbian' of 6543/GitNex into master 2019-10-14 05:11:31 +00:00
dd5f17d54d format code 2019-10-13 19:19:44 +02:00
505c930c32 first sr strings 2019-10-13 19:19:20 +02:00
edb6cdf154 add Serbian to Settings 2019-10-13 19:19:04 +02:00
687b66751f Merge branch 'crowdin_2019-10-13' of gitnex/GitNex into master 2019-10-13 12:51:24 +00:00
f14ae18324 Merge branch 'translation_add-Italian' of 6543/GitNex into master 2019-10-13 12:50:46 +00:00
ea52d6c6d2 dont run twice 2019-10-13 02:46:52 +02:00
40d12c3b97 Update Translation 2019-10-13 02:13:53 +02:00
32ebf31ef4 add first it strings 2019-10-13 02:08:46 +02:00
7fc4146c98 add Italian 2019-10-13 02:08:27 +02:00
e296a83aab Merge branch 'update-libs' of gitnex/GitNex into master 2019-10-12 17:13:43 +00:00
0fc7c67d0b update libs 2019-10-12 19:34:33 +05:00
143d680627 Merge branch '136-watch-a-repo' of gitnex/GitNex into master 2019-10-12 13:29:43 +00:00
69745b027e Implemented watch and unwatch a repository 2019-10-12 14:00:36 +05:00
7f3aed9bae fix star repo layout 2019-10-12 12:55:12 +05:00
5496401a77 Merge branch '130-star-a-repo' of gitnex/GitNex into master 2019-10-11 20:18:15 +00:00
4c0fd3c286 Implemented star/unstar a repository 2019-10-12 01:03:01 +05:00
40f924de2e Merge branch 'translation_add-Finnish' of 6543/GitNex into master 2019-10-11 19:24:49 +00:00
1953a9feff add Finnish 2019-10-11 20:14:59 +02:00
24c71b4beb Merge branch 'drone-rename-pipeline' of gitnex/GitNex into master 2019-10-11 18:08:52 +00:00
958606e476 add first strings 2019-10-11 20:07:50 +02:00
39d1007423 Drone Rename Pipeline
Rename Pipeline -> it does not loon nice and does not make sense
2019-10-11 18:02:40 +00:00
0e673bb256 Merge branch 'mentions' of 6543/GitNex into master 2019-10-11 16:53:11 +00:00
246ff6296a new line " " and italic 2019-10-11 18:34:22 +02:00
1d0b940c14 add sugestions + new translator 2019-10-11 18:15:19 +02:00
4d3fb54925 Merge branch 'lunny/add_ci_badge' of lunny/GitNex into master 2019-10-11 15:44:36 +00:00
cd81ff74bf add mentions 2019-10-11 16:57:53 +02:00
02843b4ca1 Add CI status badge on README 2019-10-11 13:15:05 +00:00
2189bd10bd Merge branch '100-bottomsheet-scroll' of gitnex/GitNex into master 2019-10-11 13:08:57 +00:00
35b9647709 improve bottomsheet with scroll and separater 2019-10-11 16:36:42 +05:00
2d2f486182 Merge branch '88-update-images' of gitnex/GitNex into master 2019-10-10 19:54:37 +00:00
640771d4fa update store images, update app description 2019-10-10 22:38:09 +05:00
2ba8a80b9f Merge branch 'repoSearch' of 6543/GitNex into master 2019-10-10 16:02:04 +00:00
2f55e7f5d1 enable to browse repository 2019-10-10 20:49:12 +05:00
d285115090 reset the adapter on new query 2019-10-10 19:01:15 +05:00
d5cffddc72 Implemented search ui and screen for exploring repositories. 2019-10-10 18:40:43 +05:00
9e2921697b Merge branch 'add-drone-ci' of gitnex/GitNex into master 2019-10-10 07:49:12 +00:00
e868364554 Merge branch 'crowdin_2019-10-10' of gitnex/GitNex into master 2019-10-10 07:48:27 +00:00
88a8303b1c Add Drone CI Config
* testing
       - test
       - build
2019-10-10 03:29:35 +02:00
ac1fc696ea complete france translation 2019-10-10 01:40:54 +02:00
2fe175223c combine commits
* add Explore Function
* define API
* Add Fragment + Code + String
* add to main activity (by @mmarif)
2019-10-10 01:21:34 +02:00
9cab502e84 Merge branch 'mv-org-update-links' of 6543/GitNex into master 2019-10-09 18:40:12 +00:00
88748998b3 update repo links 2019-10-09 16:09:07 +02:00
264ed393cb Merge branch 'readme-add-crowdin' of 6543/GitNex into master 2019-10-08 15:27:27 +00:00
821eef91a3 Merge branch 'crowdin_2019-10-07' of mmarif/GitNex into master 2019-10-08 15:26:56 +00:00
05afc9fc5a Merge branch 'crowdin-add-Persian' of 6543/GitNex into master 2019-10-08 15:26:18 +00:00
4cb6948288 Merge branch 'build-fix' of mmarif/GitNex into master 2019-10-08 14:48:28 +00:00
7012c2587c crowdin update 2019-10-08 02:54:18 +02:00
dbcbd076ea Build Fix 2019-10-08 02:41:39 +02:00
c633b62fdb show screenshots directly 2019-10-07 19:53:41 +02:00
1ce1a15955 mv Translation info (CONTRIBUTE -> README)
wil close https://gitea.com/mmarif/GitNex/issues/108
2019-10-07 19:53:30 +02:00
60b95e3c5d Add first Persian strings
got it from 243e53895b
2019-10-07 12:42:15 +02:00
48fb0cf91c add Persian to settings 2019-10-07 12:41:27 +02:00
8fcb05b0d2 Merge branch 'fixes' of mmarif/GitNex into master 2019-10-07 07:05:36 +00:00
074bbfe3cc Minor translation files fixes 2019-10-07 12:01:04 +05:00
84438b740a Merge branch '43-file-browser' of mmarif/GitNex into master 2019-10-07 06:32:42 +00:00
d4cd16a111 Merge branch 'master' into 43-file-browser 2019-10-07 11:26:24 +05:00
5ed053bba7 Merge branch 'crowdin-add-zh-CN' of mmarif/GitNex into master 2019-10-07 06:05:50 +00:00
598633a20a add first Chinese strings
@lunny thanks
2019-10-06 06:04:00 +02:00
8fe53dfd01 Settings: Languages: add Chinese and sort alphabetic 2019-10-06 06:01:48 +02:00
aadbcbd0c6 Merge branch 'crowdin-add-ar' into master 2019-10-04 19:25:53 +00:00
e3b901741a Add Untranslated Arabic 2019-10-04 20:56:29 +02:00
f8275cd7aa add Arabic to settings 2019-10-04 20:56:28 +02:00
c3afe1044c Merge branch 'crowdin' into master 2019-10-04 18:43:45 +00:00
a6503ba7c4 Crowdin Update 2019-10-04 20:26:20 +02:00
dddc9b0178 smal link fix for Translation 2019-10-04 20:24:44 +02:00
13bc50da40 git ignore crowdin config (crowdin.yml) 2019-10-04 20:23:43 +02:00
b32d291554 Merge branch 'translation-tool' of 6543/GitNex into master 2019-10-04 15:56:43 +00:00
c15e6e99f7 Added Arabic file 2019-10-04 20:46:56 +05:00
1512032f05 move corwdin Link to strings 2019-10-04 17:44:38 +02:00
e32ccde995 add info if lang is not listed 2019-10-04 16:55:09 +02:00
1be577cd3f add ClickListener to open Translation URL 2019-10-04 16:25:27 +02:00
7fa57621d9 change about layout 2019-10-04 16:20:46 +02:00
75ac6ff113 Add Crowdin Badge 2019-10-04 16:08:40 +02:00
9ef04b1287 change CONTRIBUTING.md for Crowdin 2019-10-04 16:08:17 +02:00
8c903b9658 remove some comments 2019-10-04 12:23:56 +05:00
08b8275546 translation files updates 2019-10-04 12:08:21 +05:00
5baacbd801 revert back 2019-10-04 00:21:34 +05:00
56b8b486df Merge branch 'release-2.1' into 43-file-browser 2019-10-04 00:06:03 +05:00
7abfdc9567 Merge branch 'fix-old-gitea-api' of mmarif/GitNex into release-2.1 2019-10-03 19:03:06 +00:00
0ab8784a7a another quick release and another old Gitea instances issue 2019-10-04 00:00:05 +05:00
e4ab2f64fc wip, need clean up 2019-10-03 23:50:57 +05:00
345d577fbf Merge branch 'release-2.1' into 43-file-browser 2019-10-03 21:53:38 +05:00
22b3802e73 Merge branch 'fixes-2.1.2' of mmarif/GitNex into release-2.1 2019-10-03 16:45:36 +00:00
07a1fa6aad Fix crashes on my repo, starred repos etc - 2.1.2 release 2019-10-03 21:43:33 +05:00
5c9b53f5ab api interface for sub dirs
Signed-off-by: M M Arif <mmarif@swatian.com>
2019-10-03 21:32:09 +05:00
572f93d35c Idea to use breadcrumb 2019-10-03 20:57:49 +05:00
a77716970b update gradle 2019-10-03 12:15:55 +05:00
4d998150a3 click listener checks for file, dir and unknwon files 2019-10-02 23:32:01 +05:00
90df3a31fe Merge branch 'release-2.1' into 43-file-browser 2019-10-02 22:47:46 +05:00
4904b5899f Merge branch 'fixes-2.1' of mmarif/GitNex into release-2.1 2019-10-02 17:26:30 +00:00
f19327431f fix bugs since 2.1.0 release 2019-10-02 22:24:02 +05:00
0bcbca8bdc Fix crash from gplay console, app crash when no avatar url node is present in API. old gitea instances. 2019-10-02 22:11:10 +05:00
b90b3c3320 Added reading file contentts 2019-10-02 21:32:59 +05:00
21097da995 filter files and dirs 2019-10-02 18:21:44 +05:00
06b71586c1 Sort by folder 1st approach 2019-10-02 17:58:29 +05:00
d2213c0c14 new file icon 2019-10-02 13:59:34 +05:00
4c3b735534 translation updates 2019-10-02 13:35:14 +05:00
90dce6fff8 added layout, view models, adapter and fragment 2019-10-02 13:30:07 +05:00
d9337a24d3 Fixes since 2.1.0 release, ms progress bar fix, create issue enable fix 2019-10-01 22:45:21 +05:00
45ec660ba1 Merge branch 'master' into 43-file-browser 2019-10-01 21:23:03 +05:00
8b26355fc0 Merge branch 'prepare-release' of mmarif/GitNex into master 2019-10-01 15:35:05 +00:00
8effad46f8 app release 2.1.0 2019-10-01 20:31:01 +05:00
bb24254e66 added files model 2019-10-01 20:07:37 +05:00
13e69cd09b files tab in repo tabs 2019-10-01 19:48:20 +05:00
71839bcfd6 clean up 2019-10-01 19:35:51 +05:00
53efd8b777 Merge branch '79-repo-avatar' of mmarif/GitNex into master 2019-10-01 13:59:59 +00:00
19cd5b6c5e added repos avatars 2019-10-01 18:56:20 +05:00
69082b424a Merge branch '54-enable-disable-create-issue' of mmarif/GitNex into master 2019-10-01 13:07:58 +00:00
d8b3477940 check if repo issues is enalbed or disabled 2019-10-01 18:05:09 +05:00
34892e7f43 Merge branch 'fix-ms-bar' of mmarif/GitNex into master 2019-10-01 10:26:03 +00:00
d64b035d4a fix ms progress bar 2019-10-01 15:23:49 +05:00
e2fa79b2a9 Merge branch 'master' of gitea.com:mmarif/GitNex 2019-10-01 15:06:46 +05:00
9e658aa38c 63-ms-ui (#82) 2019-10-01 10:05:26 +00:00
e4700ffd69 Merge branch 'master' of gitea.com:mmarif/GitNex 2019-10-01 11:44:45 +05:00
e53ef41fc1 ui-improvements (#81) 2019-10-01 06:42:56 +00:00
c05e69cfe9 t 2019-10-01 10:23:50 +05:00
5c6d5177fb r 2019-10-01 10:14:54 +05:00
62a5452437 Merge branch 'master' of gitea.com:mmarif/GitNex
# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java
#	app/src/main/java/org/mian/gitnex/activities/MainActivity.java
#	app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/MembersByOrgAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/ProfileFollowersAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/ProfileFollowingAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/RepositoriesByOrgAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/StarredReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java
#	app/src/main/java/org/mian/gitnex/fragments/OrganizationInfoFragment.java
#	app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java
#	app/src/main/res/layout/activity_issue_detail.xml
#	app/src/main/res/layout/admin_users_list.xml
#	app/src/main/res/layout/fragment_profile.xml
#	app/src/main/res/layout/issue_comments.xml
#	app/src/main/res/layout/my_repos_list.xml
#	app/src/main/res/layout/nav_header.xml
#	app/src/main/res/layout/organizations_list.xml
#	app/src/main/res/layout/profile_followers_list.xml
#	app/src/main/res/layout/profile_following_list.xml
#	app/src/main/res/layout/repos_list.xml
#	app/src/main/res/layout/repositories_by_org_list.xml
#	app/src/main/res/layout/starred_repos_list.xml
2019-10-01 10:14:45 +05:00
5f402c2c60 merge 2019-10-01 10:12:18 +05:00
85140fbee0 Merge branch '77-ui-changes' of mmarif/GitNex into master 2019-09-30 18:16:24 +00:00
d350fe96d9 Merge branch 'master' into 77-ui-changes 2019-09-30 23:14:04 +05:00
61a1a4446f Merge branch '62-improve-issues-ui' of mmarif/GitNex into master 2019-09-30 18:09:47 +00:00
c1e27c9776 Merge branch 'issue-copy-nr' of 6543/GitNex into master 2019-09-30 18:07:25 +00:00
03ec591643 more ui changes 2019-09-30 22:48:52 +05:00
3ebc1ae3e0 avatars improvements 2019-09-30 22:39:33 +05:00
3c8fb5bc60 markdown code cleanup 2019-09-30 21:21:51 +05:00
5503fe9951 Redid the issues list ui and some clean up 2019-09-30 21:12:45 +05:00
7f417da6b3 update libs, switch to io.notis for md. refactor all the markdown code 2019-09-29 21:44:42 +05:00
4e8a961643 copyIssue -> copyIssueUrl 2019-09-29 00:56:48 +02:00
bf5527a82d issue -> issueUrl 2019-09-29 00:10:28 +02:00
c31cf53023 Merge branch 'milestoneProgress' of 6543/GitNex into master 2019-09-28 18:15:41 +00:00
0ac2a27549 all milestones look similar 2019-09-27 23:58:23 +02:00
dcabfa4f14 add Progress Bar function 2019-09-27 23:32:31 +02:00
9688c75106 add progress bar to layout 2019-09-27 22:52:29 +02:00
71bb8cc75d add copy function 2019-09-27 21:17:28 +02:00
dcd28e845a add Copy to Clipboard String 2019-09-27 19:12:19 +02:00
b3e88b0a9d add content copy icon 2019-09-27 18:50:05 +02:00
ce67f59753 Merge branch '67-filter-icon' of mmarif/GitNex into master 2019-09-26 19:09:16 +00:00
d0b6730de4 change search icon/text to filter 2019-09-26 23:58:36 +05:00
f5e18ed5cc Merge branch 'dl-apk-buton' of 6543/GitNex into master 2019-09-23 18:38:31 +00:00
88394e1c25 Merge branch 'translate_german' of IndeedNotJames/GitNex into master 2019-09-23 18:19:01 +00:00
a9030eb8c9 Bump requred Gitea Version 2019-09-22 18:05:54 +02:00
fff307d45a test look 2019-09-22 17:48:41 +02:00
b64ee37edd add release badge 2019-09-22 17:40:18 +02:00
b4b3c2f5ee add download apk sing from website 2019-09-22 16:49:07 +02:00
8f3ef29f44 complete german translation 2019-09-21 20:50:33 +02:00
d00691d71b Merge branch 'new-font-testing' of mmarif/GitNex into master 2019-09-19 06:35:28 +00:00
4867524b4f Merge branch 'master' into new-font-testing 2019-09-19 11:28:07 +05:00
a59e818aa2 Merge branch 'master' into new-font-testing 2019-09-19 11:27:09 +05:00
aeca4a0edb Merge branch 'fix-open-issue-tab' of mmarif/GitNex into master 2019-09-19 06:22:57 +00:00
2c60f092f1 Fix open issues tab color bug, dim color for info tab headers 2019-09-19 11:21:15 +05:00
fe0b3a77cc Merge branch 'minor-enhancements' of mmarif/GitNex into master 2019-09-19 05:38:26 +00:00
43c014948a Repo label and info tabs fixes 2019-09-19 10:36:55 +05:00
a497e0a284 new font 2019-09-19 10:10:12 +05:00
168 changed files with 6909 additions and 1766 deletions

31
.drone.yml Normal file
View File

@ -0,0 +1,31 @@
---
kind: pipeline
name: gitnex-ci-test
steps:
- name: test
image: nextcloudci/android:android-49
commands:
- ./gradlew test
trigger:
event:
- pull_request
---
kind: pipeline
name: gitnex-ci-build
steps:
- name: build
image: nextcloudci/android:android-49
commands:
- ./gradlew build
trigger:
event:
- push
branch:
- master

3
.gitignore vendored
View File

@ -180,6 +180,9 @@ crashlytics.properties
crashlytics-build.properties
fabric.properties
# Crowdin
crowdin.yml
### AndroidStudio Patch ###
!/gradle/wrapper/gradle-wrapper.jar

View File

@ -1,2 +1,2 @@
# Changelog
[Check out the release notes](https://gitea.com/mmarif/GitNex/releases)
[Check out the release notes](https://gitea.com/gitnex/GitNex/releases)

View File

@ -20,10 +20,3 @@ Before creating an issue please take a moment and search the repository issues(o
In case you want to submit a bug report, please provide as much details as possible to better debug the problem. The important part is how to reproduce the bug and steps to reproduce are appreciated.
**Note:** Please contact the project directly via email(gitnex@swatian.com) if have to share sensitive and security related details.
## Translation
Help us translate GitNex to your native language.
Take a look [here](https://gitea.com/mmarif/GitNex/src/branch/master/app/src/main/res/values/strings.xml) for strings, please ignore the lines with `translatable="false"`. It is recommended to create a Pull Request with your changes.
Check the structure of other languages for example [French](https://gitea.com/mmarif/GitNex/src/branch/master/app/src/main/res/values-fr/strings.xml).

22
CONTRIBUTORS.md Normal file
View File

@ -0,0 +1,22 @@
# Contributors
This part lists all PUBLIC individuals having contributed content to the code.
* M M Arif (mmarif)
* 6543
# Translators
This part lists all PUBLIC individuals having contributed content to the translation.
*Entries are in alphabetical order*
* 6543
* ButterflyOfFire (BoFFire)
* IndeedNotJames
* Lunny Xiao (xiaolunwen)
* mmarif
* Nadezhda Moiseeva (digitalkiller)
* PsychotherapistSam
* Rodion Borisov (vintproykt)
* valeriezhao1013
* Voyvode
**Thank you for all your work** :+1:

View File

@ -1,6 +1,10 @@
[![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)
[<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"/>](https://liberapay.com/mmarif/donate)
[<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)
# GitNex - Android client for Gitea
@ -10,12 +14,14 @@ GitNex is licensed under GPLv3 License. See the LICENSE file for the full licens
No trackers are used and source code is available here for anyone to audit.
## Downloads
[<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/) [<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex) [Download APK](https://gitea.com/mmarif/GitNex/releases)
[<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='Download APK' src='https://gitnex.com/img/download-apk.png' height="80"/>](https://gitea.com/gitnex/GitNex/releases)
## Note about Gitea version
Please make sure that you are on Gitea **1.7.x** stable release or later. Below this may not work as one would expect because of the newly added objects to the API at later versions. Please consider updating your Gitea server.
Please make sure that you are on Gitea **1.9.x** stable release or later. Below this may not work as one would expect because of the newly added objects to the API at later versions. Please consider updating your Gitea server.
Check the versions [compatibility page](https://gitea.com/mmarif/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio.
Check the versions [compatibility page](https://gitea.com/gitnex/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio.
## Build from source
Option 1 - Download the source code, open it in Android Studio and build it there.
@ -29,25 +35,37 @@ Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew build`
- Create repository
- Create organization
- Issues list
- [MANY MORE](https://gitea.com/mmarif/GitNex/wiki/Features)
- [MANY MORE](https://gitea.com/gitnex/GitNex/wiki/Features)
## Contributing
[CONTRIBUTING](https://gitea.com/mmarif/GitNex/src/branch/master/CONTRIBUTING.md)
[CONTRIBUTING](https://gitea.com/gitnex/GitNex/src/branch/master/CONTRIBUTING.md)
## Translation
Help us translate GitNex to your native language.
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.
**Link: https://crowdin.com/project/GitNex**
## Screenshots:
[Screenshots](https://gitea.com/mmarif/GitNex/src/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots)
<img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/001.png" alt="001.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/002.png" alt="002.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/003.png" alt="003.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/004.png" alt="004.png" width="200"/>
---|---|---|---
<img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/005.png" alt="005.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/006.png" alt="006.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/007.png" alt="007.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/008.png" alt="008.png" width="200"/>
## FAQ
[Faq](https://gitea.com/mmarif/GitNex/wiki/FAQ)
[Faq](https://gitea.com/gitnex/GitNex/wiki/FAQ)
## Links
[Website](https://gitnex.com)
[Wiki](https://gitea.com/mmarif/GitNex/wiki/Home)
[Wiki](https://gitea.com/gitnex/GitNex/wiki/Home)
[Website Repository](https://gitlab.com/mmarif4u/gitnex-website)
[Troubleshoot Guide](https://gitea.com/mmarif/GitNex/wiki/Troubleshoot-Guide)
[Troubleshoot Guide](https://gitea.com/gitnex/GitNex/wiki/Troubleshoot-Guide)
## Thanks
Thanks to all the open source libraries, contributors and donators.
@ -65,5 +83,6 @@ Open source libraries
- Abumoallim/android-multi-select-dialog
- Pes/materialcolorpicker
- Hendraanggrian/socialview
- Fython/BreadcrumbsView
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)

View File

@ -6,8 +6,8 @@ android {
applicationId "org.mian.gitnex"
minSdkVersion 21
targetSdkVersion 28
versionCode 55
versionName "2.0.0"
versionCode 72
versionName "2.2.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@ -23,12 +23,12 @@ android {
}
dependencies {
def lifecycle_version = "2.2.0-alpha04"
final def markwon_version = "3.0.0"
def lifecycle_version = "2.2.0-beta01"
final def markwon_version = "4.1.1"
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0-alpha10'
implementation 'com.google.android.material:material:1.1.0-beta01'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
@ -47,21 +47,27 @@ dependencies {
implementation "com.vdurmont:emoji-java:4.0.0"
implementation "com.pes.materialcolorpicker:library:1.2.5"
implementation "ru.noties.markwon:core:$markwon_version"
implementation "ru.noties.markwon:ext-strikethrough:$markwon_version"
implementation "ru.noties.markwon:ext-tables:$markwon_version"
implementation "ru.noties.markwon:ext-tasklist:$markwon_version"
implementation "ru.noties.markwon:syntax-highlight:$markwon_version"
implementation "ru.noties.markwon:image-okhttp:$markwon_version"
implementation "ru.noties.markwon:html:$markwon_version"
implementation "ru.noties.markwon:recycler:$markwon_version"
implementation "ru.noties.markwon:recycler-table:$markwon_version"
implementation "ru.noties.markwon:image-gif:$markwon_version"
implementation "ru.noties.markwon:image-svg:$markwon_version"
implementation "io.noties.markwon:core:$markwon_version"
implementation "io.noties.markwon:ext-latex:$markwon_version"
implementation "io.noties.markwon:ext-strikethrough:$markwon_version"
implementation "io.noties.markwon:ext-tables:$markwon_version"
implementation "io.noties.markwon:ext-tasklist:$markwon_version"
implementation "io.noties.markwon:html:$markwon_version"
implementation "io.noties.markwon:image:$markwon_version"
implementation "io.noties.markwon:image-picasso:$markwon_version"
implementation "io.noties.markwon:linkify:$markwon_version"
implementation "io.noties.markwon:recycler:$markwon_version"
implementation "io.noties.markwon:recycler-table:$markwon_version"
implementation "io.noties.markwon:simple-ext:$markwon_version"
implementation "io.noties.markwon:syntax-highlight:$markwon_version"
implementation "com.caverock:androidsvg:1.4"
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.14"
implementation "com.hendraanggrian.appcompat:socialview:0.2"
implementation "com.hendraanggrian.appcompat:socialview-commons:0.2"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
}

View File

@ -11,8 +11,11 @@
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".activities.NewFileActivity"
android:name=".activities.FileViewActivity"
android:theme="@style/AppTheme.NoActionBar"></activity>
<activity
android:name=".activities.NewFileActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".activities.RepoWatchersActivity"
android:theme="@style/AppTheme.NoActionBar" />
@ -64,8 +67,8 @@
<activity android:name=".activities.NewOrganizationActivity" />
<activity android:name=".activities.OpenRepoInBrowserActivity" />
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

View File

@ -0,0 +1,280 @@
package org.mian.gitnex.actions;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class RepositoryActions {
public static void starRepository(final Context context) {
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");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.starRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
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("repoCreated", true);
Toasty.info(context, context.getString(R.string.starRepositorySuccess));
}
}
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) {
Log.e("onFailure", t.toString());
}
});
}
public static void unStarRepository(final Context context) {
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");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.unStarRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
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("repoCreated", true);
Toasty.info(context, context.getString(R.string.unStarRepositorySuccess));
}
}
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) {
Log.e("onFailure", t.toString());
}
});
}
public static void watchRepository(final Context context) {
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");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.watchRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
tinyDb.putBoolean("repoCreated", true);
Toasty.info(context, context.getString(R.string.watchRepositorySuccess));
}
}
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) {
Log.e("onFailure", t.toString());
}
});
}
public static void unWatchRepository(final Context context) {
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");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.unWatchRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 204) {
tinyDb.putBoolean("repoCreated", true);
Toasty.info(context, context.getString(R.string.unWatchRepositorySuccess));
}
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) {
Log.e("onFailure", t.toString());
}
});
}
}

View File

@ -323,10 +323,11 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
String msState = "open";
Call<List<Milestones>> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState);
call.enqueue(new Callback<List<Milestones>>() {

View File

@ -56,6 +56,8 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
private Button editIssueButton;
private Spinner editIssueMilestoneSpinner;
private String msState = "open";
List<Milestones> milestonesList = new ArrayList<>();
private ArrayAdapter<Mention> defaultMentionAdapter;
@ -331,7 +333,7 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
Call<List<Milestones>> call_ = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState);
final int finalMsId = msId;

View File

@ -0,0 +1,149 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Files;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class FileViewActivity extends AppCompatActivity {
private View.OnClickListener onClickListener;
private TextView singleFileContents;
final Context ctx = this;
private ProgressBar mProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final TinyDB tinyDb = new TinyDB(getApplicationContext());
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");
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
ImageView closeActivity = findViewById(R.id.close);
singleFileContents = findViewById(R.id.singleFileContents);
singleFileContents.setVisibility(View.GONE);
mProgressBar = findViewById(R.id.progress_bar);
String singleFileName = getIntent().getStringExtra("singleFileName");
TextView toolbar_title = findViewById(R.id.toolbar_title);
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
toolbar_title.setText(singleFileName);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
if(connToInternet) {
getSingleFileContents(instanceUrl, instanceToken, repoOwner, repoName, singleFileName);
}
else {
Toasty.info(getApplicationContext(), getString(R.string.checkNetConnection));
}
}
private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) {
Call<Files> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getSingleFileContents(token, owner, repo, filename);
call.enqueue(new Callback<Files>() {
@Override
public void onResponse(@NonNull Call<Files> call, @NonNull retrofit2.Response<Files> response) {
if (response.code() == 200) {
AppUtil appUtil = new AppUtil();
assert response.body() != null;
if(!response.body().getContent().equals("")) {
singleFileContents.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
singleFileContents.setText(appUtil.decodeBase64(response.body().getContent()));
}
else {
singleFileContents.setText("");
mProgressBar.setVisibility(View.GONE);
}
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
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(getApplicationContext(), getString(R.string.labelGeneralError));
}
}
@Override
public void onFailure(@NonNull Call<Files> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
getIntent().removeExtra("singleFileName");
finish();
}
};
}
}

View File

@ -10,26 +10,33 @@ import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import okhttp3.OkHttpClient;
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.AsyncDrawable;
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 ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.Spanned;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
@ -63,6 +70,8 @@ import org.mian.gitnex.viewmodels.IssueCommentsViewModel;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@ -286,22 +295,60 @@ public class IssueDetailActivity extends AppCompatActivity {
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getApplicationContext()))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.createWithAssets(getApplicationContext()))
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override
public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = getApplicationContext().getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
getApplicationContext().getPackageName());
final Drawable drawable = getApplicationContext().getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
}
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(getApplicationContext().getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getApplicationContext().getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(getApplicationContext().getResources().getColor(R.color.lightBlue));
.linkColor(getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(getApplicationContext()))
.usePlugin(TaskListPlugin.create(getApplicationContext()))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
TinyDB tinyDb = new TinyDB(getApplicationContext());
@ -310,11 +357,11 @@ public class IssueDetailActivity extends AppCompatActivity {
tinyDb.putString("issueState", singleIssue.getState());
tinyDb.putString("issueTitle", singleIssue.getTitle());
Picasso.get().load(singleIssue.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(assigneeAvatar);
Picasso.get().load(singleIssue.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
issueTitle.setText(getString(R.string.issueTitleWithId, singleIssue.getNumber(), singleIssue.getTitle()));
String cleanIssueDescription = singleIssue.getBody().trim();
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
issueDescription.setText(UserMentions.UserMentionsFunc(getApplicationContext(), bodyWithMD, cleanIssueDescription));
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
markwon.setParsedMarkdown(issueDescription, UserMentions.UserMentionsFunc(getApplicationContext(), bodyWithMD, cleanIssueDescription));
RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams)issueDescription.getLayoutParams();
@ -327,7 +374,7 @@ public class IssueDetailActivity extends AppCompatActivity {
ImageView assigneesView = new ImageView(getApplicationContext());
Picasso.get().load(singleIssue.getAssignees().get(i).getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(80, 80).centerCrop().into(assigneesView);
Picasso.get().load(singleIssue.getAssignees().get(i).getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(100, 100).centerCrop().into(assigneesView);
assigneesLayout.addView(assigneesView);
assigneesView.setLayoutParams(params1);
@ -431,7 +478,7 @@ public class IssueDetailActivity extends AppCompatActivity {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(singleIssue.getCreated_at());
issueCreatedTime.setText(getString(R.string.createdTime, createdTime));
issueCreatedTime.setText(createdTime);
issueCreatedTime.setVisibility(View.VISIBLE);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getCreated_at()), getApplicationContext()));
break;
@ -439,14 +486,14 @@ public class IssueDetailActivity extends AppCompatActivity {
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(singleIssue.getCreated_at());
issueCreatedTime.setText(getString(R.string.createdTime, createdTime));
issueCreatedTime.setText(createdTime);
issueCreatedTime.setVisibility(View.VISIBLE);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(singleIssue.getCreated_at());
issueCreatedTime.setText(getString(R.string.createdTime, createdTime));
issueCreatedTime.setText(createdTime);
issueCreatedTime.setVisibility(View.VISIBLE);
break;
}

View File

@ -21,6 +21,7 @@ import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.AboutFragment;
import org.mian.gitnex.fragments.ExploreRepositoriesFragment;
import org.mian.gitnex.fragments.MyRepositoriesFragment;
import org.mian.gitnex.fragments.NavSubMenuBottomSheetFragment;
import org.mian.gitnex.fragments.OrganizationsFragment;
@ -148,7 +149,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
userAvatar = hView.findViewById(R.id.userAvatar);
if (!userAvatarNav.equals("")) {
Picasso.get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).transform(new RoundedTransformation(100, 0)).resize(180, 180).centerCrop().into(userAvatar);
Picasso.get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(userAvatar);
}
} else {
@ -278,6 +279,11 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new StarredRepositoriesFragment()).commit();
break;
case R.id.nav_explore:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ExploreRepositoriesFragment()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
@ -354,9 +360,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
userAvatar = hView.findViewById(R.id.userAvatar);
if (!Objects.requireNonNull(userDetails).getAvatar().equals("")) {
Picasso.get().load(userDetails.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(180, 180).centerCrop().into(userAvatar);
Picasso.get().load(userDetails.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
} else {
userAvatar.setImageResource(R.mipmap.ic_launcher_round);
userAvatar.setImageResource(R.mipmap.app_logo_round);
}
userFullName = hView.findViewById(R.id.userFullname);

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.activities;
import com.google.android.material.tabs.TabLayout;
import com.google.gson.JsonElement;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
@ -10,7 +11,9 @@ import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import retrofit2.Call;
import retrofit2.Callback;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@ -24,6 +27,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BranchesFragment;
import org.mian.gitnex.fragments.ClosedIssuesFragment;
import org.mian.gitnex.fragments.CollaboratorsFragment;
import org.mian.gitnex.fragments.FilesFragment;
import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.fragments.LabelsFragment;
import org.mian.gitnex.fragments.MilestonesFragment;
@ -32,6 +36,7 @@ import org.mian.gitnex.fragments.RepoBottomSheetFragment;
import org.mian.gitnex.fragments.RepoInfoFragment;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.Objects;
@ -80,14 +85,23 @@ public class RepoDetailActivity extends AppCompatActivity implements RepoBottomS
if(tinyDb.getBoolean("enableCounterIssueBadge")) {
View tabHeader = LayoutInflater.from(this).inflate(R.layout.badge, null);
@SuppressLint("InflateParams") View tabHeader = LayoutInflater.from(this).inflate(R.layout.badge, null);
textViewBadge = tabHeader.findViewById(R.id.counterBadge);
if(!tinyDb.getString("issuesCounter").isEmpty()) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
}
Objects.requireNonNull(tabLayout.getTabAt(1)).setCustomView(tabHeader);
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader);
TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2);
ColorStateList textColor = tabLayout.getTabTextColors();
assert tabOpenIssues != null;
TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeText);
openIssueTabView.setTextColor(textColor);
}
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
}
@Override
@ -191,21 +205,23 @@ public class RepoDetailActivity extends AppCompatActivity implements RepoBottomS
switch (position) {
case 0: // information
return RepoInfoFragment.newInstance(repoOwner, repoName);
case 1: // issues
case 1: // files
return FilesFragment.newInstance(repoOwner, repoName);
case 2: // issues
fragment = new IssuesFragment();
break;
case 2: // closed issues
case 3: // closed issues
fragment = new ClosedIssuesFragment();
break;
case 3: // milestones
case 4: // milestones
return MilestonesFragment.newInstance(repoOwner, repoName);
case 4: // labels
case 5: // labels
return LabelsFragment.newInstance(repoOwner, repoName);
case 5: // branches
case 6: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 6: // releases
case 7: // releases
return ReleasesFragment.newInstance(repoOwner, repoName);
case 7: // collaborators
case 8: // collaborators
return CollaboratorsFragment.newInstance(repoOwner, repoName);
}
return fragment;
@ -213,7 +229,7 @@ public class RepoDetailActivity extends AppCompatActivity implements RepoBottomS
@Override
public int getCount() {
return 8;
return 9;
}
}
@ -256,4 +272,67 @@ public class RepoDetailActivity extends AppCompatActivity implements RepoBottomS
}
private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.checkRepoStarStatus(instanceToken, owner, repo);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putInt("repositoryStarStatus", response.code());
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
Call<WatchRepository> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.checkRepoWatchStatus(instanceToken, owner, repo);
call.enqueue(new Callback<WatchRepository>() {
@Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
if(response.code() == 200) {
assert response.body() != null;
if(response.body().getSubscribed()) {
tinyDb.putBoolean("repositoryWatchStatus", true);
}
}
else {
tinyDb.putBoolean("repositoryWatchStatus", false);
}
}
@Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
}

View File

@ -98,7 +98,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
holder.userRole.setVisibility(View.GONE);
}
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(140, 140).centerCrop().into(holder.userAvatar);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
@Override

View File

@ -3,22 +3,21 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime;
@ -27,22 +26,8 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TableTheme;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
/**
* Author M M Arif
@ -122,8 +107,6 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
private TextView issueNumber;
private ImageView issueAssigneeAvatar;
private TextView issueTitle;
private TextView issueDescription;
//private ImageView issueState;
private TextView issueCreatedTime;
private TextView issueCommentsCount;
private ImageView issueType;
@ -135,9 +118,8 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
issueNumber = itemView.findViewById(R.id.issueNumber);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle);
issueDescription = itemView.findViewById(R.id.issueDescription);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
//issueState = itemView.findViewById(R.id.issueStatus);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
issueType = itemView.findViewById(R.id.issueType);
@ -157,7 +139,7 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
});
issueDescription.setOnClickListener(new View.OnClickListener() {
frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -183,26 +165,6 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.createWithAssets(context))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(context.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(context))
.usePlugin(TaskListPlugin.create(context))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.build();
if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else {
@ -210,9 +172,9 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
if (issuesModel.getUser().getAvatar_url() != null) {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar);
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} else {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar);
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
}
if (issuesModel.getPull_request() == null) {
@ -223,28 +185,12 @@ public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypePullRequest), context));
}
issueTitle.setText(context.getResources().getString(R.string.hash) + issuesModel.getNumber() + " " + issuesModel.getTitle());
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()));
if (!issuesModel.getBody().equals("")) {
String cleanIssueDescription = issuesModel.getBody().trim();
issueDescription.setVisibility(View.VISIBLE);
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
issueDescription.setText(UserMentions.UserMentionsFunc(context, bodyWithMD, cleanIssueDescription));
}
else {
issueDescription.setText("");
issueDescription.setVisibility(View.GONE);
}
/*if (issuesModel.getState().equals("open")) {
issueState.setImageResource(R.drawable.ic_issue_open);
issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextOpen), context));
} else {
issueState.setImageResource(R.drawable.ic_issue_closed);
issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextClosed), context));
}*/
switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));

View File

@ -77,7 +77,7 @@ public class CollaboratorsAdapter extends BaseAdapter {
private void initData(ViewHolder viewHolder, int position) {
Collaborators currentItem = collaboratorsList.get(position);
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.collaboratorAvatar);
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.collaboratorAvatar);
if(!currentItem.getFull_name().equals("")) {
viewHolder.collaboratorName.setText(currentItem.getFull_name());

View File

@ -0,0 +1,216 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.List;
/**
* Author M M Arif
*/
public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepositoriesAdapter.ReposSearchViewHolder> {
private List<UserRepositories> searchedReposList;
private Context mCtx;
public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context mCtx) {
this.mCtx = mCtx;
this.searchedReposList = dataList;
}
static class ReposSearchViewHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView mTextView1;
private TextView mTextView2;
private TextView fullName;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private ReposSearchViewHolder(View itemView) {
super(itemView);
mTextView1 = itemView.findViewById(R.id.repoName);
mTextView2 = itemView.findViewById(R.id.repoDescription);
image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName);
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", repoFullName.getText().toString());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
context.startActivity(intent);
}
});
reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext();
Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
PopupMenu popupMenu = new PopupMenu(context_, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
} catch (Exception e) {
popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.repoStargazers:
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
break;
case R.id.repoWatchers:
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
break;
case R.id.repoOpenInBrowser:
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
break;
}
return false;
}
});
popupMenu.show();
}
});
}
}
@NonNull
@Override
public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repos_list, parent, false);
return new ExploreRepositoriesAdapter.ReposSearchViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull final ExploreRepositoriesAdapter.ReposSearchViewHolder holder, int position) {
final UserRepositories currentItem = searchedReposList.get(position);
holder.mTextView2.setVisibility(View.GONE);
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE);
holder.mTextView2.setText(currentItem.getDescription());
}
holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
}
else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
}
@Override
public int getItemCount() {
return searchedReposList.size();
}
}

View File

@ -0,0 +1,212 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
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.helpers.Toasty;
import org.mian.gitnex.models.Files;
import java.util.ArrayList;
import java.util.List;
/**
* Author M M Arif
*/
public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHolder> implements Filterable {
private List<Files> filesList;
private Context mCtx;
private List<Files> filesListFull;
private FilesAdapterListener filesListener;
public interface FilesAdapterListener {
void onClickDir(String str);
void onClickFile(String str);
}
class FilesViewHolder extends RecyclerView.ViewHolder {
private ImageView fileTypeImage;
private TextView fileName;
private TextView fileType;
private FilesViewHolder(View itemView) {
super(itemView);
fileName = itemView.findViewById(R.id.fileName);
fileTypeImage = itemView.findViewById(R.id.fileImage);
fileType = itemView.findViewById(R.id.fileType);
//ImageView filesDropdownMenu = itemView.findViewById(R.id.filesDropdownMenu);
fileName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
if(fileType.getText().toString().equals("file")) {
filesListener.onClickFile(fileName.getText().toString());
}
else if(fileType.getText().toString().equals("dir")) {
filesListener.onClickDir(fileName.getText().toString());
}
else {
Toasty.info(context, context.getString(R.string.filesGenericError));
}
}
});
/*filesDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext();
Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
PopupMenu popupMenu = new PopupMenu(context_, v);
popupMenu.inflate(R.menu.files_dotted_list_menu);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
} catch (Exception e) {
popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.deleteFile:
Intent intent = new Intent(context, DeleteFileActivity.class);
intent.putExtra("repoFullNameForDeleteFile", fullName.getText());
context.startActivity(intent);
break;
case R.id.editFile:
Intent intentW = new Intent(context, EditFileActivity.class);
intentW.putExtra("repoFullNameForEditFile", fullName.getText());
context.startActivity(intentW);
break;
case R.id.openInBrowser:
Intent intentOpenInBrowser = new Intent(context, OpenFileInBrowserActivity.class);
intentOpenInBrowser.putExtra("fileFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
break;
}
return false;
}
});
popupMenu.show();
}
});*/
}
}
public FilesAdapter(Context mCtx, List<Files> filesListMain, FilesAdapterListener filesListener) {
this.mCtx = mCtx;
this.filesList = filesListMain;
filesListFull = new ArrayList<>(filesList);
this.filesListener = filesListener;
}
@NonNull
@Override
public FilesAdapter.FilesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.files_list, parent, false);
return new FilesAdapter.FilesViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull FilesAdapter.FilesViewHolder holder, int position) {
Files currentItem = filesList.get(position);
holder.fileType.setText(currentItem.getType());
holder.fileName.setText(currentItem.getName());
if(currentItem.getType().equals("file")) {
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_file_new));
}
else if(currentItem.getType().equals("dir")) {
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_folder_24));
}
else {
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_question_mark_24));
}
}
@Override
public int getItemCount() {
return filesList.size();
}
@Override
public Filter getFilter() {
return filesFilter;
}
private Filter filesFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Files> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(filesListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Files item : filesListFull) {
if (item.getName().toLowerCase().contains(filterPattern) || item.getPath().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filesList.clear();
filesList.addAll((List) results.values);
notifyDataSetChanged();
}
};
}

View File

@ -3,7 +3,9 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@ -14,8 +16,8 @@ import com.squareup.picasso.Picasso;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.IssueComments;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB;
@ -24,26 +26,32 @@ import org.ocpsoft.prettytime.PrettyTime;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TableTheme;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
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.AsyncDrawable;
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;
/**
* Author M M Arif
@ -171,34 +179,72 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
}
if (currentItem.getUser().getAvatar_url() != null) {
Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(holder.issueCommenterAvatar);
Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);
} else {
Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(holder.issueCommenterAvatar);
Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);
}
String cleanIssueComments = currentItem.getBody().trim();
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.create(mCtx))
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override
public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = mCtx.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
mCtx.getPackageName());
final Drawable drawable = mCtx.getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
}
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"));
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
holder.issueComment.setText(UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments));
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
markwon.setParsedMarkdown(holder.issueComment, UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments));
String edited;

View File

@ -3,22 +3,21 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime;
@ -27,22 +26,8 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TableTheme;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
/**
* Author M M Arif
@ -122,8 +107,6 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
private TextView issueNumber;
private ImageView issueAssigneeAvatar;
private TextView issueTitle;
private TextView issueDescription;
//private ImageView issueState;
private TextView issueCreatedTime;
private TextView issueCommentsCount;
private ImageView issueType;
@ -135,9 +118,8 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
issueNumber = itemView.findViewById(R.id.issueNumber);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle);
issueDescription = itemView.findViewById(R.id.issueDescription);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
//issueState = itemView.findViewById(R.id.issueStatus);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
issueType = itemView.findViewById(R.id.issueType);
@ -157,7 +139,7 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
});
issueDescription.setOnClickListener(new View.OnClickListener() {
frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -183,26 +165,6 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.createWithAssets(context))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(context.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(context))
.usePlugin(TaskListPlugin.create(context))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.build();
if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else {
@ -210,9 +172,9 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
if (issuesModel.getUser().getAvatar_url() != null) {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar);
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} else {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar);
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
}
if (issuesModel.getPull_request() == null) {
@ -223,28 +185,12 @@ public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypePullRequest), context));
}
issueTitle.setText(context.getResources().getString(R.string.hash) + issuesModel.getNumber() + " " + issuesModel.getTitle());
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()));
if (!issuesModel.getBody().equals("")) {
String cleanIssueDescription = issuesModel.getBody().trim();
issueDescription.setVisibility(View.VISIBLE);
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
issueDescription.setText(UserMentions.UserMentionsFunc(context, bodyWithMD, cleanIssueDescription));
}
else {
issueDescription.setText("");
issueDescription.setVisibility(View.GONE);
}
/*if (issuesModel.getState().equals("open")) {
issueState.setImageResource(R.drawable.ic_issue_open);
issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextOpen), context));
} else {
issueState.setImageResource(R.drawable.ic_issue_closed);
issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextClosed), context));
}*/
switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));

View File

@ -3,7 +3,6 @@ package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@ -42,13 +41,12 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
private TextView labelId;
private TextView labelColor;
private ImageView labelsView;
private ImageView labelsOptionsMenu;
private LabelsViewHolder(View itemView) {
super(itemView);
labelsView = itemView.findViewById(R.id.labelsView);
labelsOptionsMenu = itemView.findViewById(R.id.labelsOptionsMenu);
ImageView labelsOptionsMenu = itemView.findViewById(R.id.labelsOptionsMenu);
labelTitle = itemView.findViewById(R.id.labelTitle);
labelId = itemView.findViewById(R.id.labelId);
labelColor = itemView.findViewById(R.id.labelColor);
@ -146,6 +144,7 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
//.useFont(Typeface.DEFAULT)
.bold()
.textColor(new ColorInverter().getContrastColor(color))
.fontSize(36)
.width(LabelWidthCalculator.customWidth(getMaxLabelLength()))

View File

@ -83,7 +83,7 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
private void initData(MembersByOrgAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = membersList.get(position);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.memberAvatar);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(viewHolder.memberAvatar);
if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname());

View File

@ -3,12 +3,16 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.vdurmont.emoji.EmojiParser;
@ -21,25 +25,31 @@ import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TableTheme;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
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.AsyncDrawable;
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;
/**
* Author M M Arif
@ -59,6 +69,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
private TextView msClosedIssues;
private TextView msDueDate;
private ImageView msStatus;
private ProgressBar msProgress;
private MilestonesViewHolder(View itemView) {
super(itemView);
@ -69,8 +80,9 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
msOpenIssues = itemView.findViewById(R.id.milestoneIssuesOpen);
msClosedIssues = itemView.findViewById(R.id.milestoneIssuesClosed);
msDueDate = itemView.findViewById(R.id.milestoneDueDate);
msProgress = itemView.findViewById(R.id.milestoneProgress);
/*issueTitle.setOnClickListener(new View.OnClickListener() {
/*msTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -113,8 +125,45 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.createWithAssets(mCtx))
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override
public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = mCtx.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
mCtx.getPackageName());
final Drawable drawable = mCtx.getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
}
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
@ -127,11 +176,12 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
.usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
holder.msTitle.setText(currentItem.getTitle());
Spanned msTitle = markwon.toMarkdown(currentItem.getTitle());
markwon.setParsedMarkdown(holder.msTitle, msTitle);
//holder.msStatus.setText(currentItem.getState());
if(currentItem.getState().equals("open")) {
@ -183,6 +233,24 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
holder.msClosedIssues.setText(String.valueOf(currentItem.getClosed_issues()));
holder.msClosedIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneClosedIssues, currentItem.getClosed_issues()), mCtx));
if ((currentItem.getOpen_issues() + currentItem.getClosed_issues()) > 0) {
if (currentItem.getOpen_issues() == 0) {
holder.msProgress.setProgress(100);
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 100), mCtx));
}
else {
int msCompletion = 100 * currentItem.getClosed_issues() / (currentItem.getOpen_issues() + currentItem.getClosed_issues());
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, msCompletion), mCtx));
holder.msProgress.setProgress(msCompletion);
}
}
else {
holder.msProgress.setProgress(0);
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 0), mCtx));
}
if(currentItem.getDue_on() != null) {
if (timeFormat.equals("normal") || timeFormat.equals("pretty")) {
@ -216,7 +284,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
}
else {
holder.msDueDate.setVisibility(View.INVISIBLE);
holder.msDueDate.setVisibility(View.GONE);
}
}

View File

@ -13,11 +13,13 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
@ -46,7 +48,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
private TextView fullNameMy;
private ImageView repoPrivatePublicMy;
private TextView repoStarsMy;
private TextView repoWatchersMy;
private TextView repoForksMy;
private TextView repoOpenIssuesCountMy;
private MyReposViewHolder(View itemView) {
@ -57,7 +59,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
fullNameMy = itemView.findViewById(R.id.repoFullNameMy);
repoPrivatePublicMy = itemView.findViewById(R.id.imageRepoTypeMy);
repoStarsMy = itemView.findViewById(R.id.repoStarsMy);
repoWatchersMy = itemView.findViewById(R.id.repoWatchersMy);
repoForksMy = itemView.findViewById(R.id.repoForksMy);
repoOpenIssuesCountMy = itemView.findViewById(R.id.repoOpenIssuesCountMy);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
@ -165,19 +167,29 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String charac = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(16)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRound(charac, color);
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.imageMy);
} else {
holder.imageMy.setImageDrawable(drawable);
}
}
else {
holder.imageMy.setImageDrawable(drawable);
}
holder.imageMy.setImageDrawable(drawable);
holder.mTextView1My.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.mTextView2My.setVisibility(View.VISIBLE);
@ -191,7 +203,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_public);
}
holder.repoStarsMy.setText(currentItem.getStars_count());
holder.repoWatchersMy.setText(currentItem.getWatchers_count());
holder.repoForksMy.setText(currentItem.getForks_count());
holder.repoOpenIssuesCountMy.setText(currentItem.getOpen_issues_count());
}

View File

@ -79,7 +79,7 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<Organizations
UserOrganizations currentItem = orgList.get(position);
holder.mTextView2.setVisibility(View.GONE);
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(holder.image);
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
holder.mTextView1.setText(currentItem.getUsername());
if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE);

View File

@ -65,7 +65,7 @@ public class ProfileFollowersAdapter extends RecyclerView.Adapter<ProfileFollowe
holder.userName.setVisibility(View.GONE);
}
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(140, 140).centerCrop().into(holder.userAvatar);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
@Override

View File

@ -65,7 +65,7 @@ public class ProfileFollowingAdapter extends RecyclerView.Adapter<ProfileFollowi
holder.userName.setVisibility(View.GONE);
}
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(140, 140).centerCrop().into(holder.userAvatar);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
@Override

View File

@ -1,8 +1,10 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Html;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
@ -13,22 +15,30 @@ import com.amulyakhare.textdrawable.TextDrawable;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R;
import org.mian.gitnex.models.Releases;
import org.mian.gitnex.util.TinyDB;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import okhttp3.OkHttpClient;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
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.AsyncDrawable;
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;
/**
* Author M M Arif
@ -77,6 +87,8 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
@Override
public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) {
final TinyDB tinyDb = new TinyDB(mCtx);
Releases currentItem = releasesList.get(position);
holder.releaseTitle.setText(currentItem.getName());
@ -115,28 +127,65 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.createWithAssets(mCtx))
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override
public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = mCtx.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
mCtx.getPackageName());
final Drawable drawable = mCtx.getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
}
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(Color.GREEN)
.codeBackgroundColor(Color.BLACK)
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody()));
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody()));
if(!currentItem.getBody().equals("")) {
holder.releaseDescription.setText(bodyWithMD);
markwon.setParsedMarkdown(holder.releaseDescription, bodyWithMD);
}
else {
holder.releaseDescription.setVisibility(View.GONE);

View File

@ -77,7 +77,7 @@ public class RepoStargazersAdapter extends BaseAdapter {
private void initData(RepoStargazersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = stargazersList.get(position);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.memberAvatar);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname());

View File

@ -77,7 +77,7 @@ public class RepoWatchersAdapter extends BaseAdapter {
private void initData(RepoWatchersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = watchersList.get(position);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.memberAvatar);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname());

View File

@ -17,11 +17,13 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
@ -46,7 +48,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
private TextView fullName;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoWatchers;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private ReposViewHolder(View itemView) {
@ -58,7 +60,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoWatchers = itemView.findViewById(R.id.repoWatchers);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
@ -167,19 +169,29 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String charac = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(16)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRound(charac, color);
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
holder.image.setImageDrawable(drawable);
holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE);
@ -193,7 +205,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoWatchers.setText(currentItem.getWatchers_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
}

View File

@ -13,11 +13,13 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
@ -46,7 +48,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
private TextView fullName;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoWatchers;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private OrgReposViewHolder(View itemView) {
@ -57,7 +59,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoWatchers = itemView.findViewById(R.id.repoWatchers);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
@ -166,19 +168,29 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String charac = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(16)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRound(charac, color);
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
holder.image.setImageDrawable(drawable);
holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE);
@ -192,7 +204,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoWatchers.setText(currentItem.getWatchers_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
}

View File

@ -13,11 +13,13 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
@ -46,7 +48,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
private TextView fullName;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoWatchers;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private StarredReposViewHolder(View itemView) {
@ -57,7 +59,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoWatchers = itemView.findViewById(R.id.repoWatchers);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
@ -166,19 +168,29 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String charac = String.valueOf(currentItem.getName().charAt(0));
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(16)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRound(charac, color);
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
holder.image.setImageDrawable(drawable);
holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE);
@ -192,7 +204,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoWatchers.setText(currentItem.getWatchers_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
}

View File

@ -78,7 +78,7 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
private void initData(TeamMembersByOrgAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = teamMembersList.get(position);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.memberAvatar);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname());

View File

@ -141,7 +141,7 @@ public class UserSearchAdapter extends RecyclerView.Adapter<UserSearchAdapter.Us
}
if (!currentItem.getAvatar().equals("")) {
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(holder.userAvatar);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
}
if(getItemCount() > 0) {

View File

@ -49,6 +49,7 @@ public class AboutFragment extends Fragment {
final TextView appVerBuild;
final TextView donationLink;
final TextView donationLinkPatreon;
final TextView translateLink;
final TextView creditsButton;
final TextView sponsorsButton;
final TextView appWebsite;
@ -64,6 +65,7 @@ public class AboutFragment extends Fragment {
creditsButton = v.findViewById(R.id.creditsButton);
donationLink = v.findViewById(R.id.donationLink);
donationLinkPatreon = v.findViewById(R.id.donationLinkPatreon);
translateLink = v.findViewById(R.id.translateLink);
sponsorsButton = v.findViewById(R.id.sponsorsButton);
appWebsite = v.findViewById(R.id.appWebsite);
appRepo = v.findViewById(R.id.appRepo);
@ -90,6 +92,16 @@ public class AboutFragment extends Fragment {
}
});
translateLink.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
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);
}
});
appWebsite.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();

View File

@ -263,6 +263,7 @@ public class ClosedIssuesFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -0,0 +1,194 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
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.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.adapters.ExploreRepositoriesAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.ExploreRepositories;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.List;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
+ * Template Author M M Arif
+ * Author 6543
+ */
public class ExploreRepositoriesFragment extends Fragment {
private static String repoNameF = "param2";
private static String repoOwnerF = "param1";
private ProgressBar mProgressBar;
private RecyclerView mRecyclerView;
private TextView noData;
private TextView searchKeyword;
private Boolean repoTypeInclude = true;
private String sort = "updated";
private String order = "asc";
private ExploreRepositoriesAdapter adapter;
private OnFragmentInteractionListener mListener;
public ExploreRepositoriesFragment() {
}
public static ExploreRepositoriesFragment newInstance(String param1, String param2) {
ExploreRepositoriesFragment fragment = new ExploreRepositoriesFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
String repoName = getArguments().getString(repoNameF);
String repoOwner = getArguments().getString(repoOwnerF);
}
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
final View v = inflater.inflate(R.layout.fragment_explore_repo, container, false);
//setHasOptionsMenu(true);
((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleExplore));
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");
searchKeyword = v.findViewById(R.id.searchKeyword);
noData = v.findViewById(R.id.noData);
mProgressBar = v.findViewById(R.id.progress_bar);
mRecyclerView = v.findViewById(R.id.recyclerViewReposSearch);
if(connToInternet) {
searchKeyword.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND) {
if(!searchKeyword.getText().toString().equals("")) {
mProgressBar.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
loadSearchReposList(instanceUrl, instanceToken, loginUid, searchKeyword.getText().toString(), repoTypeInclude, sort, order, getContext());
}
}
return false;
}
});
}
else {
mProgressBar.setVisibility(View.GONE);
}
return v;
}
private void loadSearchReposList(String instanceUrl, String instanceToken, String loginUid, String searchKeyword, Boolean repoTypeInclude, String sort, String order, final Context context) {
Call<ExploreRepositories> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), searchKeyword, repoTypeInclude, sort, order);
call.enqueue(new Callback<ExploreRepositories>() {
@Override
public void onResponse(@NonNull Call<ExploreRepositories> call, @NonNull Response<ExploreRepositories> response) {
if (response.isSuccessful()) {
assert response.body() != null;
getReposList(response.body().getSearchedData(), context);
} else {
Log.i("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<ExploreRepositories> call, @NonNull Throwable t) {
Log.i("onFailure", t.getMessage());
}
});
}
private void getReposList(List<UserRepositories> dataList, Context context) {
adapter = new ExploreRepositoriesAdapter(dataList, context);
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noData.setVisibility(View.GONE);
mProgressBar.setVisibility(View.GONE);
}
else {
noData.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}

View File

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

View File

@ -262,6 +262,7 @@ public class IssuesFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -112,6 +112,7 @@ public class MembersByOrgFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -46,6 +46,7 @@ public class MilestonesFragment extends Fragment {
private String repoName;
private String repoOwner;
private String msState = "all";
private OnFragmentInteractionListener mListener;
@ -103,7 +104,7 @@ public class MilestonesFragment extends Fragment {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, msState);
}
}, 50);
}
@ -127,7 +128,7 @@ public class MilestonesFragment extends Fragment {
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("milestoneCreated")) {
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, msState);
tinyDb.putBoolean("milestoneCreated", false);
}
}
@ -152,7 +153,7 @@ public class MilestonesFragment extends Fragment {
MilestonesViewModel msModel = new ViewModelProvider(this).get(MilestonesViewModel.class);
msModel.getMilestonesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Milestones>>() {
msModel.getMilestonesList(instanceUrl, instanceToken, owner, repo, msState).observe(this, new Observer<List<Milestones>>() {
@Override
public void onChanged(@Nullable List<Milestones> msListMain) {
adapter = new MilestonesAdapter(getContext(), msListMain);
@ -182,6 +183,7 @@ public class MilestonesFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -89,6 +89,7 @@ public class MyRepositoriesFragment extends Fragment {
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String userLogin = tinyDb.getString("userLogin");
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
@ -140,13 +141,13 @@ public class MyRepositoriesFragment extends Fragment {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), loginUid);
MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), userLogin);
}
}, 50);
}
});
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), loginUid);
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), userLogin);
}
else {
@ -164,16 +165,17 @@ public class MyRepositoriesFragment extends Fragment {
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String userLogin = tinyDb.getString("userLogin");
MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), loginUid);
MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), userLogin);
}
private void fetchDataAsync(String instanceUrl, String instanceToken, String username) {
private void fetchDataAsync(String instanceUrl, String instanceToken, String userLogin) {
MyRepositoriesViewModel myRepoModel = new ViewModelProvider(this).get(MyRepositoriesViewModel.class);
myRepoModel.getCurrentUserRepositories(instanceUrl, instanceToken, username).observe(this, new Observer<List<UserRepositories>>() {
myRepoModel.getCurrentUserRepositories(instanceUrl, instanceToken, userLogin).observe(this, new Observer<List<UserRepositories>>() {
@Override
public void onChanged(@Nullable List<UserRepositories> myReposListMain) {
adapter = new MyReposListAdapter(getContext(), myReposListMain);
@ -203,6 +205,7 @@ public class MyRepositoriesFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -104,7 +104,7 @@ public class OrganizationInfoFragment extends Fragment {
if (response.code() == 200) {
assert orgInfo != null;
Picasso.get().load(orgInfo.getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(orgAvatar);
Picasso.get().load(orgInfo.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(orgAvatar);
orgDescInfo.setText(orgInfo.getDescription());
orgWebsiteInfo.setText(orgInfo.getWebsite());
orgLocationInfo.setText(orgInfo.getLocation());

View File

@ -173,6 +173,7 @@ public class OrganizationsFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -48,7 +48,7 @@ public class ProfileFragment extends Fragment {
TextView userEmail = v.findViewById(R.id.userEmail);
userFullName.setText(tinyDb.getString("userFullname"));
Picasso.get().load(tinyDb.getString("userAvatar")).transform(new RoundedTransformation(100, 0)).resize(180, 180).centerCrop().into(userAvatar);
Picasso.get().load(tinyDb.getString("userAvatar")).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(userAvatar);
userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin")));
userEmail.setText(tinyDb.getString("userEmail"));

View File

@ -8,6 +8,8 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.RepositoryActions;
import org.mian.gitnex.util.TinyDB;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -24,6 +26,8 @@ public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.repo_bottom_sheet_layout, container, false);
final TinyDB tinyDb = new TinyDB(getContext());
TextView createLabel = v.findViewById(R.id.createLabel);
TextView createIssue = v.findViewById(R.id.createNewIssue);
TextView createMilestone = v.findViewById(R.id.createNewMilestone);
@ -31,6 +35,10 @@ public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
TextView createRelease = v.findViewById(R.id.createRelease);
TextView openWebRepo = v.findViewById(R.id.openWebRepo);
TextView newFile = v.findViewById(R.id.newFile);
TextView starRepository = v.findViewById(R.id.starRepository);
TextView unStarRepository = v.findViewById(R.id.unStarRepository);
TextView watchRepository = v.findViewById(R.id.watchRepository);
TextView unWatchRepository = v.findViewById(R.id.unWatchRepository);
createLabel.setOnClickListener(new View.OnClickListener() {
@Override
@ -40,13 +48,19 @@ public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
}
});
createIssue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("newIssue");
dismiss();
}
});
if(tinyDb.getBoolean("hasIssues")) {
createIssue.setVisibility(View.VISIBLE);
createIssue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("newIssue");
dismiss();
}
});
}
else {
createIssue.setVisibility(View.GONE);
}
createMilestone.setOnClickListener(new View.OnClickListener() {
@Override
@ -88,6 +102,72 @@ public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
}
});
if(tinyDb.getInt("repositoryStarStatus") == 204) { // star a repo
starRepository.setVisibility(View.GONE);
unStarRepository.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RepositoryActions.unStarRepository(getContext());
tinyDb.putInt("repositoryStarStatus", 404);
dismiss();
}
});
}
else if(tinyDb.getInt("repositoryStarStatus") == 404) {
unStarRepository.setVisibility(View.GONE);
starRepository.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RepositoryActions.starRepository(getContext());
tinyDb.putInt("repositoryStarStatus", 204);
dismiss();
}
});
}
if(tinyDb.getBoolean("repositoryWatchStatus")) { // watch a repo
watchRepository.setVisibility(View.GONE);
unWatchRepository.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RepositoryActions.unWatchRepository(getContext());
tinyDb.putBoolean("repositoryWatchStatus", false);
dismiss();
}
});
}
else {
unWatchRepository.setVisibility(View.GONE);
watchRepository.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RepositoryActions.watchRepository(getContext());
tinyDb.putBoolean("repositoryWatchStatus", true);
dismiss();
}
});
}
return v;
}

View File

@ -1,24 +1,31 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import okhttp3.OkHttpClient;
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.AsyncDrawable;
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 ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
import android.text.Spanned;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@ -40,6 +47,8 @@ import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Objects;
@ -206,6 +215,8 @@ public class RepoInfoFragment extends Fragment {
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) {
final TinyDB tinyDb = new TinyDB(getContext());
Call<UserRepositories> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
@ -236,6 +247,13 @@ public class RepoInfoFragment extends Fragment {
repoRepoUrlInfo.setText(repoInfo.getHtml_url());
repoForksCountInfo.setText(repoInfo.getForks_count());
if(repoInfo.getHas_issues() != null) {
tinyDb.putBoolean("hasIssues", repoInfo.getHas_issues());
}
else {
tinyDb.putBoolean("hasIssues", true);
}
switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
@ -299,30 +317,68 @@ public class RepoInfoFragment extends Fragment {
if (response.code() == 200) {
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext()))
.usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
.usePlugin(ImagesPlugin.createWithAssets(getContext()))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
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(getContext()))
.usePlugin(TaskListPlugin.create(getContext()))
.usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.build();
.usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override
public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
CharSequence bodyWithMD = null;
final int resourceId = getContext().getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
getContext().getPackageName());
final Drawable drawable = getContext().getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
}
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(getContext().getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getContext().getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(getContext()))
.usePlugin(TaskListPlugin.create(getContext()))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
Spanned bodyWithMD = null;
if (response.body() != null) {
bodyWithMD = markwon.toMarkdown(response.body());
}
repoFileContents.setText(bodyWithMD);
assert bodyWithMD != null;
markwon.setParsedMarkdown(repoFileContents, bodyWithMD);
} else if (response.code() == 401) {

View File

@ -155,6 +155,7 @@ public class RepositoriesByOrgFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -176,6 +176,7 @@ public class RepositoriesFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -30,7 +30,7 @@ public class SettingsFragment extends Fragment {
private Context ctx = null;
private static String[] langList = {"English", "French", "German", "Russian"};
private static String[] langList = {"Arabic", "Chinese", "English", "Finnish", "French", "German", "Italian", "Persian", "Russian", "Serbian"};
private static int langSelectedChoice = 0;
private static String[] timeList = {"Pretty", "Normal"};
@ -68,7 +68,7 @@ public class SettingsFragment extends Fragment {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse(getResources().getString(R.string.appRepoContributingLink)));
intent.setData(Uri.parse(getResources().getString(R.string.crowdInLink)));
startActivity(intent);
}
});
@ -244,15 +244,33 @@ public class SettingsFragment extends Fragment {
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 "Persian":
tinyDb.putString("locale", "fa");
break;
case "Russian":
tinyDb.putString("locale", "ru");
break;
case "Serbian":
tinyDb.putString("locale", "sr");
break;
default:
tinyDb.putString("locale", "en");
break;

View File

@ -13,9 +13,13 @@ import org.mian.gitnex.activities.AddRemoveAssigneesActivity;
import org.mian.gitnex.activities.AddRemoveLabelsActivity;
import org.mian.gitnex.activities.EditIssueActivity;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.helpers.Toasty;
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;
/**
* Author M M Arif
@ -37,6 +41,7 @@ public class SingleIssueBottomSheetFragment extends BottomSheetDialogFragment {
TextView closeIssue = v.findViewById(R.id.closeIssue);
TextView reOpenIssue = v.findViewById(R.id.reOpenIssue);
TextView addRemoveAssignees = v.findViewById(R.id.addRemoveAssignees);
TextView copyIssueUrl = v.findViewById(R.id.copyIssueUrl);
replyToIssue.setOnClickListener(new View.OnClickListener() {
@Override
@ -78,6 +83,32 @@ public class SingleIssueBottomSheetFragment extends BottomSheetDialogFragment {
}
});
copyIssueUrl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// get url of repo
String repoFullName = tinyDB.getString("repoFullName");
String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw");
if(!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol");
}
// get issue Url
String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber");
// copy to clipboard
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(getContext()).getSystemService(android.content.Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("issueUrl", issueUrl);
clipboard.setPrimaryClip(clip);
dismiss();
Toasty.info(getContext(), getContext().getString(R.string.copyIssueUrlToastMsg));
}
});
if(tinyDB.getString("issueState").equals("open")) { // close issue
reOpenIssue.setVisibility(View.GONE);

View File

@ -198,6 +198,7 @@ public class StarredRepositoriesFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -156,6 +156,7 @@ public class TeamsByOrgFragment extends Fragment {
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.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) {
return;

View File

@ -3,6 +3,8 @@ package org.mian.gitnex.interfaces;
import com.google.gson.JsonElement;
import org.mian.gitnex.models.AddEmail;
import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.ExploreRepositories;
import org.mian.gitnex.models.Files;
import org.mian.gitnex.models.NewFile;
import org.mian.gitnex.models.UpdateIssueAssignee;
import org.mian.gitnex.models.UpdateIssueState;
@ -26,6 +28,7 @@ import org.mian.gitnex.models.UserOrganizations;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.UserSearch;
import org.mian.gitnex.models.UserTokens;
import org.mian.gitnex.models.WatchRepository;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.Body;
@ -99,7 +102,7 @@ public interface ApiInterface {
Call<Issues> replyCommentToIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex, @Body Issues jsonStr);
@GET("repos/{owner}/{repo}/milestones") // get milestones by repo
Call<List<Milestones>> getMilestones(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
Call<List<Milestones>> getMilestones(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Query("state") String state);
@GET("repos/{owner}/{repo}/branches") // get branches
Call<List<Branches>> getBranches(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@ -212,6 +215,36 @@ public interface ApiInterface {
@GET("repos/{owner}/{repo}/subscribers") // get all repo watchers
Call<List<UserInfo>> getRepoWatchers(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@GET("repos/search") // get all the repos which match the query string
Call<ExploreRepositories> queryRepos(@Header("Authorization") String token, @Query("q") String searchKeyword, @Query("private") Boolean repoTypeInclude, @Query("sort") String sort, @Query("order") String order);
@POST("repos/{owner}/{repo}/contents/{file}") // create new file
Call<JsonElement> createNewFile(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("file") String fileName, @Body NewFile jsonStr);
@GET("repos/{owner}/{repo}/contents") // get all the files and dirs of a repository
Call<List<Files>> getFiles(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@GET("repos/{owner}/{repo}/contents/{file}") // get single file contents
Call<Files> getSingleFileContents(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("file") String file);
@GET("repos/{owner}/{repo}/contents/{fileDir}") // get all the sub files and dirs of a repository
Call<List<Files>> getDirFiles(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("fileDir") String fileDir);
@GET("user/starred/{owner}/{repo}") // check star status of a repository
Call<JsonElement> checkRepoStarStatus(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@PUT("user/starred/{owner}/{repo}") // star a repository
Call<JsonElement> starRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@DELETE("user/starred/{owner}/{repo}") // un star a repository
Call<JsonElement> unStarRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@GET("repos/{owner}/{repo}/subscription") // check watch status of a repository
Call<WatchRepository> checkRepoWatchStatus(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@PUT("repos/{owner}/{repo}/subscription") // watch a repository
Call<JsonElement> watchRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@DELETE("repos/{owner}/{repo}/subscription") // un watch a repository
Call<JsonElement> unWatchRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
}

View File

@ -0,0 +1,22 @@
package org.mian.gitnex.models;
import java.util.ArrayList;
/**
* Author M M Arif
*/
public class ExploreRepositories {
private ArrayList<UserRepositories> data;
private Boolean ok;
public ArrayList<UserRepositories> getSearchedData() {
return data;
}
public Boolean getOk() {
return ok;
}
}

View File

@ -0,0 +1,74 @@
package org.mian.gitnex.models;
/**
* Author M M Arif
*/
public class Files {
private String name;
private String path;
private String sha;
private String type;
private int size;
private String encoding;
private String content;
private String target;
private String url;
private String html_url;
private String git_url;
private String download_url;
private String submodule_git_url;
public String getName() {
return name;
}
public String getPath() {
return path;
}
public String getSha() {
return sha;
}
public String getType() {
return type;
}
public int getSize() {
return size;
}
public String getEncoding() {
return encoding;
}
public String getContent() {
return content;
}
public String getTarget() {
return target;
}
public String getUrl() {
return url;
}
public String getHtml_url() {
return html_url;
}
public String getGit_url() {
return git_url;
}
public String getDownload_url() {
return download_url;
}
public String getSubmodule_git_url() {
return submodule_git_url;
}
}

View File

@ -27,7 +27,8 @@ public class UserRepositories {
private String ssh_url;
private String website;
private String forks_count;
private Boolean has_issues;
private String avatar_url;
public int getId() {
return id;
@ -96,4 +97,12 @@ public class UserRepositories {
public String getForks_count() {
return forks_count;
}
public Boolean getHas_issues() {
return has_issues;
}
public String getAvatar_url() {
return avatar_url;
}
}

View File

@ -0,0 +1,39 @@
package org.mian.gitnex.models;
/**
* Author M M Arif
*/
public class WatchRepository {
private Boolean subscribed;
private Boolean ignored;
private String reason;
private String created_at;
private String url;
private String repository_url;
public Boolean getSubscribed() {
return subscribed;
}
public Boolean getIgnored() {
return ignored;
}
public String getReason() {
return reason;
}
public String getCreated_at() {
return created_at;
}
public String getUrl() {
return url;
}
public String getRepository_url() {
return repository_url;
}
}

View File

@ -0,0 +1,117 @@
package org.mian.gitnex.viewmodels;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Files;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class FilesViewModel extends ViewModel {
private static MutableLiveData<List<Files>> filesList;
private static MutableLiveData<List<Files>> filesList2;
public LiveData<List<Files>> getFilesList(String instanceUrl, String token, String owner, String repo, Context ctx) {
filesList = new MutableLiveData<>();
loadFilesList(instanceUrl, token, owner, repo, ctx);
return filesList;
}
private static void loadFilesList(String instanceUrl, String token, String owner, String repo, final Context ctx) {
Call<List<Files>> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getFiles(token, owner, repo);
call.enqueue(new Callback<List<Files>>() {
@Override
public void onResponse(@NonNull Call<List<Files>> call, @NonNull Response<List<Files>> response) {
if (response.isSuccessful()) {
Collections.sort(response.body(), new Comparator<Files>() {
@Override
public int compare(Files byType1, Files byType2) {
return byType1.getType().compareTo(byType2.getType());
}
});
filesList.postValue(response.body());
} else {
Toasty.info(ctx, ctx.getString(R.string.noDataFilesTab));
Log.i("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Files>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
public LiveData<List<Files>> getFilesList2(String instanceUrl, String token, String owner, String repo, String filesDir, Context ctx) {
filesList2 = new MutableLiveData<>();
loadFilesList2(instanceUrl, token, owner, repo, filesDir, ctx);
return filesList2;
}
private static void loadFilesList2(String instanceUrl, String token, String owner, String repo, String filesDir, final Context ctx) {
Call<List<Files>> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getDirFiles(token, owner, repo, filesDir);
call.enqueue(new Callback<List<Files>>() {
@Override
public void onResponse(@NonNull Call<List<Files>> call, @NonNull Response<List<Files>> response) {
if (response.isSuccessful()) {
Collections.sort(response.body(), new Comparator<Files>() {
@Override
public int compare(Files byType1, Files byType2) {
return byType1.getType().compareTo(byType2.getType());
}
});
filesList2.postValue(response.body());
} else {
Toasty.info(ctx, ctx.getString(R.string.noDataFilesTab));
Log.i("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Files>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

@ -20,20 +20,20 @@ public class MilestonesViewModel extends ViewModel {
private static MutableLiveData<List<Milestones>> milestonesList;
public LiveData<List<Milestones>> getMilestonesList(String instanceUrl, String token, String owner, String repo) {
public LiveData<List<Milestones>> getMilestonesList(String instanceUrl, String token, String owner, String repo, String msState) {
milestonesList = new MutableLiveData<>();
loadMilestonesList(instanceUrl, token, owner, repo);
loadMilestonesList(instanceUrl, token, owner, repo, msState);
return milestonesList;
}
public static void loadMilestonesList(String instanceUrl, String token, String owner, String repo) {
public static void loadMilestonesList(String instanceUrl, String token, String owner, String repo, String msState) {
Call<List<Milestones>> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getMilestones(token, owner, repo);
.getMilestones(token, owner, repo, msState);
call.enqueue(new Callback<List<Milestones>>() {

View File

@ -0,0 +1,5 @@
<vector android:height="16dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M21.99,4c0,-1.1 -0.89,-2 -1.99,-2H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h14l4,4 -0.01,-18z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="20dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="20dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M21.99,4c0,-1.1 -0.89,-2 -1.99,-2H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h14l4,4 -0.01,-18z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
</vector>

View File

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="512dp"
android:height="512dp"
android:viewportWidth="16"
android:viewportHeight="16"
tools:ignore="VectorRaster">
<path
android:fillColor="#FFFFFF"
android:pathData="m13.707,3.293 l-3,-3c-0.1875,-0.1875 -0.4419,-0.293 -0.707,-0.293h-7c-0.5522,0 -1,0.4478 -1,1v14c0,0.5527 0.4478,1 1,1h10c0.5522,0 1,-0.4473 1,-1v-11c0,-0.2651 -0.1055,-0.5195 -0.293,-0.707zM8,12h-3v-2h3zM11,9h-6v-2h6zM11,4c-0.5523,0 -1,-0.4478 -1,-1v-2l3,3z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M14,4l2.29,2.29 -2.88,2.88 1.42,1.42 2.88,-2.88L20,10L20,4zM10,4L4,4v6l2.29,-2.29 4.71,4.7L11,20h2v-8.41l-5.29,-5.3z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/>
</vector>

View File

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="511.999" android:viewportWidth="511.999"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFFFF" android:pathData="M508.745,246.041c-4.574,-6.257 -113.557,-153.206 -252.748,-153.206S7.818,239.784 3.249,246.035c-4.332,5.936 -4.332,13.987 0,19.923c4.569,6.257 113.557,153.206 252.748,153.206s248.174,-146.95 252.748,-153.201C513.083,260.028 513.083,251.971 508.745,246.041zM255.997,385.406c-102.529,0 -191.33,-97.533 -217.617,-129.418c26.253,-31.913 114.868,-129.395 217.617,-129.395c102.524,0 191.319,97.516 217.617,129.418C447.361,287.923 358.746,385.406 255.997,385.406z"/>
<path android:fillColor="#FFFFFFFF" android:pathData="M255.997,154.725c-55.842,0 -101.275,45.433 -101.275,101.275s45.433,101.275 101.275,101.275s101.275,-45.433 101.275,-101.275S311.839,154.725 255.997,154.725zM255.997,323.516c-37.23,0 -67.516,-30.287 -67.516,-67.516s30.287,-67.516 67.516,-67.516s67.516,30.287 67.516,67.516S293.227,323.516 255.997,323.516z"/>
</vector>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@android:id/background"
android:top="2dp"
android:bottom="2dp"
android:right="1dp"
android:left="1dp">
<shape>
<corners android:radius="15dp"/>
<solid android:color="@color/divider"/>
</shape>
</item>
<item
android:id="@android:id/progress"
android:top="3dp"
android:bottom="3dp"
android:left="1dp"
android:right="1dp">
<scale android:scaleWidth="100%">
<shape>
<corners android:radius="15dp" />
</shape>
</scale>
</item>
</layer-list>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="35dp"/>
<corners android:radius="5dp"/>
</shape>

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/colorPrimary">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
tools:ignore="UnusedAttribute">
<ImageView
android:id="@+id/close"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="15dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:contentDescription="@string/close"
android:src="@drawable/ic_close" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/defaultFilename"
android:textColor="@color/white"
android:ellipsize="none"
android:scrollbars="horizontal"
android:singleLine="true"
android:layout_marginEnd="20dp"
android:textSize="18sp" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/toastBackground">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="UselessParent">
<TextView
android:id="@+id/singleFileContents"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:textSize="14sp"
android:padding="15dp"
/>
</ScrollView>
</LinearLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
android:visibility="visible" />
</RelativeLayout>

View File

@ -182,7 +182,7 @@
android:layout_width="match_parent"
android:layout_height="1dp"
android:id="@+id/divider"
android:layout_marginTop="10dp"
android:layout_marginTop="15dp"
android:background="@color/divider" />
<androidx.recyclerview.widget.RecyclerView

View File

@ -22,7 +22,7 @@
android:layout_marginBottom="20dp"
android:baselineAligned="false"
android:contentDescription="@string/app_name"
android:src="@mipmap/app_logo_round" />
android:src="@mipmap/app_logo" />
<LinearLayout
android:layout_width="match_parent"
@ -147,23 +147,13 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/appRepoIssuesText"
android:textColor="@color/colorWhite"
android:textSize="14sp"
android:gravity="center"
android:layout_marginTop="20dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/appRepoIssuesLink"
android:text="@string/appRepoLink"
android:textColor="@color/colorWhite"
android:textSize="14sp"
android:gravity="center"
android:autoLink="web"
android:textColorLink="@color/lightBlue"
android:layout_marginTop="20dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp" />

View File

@ -39,6 +39,12 @@
android:layout_height="wrap_content"
android:text="@string/tab_text_info" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tabItemFiles"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tab_text_files" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tabItem2_issues"
android:layout_width="wrap_content"

View File

@ -2,22 +2,35 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="@color/backgroundColor"
android:paddingTop="8dp">
<TextView
android:id="@+id/createNewUser"
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/adminCreateNewUser"
android:drawableStart="@drawable/ic_add_person"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:id="@+id/createNewUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/adminCreateNewUser"
android:drawableStart="@drawable/ic_add_person"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@ -30,7 +30,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:scaleType="fitCenter"
android:layout_marginTop="5dp"
android:contentDescription="@string/userRoleAdmin"
android:src="@drawable/ic_android" />

View File

@ -13,7 +13,7 @@
android:textSize="16sp"
app:textAllCaps="true"
android:text="@string/tab_text_issues"
android:textColor="@color/white" />
android:textColor="@color/lightGray" />
<TextView
android:id="@+id/counterBadge"

View File

@ -13,7 +13,6 @@
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="15dp"
android:layout_marginTop="5dp"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_android" />

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearLayoutFilesFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:fitsSystemWindows="true"
android:orientation="vertical"
android:layout_margin="10dp"
android:theme="@style/AppTheme"
android:background="@color/backgroundColor"
tools:context=".activities.MainActivity">
<TextView
android:id="@+id/fileType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"/>
<ImageView
android:id="@+id/fileImage"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginEnd="15dp"
android:contentDescription="@string/repoContentAvatar"
android:src="@drawable/ic_file" />
<LinearLayout
android:id="@+id/infoSection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/fileImage"
android:orientation="horizontal">
<TextView
android:id="@+id/fileName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".80"
android:layout_marginBottom="0dp"
android:text="@string/defaultFilename"
android:textColor="@color/white"
android:textSize="16sp" />
<ImageView
android:id="@+id/filesDropdownMenu"
android:layout_width="0dp"
android:layout_weight=".10"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:scaleType="fitEnd"
android:visibility="gone"
android:src="@drawable/ic_dotted_menu_horizontal"
android:contentDescription="@string/menuContentDesc" />
</LinearLayout>
</RelativeLayout>

View File

@ -25,7 +25,7 @@
android:layout_marginTop="20dp"
android:baselineAligned="false"
android:contentDescription="@string/logo"
android:src="@mipmap/app_logo_round" />
android:src="@mipmap/app_logo" />
<TextView
android:id="@+id/appName"
@ -105,8 +105,21 @@
android:gravity="start"
android:autoLink="web"
android:visibility="visible"
android:layout_marginBottom="10dp"
android:textColorLink="@color/lightBlue" />
<TextView
android:id="@+id/translateLink"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:gravity="start"
android:text="@string/translateText"
android:textColor="@color/lightBlue"
android:textColorLink="@color/lightBlue"
android:textSize="16sp"
android:visibility="visible" />
</LinearLayout>
<LinearLayout

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:orientation="vertical">
<EditText
android:id="@+id/searchKeyword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="14sp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:inputType="text"
android:background="@drawable/shape_inputs"
android:textColor="@color/white"
android:textColorHint="@color/colorAccent"
android:hint="@string/exploreTextBoxHint"
android:textColorHighlight="@color/white"
android:imeOptions="actionSend" />
<TextView
android:id="@+id/noData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:gravity="center"
android:text="@string/noDataFound"
android:textColor="@color/white"
android:textSize="20sp"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewReposSearch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="0dp"
android:scrollbars="vertical" />
</LinearLayout>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
tools:context=".activities.RepoDetailActivity">
<LinearLayout
android:id="@+id/filesFrame"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/fileStructure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<moe.feng.common.view.breadcrumbs.BreadcrumbsView
android:id="@+id/breadcrumbs_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:CustomTextSize="16sp"
app:SelectedTextColor="@color/colorAccent"
app:UnSelectedTextColor="@color/lightGray"
android:text="@string/filesBreadcrumbRoot"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:padding="4dp"
android:scrollbars="vertical" />
<TextView
android:id="@+id/noDataFiles"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:gravity="center"
android:text="@string/noDataFilesTab"
android:textColor="@color/white"
android:textSize="20sp"
android:visibility="gone" />
</LinearLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:indeterminate="true"
android:visibility="gone" />
</LinearLayout>

View File

@ -37,7 +37,7 @@
android:paddingBottom="10dp"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:textColor="@color/white"/>
android:textColor="@color/lightGray"/>
<ImageView
android:id="@+id/repoMetaDataExpandCollapse"
@ -69,7 +69,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoBlank"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:textColor="@color/colorWhite"/>
@ -87,7 +87,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoBlank"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:textColor="@color/colorWhite"/>
@ -105,7 +105,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoBlank"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:autoLink="web"
android:textColor="@color/colorWhite"/>
@ -124,9 +124,10 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoBlank"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:autoLink="web"
android:textColorLink="@color/lightBlue"
android:textColor="@color/colorWhite"/>
<TextView
@ -143,7 +144,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoZero"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:textColor="@color/colorWhite"/>
@ -161,7 +162,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoDefaultBranchText"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:textColor="@color/colorWhite"/>
@ -179,7 +180,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoBlank"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:autoLink="web"
android:textColorLink="@color/lightBlue"
@ -199,7 +200,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoBlank"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:autoLink="web"
android:textColorLink="@color/lightBlue"
@ -219,7 +220,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoBlank"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:autoLink="web"
android:textColorLink="@color/lightBlue"
@ -239,7 +240,7 @@
android:layout_height="match_parent"
android:text="@string/infoTabRepoZero"
android:textIsSelectable="true"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:textColor="@color/colorWhite"/>
@ -256,7 +257,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/infoTabRepoDummyTime"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="5dp"
android:textColor="@color/colorWhite"/>
@ -284,7 +285,7 @@
android:paddingEnd="0dp"
android:autoLink="web"
android:textColorLink="@color/lightBlue"
android:textColor="@color/white"/>
android:textColor="@color/lightGray"/>
<ImageView
android:id="@+id/repoFilenameExpandCollapse"

View File

@ -1,101 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/relativeLayoutMainFrame"
android:background="@color/backgroundColor">
android:layout_margin="15dp"
android:id="@+id/milestoneFrame"
android:background="@color/backgroundColor"
android:orientation="vertical">
<LinearLayout
android:id="@+id/frameTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/milestoneTitle"
android:layout_width="0dp"
android:textIsSelectable="true"
android:layout_height="wrap_content"
android:layout_weight=".80"
android:layout_marginBottom="5dp"
android:textColor="@color/white"
android:textSize="18sp" />
<ImageView
android:id="@+id/milestoneState"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".15"
android:layout_gravity="end"
android:gravity="end"
android:contentDescription="@string/pageTitleCreateMilestone"
android:layout_marginBottom="5dp" />
</LinearLayout>
<TextView
android:id="@+id/milestoneDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/repoDescription"
android:textIsSelectable="true"
android:textColor="@color/colorWhite"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<TextView
android:id="@+id/milestoneIssuesClosed"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:text="@string/repoWatchers"
android:gravity="start"
android:textColor="@color/colorWhite"
android:textSize="14sp" />
<ProgressBar
android:id="@+id/milestoneProgress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="80"
android:progress="50"
android:layout_marginTop="2dp"
android:progressDrawable="@drawable/progress_bar"
android:progressTint="@color/colorLightGreen" />
<TextView
android:id="@+id/milestoneIssuesOpen"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:text="@string/repoStars"
android:gravity="end"
android:textColor="@color/colorWhite"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:id="@+id/milestoneFrame"
android:orientation="vertical">
<LinearLayout
android:id="@+id/frameTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/milestoneTitle"
android:layout_width="0dp"
android:textIsSelectable="true"
android:layout_height="wrap_content"
android:layout_weight=".80"
android:layout_marginBottom="5dp"
android:textColor="@color/white"
android:textSize="18sp" />
<ImageView
android:id="@+id/milestoneState"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".15"
android:layout_gravity="end"
android:gravity="end"
android:contentDescription="@string/pageTitleCreateMilestone"
android:layout_marginBottom="5dp" />
</LinearLayout>
android:orientation="horizontal">
<TextView
android:id="@+id/milestoneDescription"
android:layout_width="match_parent"
android:id="@+id/milestoneDueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/repoDescription"
android:textIsSelectable="true"
android:text="@string/repoWatchers"
android:gravity="start"
android:layout_marginTop="5dp"
android:textColor="@color/colorWhite"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<TextView
android:id="@+id/milestoneIssuesOpen"
android:layout_width="0dp"
android:layout_height="24dp"
android:layout_weight=".25"
android:drawableStart="@drawable/ic_issues"
android:drawablePadding="6dp"
android:text="@string/repoStars"
android:gravity="start"
android:textColor="@color/colorWhite"
android:textSize="16sp" />
<TextView
android:id="@+id/milestoneIssuesClosed"
android:layout_width="0dp"
android:layout_height="24dp"
android:layout_weight=".25"
android:drawableStart="@drawable/ic_issue_closed"
android:drawablePadding="6dp"
android:text="@string/repoWatchers"
android:gravity="start"
android:textColor="@color/colorWhite"
android:textSize="16sp" />
<TextView
android:id="@+id/milestoneDueDate"
android:layout_width="0dp"
android:layout_height="24dp"
android:layout_weight=".50"
android:drawableStart="@drawable/ic_calendar"
android:drawablePadding="06dp"
android:text="@string/repoWatchers"
android:gravity="start"
android:textColor="@color/colorWhite"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>

View File

@ -52,7 +52,7 @@
android:layout_weight=".05"
android:id="@+id/imageRepoTypeMy"
android:layout_width="10dp"
android:layout_height="18dp"
android:layout_height="20dp"
android:layout_gravity="end"
android:contentDescription="@string/privateAvatar"
android:src="@drawable/ic_lock_bold" />
@ -112,11 +112,11 @@
android:textSize="16sp" />
<TextView
android:id="@+id/repoWatchersMy"
android:id="@+id/repoForksMy"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_weight=".25"
android:drawableStart="@drawable/ic_watchers"
android:drawableStart="@drawable/ic_forks_24"
android:drawablePadding="6dp"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"

View File

@ -14,7 +14,6 @@
android:src="@drawable/ic_android"
android:maxHeight="24dp"
android:maxWidth="24dp"
android:layout_marginTop="5dp"
android:paddingStart="20dp"
android:paddingEnd="5dp"
android:contentDescription="@string/app_name"/>

View File

@ -2,22 +2,35 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="@color/backgroundColor"
android:paddingTop="8dp">
<TextView
android:id="@+id/adminUsers"
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/adminUsers"
android:drawableStart="@drawable/ic_users"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:id="@+id/adminUsers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/adminUsers"
android:drawableStart="@drawable/ic_users"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@ -1,22 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="@color/backgroundColor"
android:paddingTop="8dp">
<TextView
android:id="@+id/createTeam"
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/orgCreateTeam"
android:drawableStart="@drawable/ic_organizations"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:id="@+id/createTeam"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/orgCreateTeam"
android:drawableStart="@drawable/ic_organizations"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@ -22,6 +22,7 @@
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="15dp"
android:layout_marginBottom="5dp"
android:src="@drawable/ic_android"
android:contentDescription="@string/orgContentAvatar"/>

View File

@ -1,22 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="@color/backgroundColor"
android:paddingTop="8dp">
<TextView
android:id="@+id/addNewEmailAddress"
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/profileCreateNewEmailAddress"
android:drawableStart="@drawable/ic_email"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:id="@+id/addNewEmailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/profileCreateNewEmailAddress"
android:drawableStart="@drawable/ic_email"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@ -1,94 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="@color/backgroundColor"
android:paddingTop="8dp">
<TextView
android:id="@+id/newFile"
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/pageTitleNewFile"
android:drawableStart="@drawable/ic_file"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
android:layout_height="400dp">
<TextView
android:id="@+id/createNewIssue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/pageTitleCreateNewIssue"
android:drawableStart="@drawable/ic_issue_open_white"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:id="@+id/createNewMilestone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/pageTitleCreateMilestone"
android:drawableStart="@drawable/ic_milestone"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/newFile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/pageTitleNewFile"
android:drawableStart="@drawable/ic_file"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/createLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/createLabel"
android:drawableStart="@drawable/ic_label"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/createNewIssue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/pageTitleCreateNewIssue"
android:drawableStart="@drawable/ic_issue_open_white"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/createRelease"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/createRelease"
android:drawableStart="@drawable/ic_new_releases"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/createNewMilestone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/pageTitleCreateMilestone"
android:drawableStart="@drawable/ic_milestone"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/addCollaborator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/addCollaboratorTitle"
android:drawableStart="@drawable/ic_person_filled"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/createLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/createLabel"
android:drawableStart="@drawable/ic_label"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/openWebRepo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:drawableStart="@drawable/ic_open_in_browser"
android:drawablePadding="24dp"
android:padding="16dp"
android:text="@string/openWebRepo"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/createRelease"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/createRelease"
android:drawableStart="@drawable/ic_new_releases"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<View style="@style/lineDividerHorizontal" />
<TextView
android:id="@+id/addCollaborator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/addCollaboratorTitle"
android:drawableStart="@drawable/ic_person_filled"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/starRepository"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/starRepository"
android:drawableStart="@drawable/ic_star_border_24dp"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/unStarRepository"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/unStarRepository"
android:drawableStart="@drawable/ic_star"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/watchRepository"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/watchRepository"
android:drawableStart="@drawable/ic_unwatch"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<TextView
android:id="@+id/unWatchRepository"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/unWatchRepository"
android:drawableStart="@drawable/ic_watchers"
android:drawablePadding="24dp"
android:textColor="@color/white"
android:textSize="16sp"
android:padding="16dp" />
<View style="@style/lineDividerHorizontal" />
<TextView
android:id="@+id/openWebRepo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:drawableStart="@drawable/ic_open_in_browser"
android:drawablePadding="24dp"
android:padding="16dp"
android:text="@string/openWebRepo"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@ -1,119 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayoutFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/relativeLayoutMainFrame"
android:background="@color/backgroundColor">
android:layout_margin="15dp"
android:theme="@style/AppTheme"
tools:context=".activities.RepoDetailActivity">
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/relativeLayoutFrame"
<TextView
android:id="@+id/issueNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"/>
<ImageView
android:id="@+id/assigneeAvatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="15dp"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_android" />
<LinearLayout
android:id="@+id/infoSection"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:theme="@style/AppTheme"
tools:context=".activities.RepoDetailActivity">
<TextView
android:id="@+id/issueNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"/>
<ImageView
android:id="@+id/assigneeAvatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="15dp"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_android" />
<TextView
android:layout_marginTop="10dp"
android:id="@+id/issueCommentsCount"
android:layout_width="48dp"
android:layout_height="50dp"
android:width="16dp"
android:height="16dp"
android:layout_marginEnd="15dp"
android:layout_below="@+id/assigneeAvatar"
android:drawableTop="@drawable/ic_comment"
android:gravity="center"
android:textColor="@color/colorWhite"
android:textSize="14sp" />
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/assigneeAvatar"
android:orientation="vertical">
<LinearLayout
android:id="@+id/infoSection"
android:id="@+id/frameIssueNameStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/assigneeAvatar"
android:orientation="vertical">
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/issueTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".65"
android:gravity="top|center_vertical"
android:textAlignment="gravity"
android:text="@string/strFilter"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:layout_width="0dp"
android:layout_weight=".08"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/issueType"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_horizontal"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_issues" />
</LinearLayout>
<LinearLayout
android:id="@+id/frameCreatedDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/frameIssueNameStatus"
android:layout_width="match_parent"
android:id="@+id/frameCommentsCount"
android:layout_width="0dp"
android:layout_weight=".25"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/issueTitle"
android:layout_width="0dp"
android:layout_weight=".82"
android:id="@+id/issueCommentsCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:layout_width="0dp"
android:layout_weight=".08"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/issueType"
android:layout_width="24dp"
android:layout_height="24dp"
android:gravity="start"
android:drawablePadding="5dp"
android:drawableStart="@drawable/ic_comment_20"
android:layout_gravity="center_horizontal"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_issues" />
android:textColor="@color/colorWhite"
android:textSize="14sp" />
</LinearLayout>
<TextView
android:id="@+id/issueDescription"
android:layout_width="match_parent"
android:id="@+id/issueCreatedTime"
android:layout_width="0dp"
android:layout_weight=".15"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="end"
android:textColor="@color/colorWhite"
android:textSize="16sp"
android:visibility="gone" />
<LinearLayout
android:id="@+id/frameCreatedDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/issueCreatedAtText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/createdText"
android:textColor="@color/colorWhite"
android:textSize="12sp" />
<TextView
android:id="@+id/issueCreatedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:textSize="12sp" />
</LinearLayout>
android:textSize="14sp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>

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