Compare commits
328 Commits
2.5.1
...
7-assign-t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71d7f543a6 | ||
|
|
244dc12fc3 | ||
|
|
8ea7e470c5 | ||
|
|
77edf450c6 | ||
|
|
e0ff35d530 | ||
|
|
f88a2df749 | ||
|
|
bb392fb639 | ||
|
|
6a6ecd251a | ||
|
|
1693acaa70 | ||
|
|
1e8c8efd6b | ||
|
|
5544ae4248 | ||
|
|
36f20bb1aa | ||
|
|
0e696eb46f | ||
|
|
2b3b0fbe0f | ||
|
|
f96827488b | ||
|
|
8d0df59bfe | ||
|
|
d567a012d8 | ||
|
|
0fc845e058 | ||
|
|
b97fa45b18 | ||
|
|
d458d60122 | ||
|
|
881aad5f2d | ||
|
|
547e7c705d | ||
|
|
cc70fe9a68 | ||
|
|
3b3b0ada2f | ||
|
|
a9f1010add | ||
|
|
c8872ade9f | ||
|
|
960eaa1cf9 | ||
|
|
224ead33bf | ||
|
|
1dd615fcae | ||
|
|
36808b1dbb | ||
|
|
8741074906 | ||
|
|
23b8301fbf | ||
|
|
cd902ff1ca | ||
|
|
d72f097012 | ||
|
|
9d3cd49d23 | ||
|
|
e8f938bdb0 | ||
|
|
27a4bab73c | ||
|
|
8312983ed3 | ||
|
|
69a5f00771 | ||
|
|
8104889bf6 | ||
|
|
bd3e6ff20a | ||
|
|
a384128c8f | ||
|
|
a47be21017 | ||
|
|
4b140f3195 | ||
|
|
4ccc66b04e | ||
|
|
7c6247782b | ||
|
|
3e5fca4f52 | ||
|
|
a848cabcda | ||
|
|
0b8d8618ed | ||
|
|
62ce30db23 | ||
|
|
dc29a31e63 | ||
|
|
98cf1a1976 | ||
|
|
69b7984d85 | ||
|
|
ef3108db14 | ||
|
|
f1c88921bc | ||
|
|
26b623a35b | ||
|
|
fb0bd0299c | ||
|
|
c353275ab8 | ||
|
|
328dbaa01c | ||
|
|
ff915f1813 | ||
|
|
77e39952c1 | ||
|
|
afffb7c15a | ||
|
|
47d6c68410 | ||
|
|
57ce453661 | ||
|
|
d8a14105c9 | ||
|
|
711711274e | ||
|
|
44b8ad8d1c | ||
|
|
fc49e29703 | ||
|
|
7f8595defc | ||
|
|
eb858f3535 | ||
|
|
29653cade2 | ||
|
|
df3e1b9940 | ||
|
|
d72cd57cd7 | ||
|
|
1d15f9b1d2 | ||
|
|
cb241d80f3 | ||
|
|
3c381f372e | ||
|
|
2398995928 | ||
|
|
7faf800d02 | ||
|
|
1e838031e1 | ||
|
|
d0c06a65f4 | ||
|
|
c6ebca8a08 | ||
|
|
20b203c4ad | ||
|
|
b02c87b143 | ||
|
|
093204df43 | ||
|
|
a26737e510 | ||
|
|
371649b8ca | ||
|
|
5b92be3a28 | ||
|
|
8c62ecadbc | ||
|
|
b75bf84d43 | ||
|
|
5d2bb02b2d | ||
|
|
fef1597522 | ||
|
|
1f9a3eb85d | ||
|
|
a51ba4f2a8 | ||
|
|
4c4a7376cb | ||
|
|
bbbcb56b98 | ||
|
|
b871a1fb22 | ||
|
|
f2bc81210c | ||
|
|
a6e97a1b36 | ||
|
|
2ebcdf9186 | ||
|
|
272fc78df9 | ||
|
|
3aa819f3ef | ||
|
|
e9fa2984a1 | ||
|
|
240cdf5701 | ||
|
|
a170c10e43 | ||
|
|
d11da92fc4 | ||
|
|
3b53111981 | ||
|
|
ade7b797f1 | ||
|
|
f97f668363 | ||
|
|
639cf51027 | ||
|
|
a92da6a6d4 | ||
|
|
87379ae0b2 | ||
|
|
43166237ee | ||
|
|
a3bd5c2af2 | ||
|
|
0f5858f292 | ||
|
|
dcec158076 | ||
|
|
63d3c95501 | ||
|
|
f111f7f2df | ||
|
|
5807d11e8c | ||
|
|
4a9bde8731 | ||
|
|
f64e23dcc1 | ||
|
|
6a9144435e | ||
|
|
3c7b505b5b | ||
|
|
2064c40c7d | ||
|
|
65c0ecaad1 | ||
|
|
99925621f1 | ||
|
|
d3fe4d6d41 | ||
|
|
8e86fa668d | ||
|
|
044f6191bf | ||
|
|
9e19945ad4 | ||
|
|
fbd92eb06b | ||
|
|
cafb29f8b7 | ||
|
|
f727ec51b8 | ||
|
|
d346d68b4f | ||
|
|
57f0d23ef0 | ||
|
|
1e30c37d7c | ||
|
|
829320ca0c | ||
|
|
1bf023357b | ||
|
|
4d1d7a7204 | ||
|
|
3235caf07d | ||
|
|
0f014c2822 | ||
|
|
996983d7a3 | ||
|
|
00cfcbc9cf | ||
|
|
74669a9dcb | ||
|
|
d52d7a188e | ||
|
|
d20a773d1d | ||
|
|
bf19e52799 | ||
|
|
8612258174 | ||
|
|
a31abf0974 | ||
|
|
6d466e2542 | ||
|
|
01bd61ad8e | ||
|
|
4031c32fc8 | ||
|
|
d51d2d5164 | ||
|
|
7b8bc21a83 | ||
|
|
1c1f73eafc | ||
|
|
02672aef3d | ||
|
|
23fb1ce71f | ||
|
|
1f5eeb5632 | ||
|
|
78782d159a | ||
|
|
a009e5dac9 | ||
|
|
a75ffe0381 | ||
|
|
c4279dcd77 | ||
|
|
14b1256ce1 | ||
|
|
7b72815bcb | ||
|
|
5e6c600e71 | ||
|
|
dbf5be25a5 | ||
|
|
2bfe0b8d1a | ||
|
|
0c92eb3fa2 | ||
|
|
32f3080283 | ||
|
|
7342668a1b | ||
|
|
6f9bbe4c58 | ||
|
|
b2b42887f7 | ||
|
|
37f622b952 | ||
|
|
d677c90b01 | ||
|
|
23d3ba7f42 | ||
|
|
a42d888eb7 | ||
|
|
bbcffd67d6 | ||
|
|
00eb9c9135 | ||
|
|
28a23d30f8 | ||
|
|
82f874dc37 | ||
|
|
b60a0e7a92 | ||
|
|
185bdb863d | ||
|
|
da338fcc83 | ||
|
|
6d8a87358d | ||
|
|
5fc6cdde63 | ||
|
|
dc6b1bb5b6 | ||
|
|
8768c87b8a | ||
|
|
7caff70946 | ||
|
|
76137c56bc | ||
|
|
dcacf1f141 | ||
|
|
7585eb4834 | ||
|
|
7dd231ee95 | ||
|
|
d5fd6d8cc4 | ||
|
|
28963bb079 | ||
|
|
87649ebae8 | ||
|
|
a92969a47f | ||
|
|
d9cd04facf | ||
|
|
3eacfe91fe | ||
|
|
e38d141d38 | ||
|
|
7c40c049d4 | ||
|
|
b4b7981722 | ||
|
|
96fad2d73e | ||
|
|
24064192e4 | ||
|
|
12a7b6040b | ||
|
|
30921ea330 | ||
|
|
ea36a3f6d6 | ||
|
|
f1ecc42876 | ||
|
|
73e7acfbdf | ||
|
|
a9ad91d954 | ||
|
|
ff537b79ff | ||
|
|
7efc8650fa | ||
|
|
a171abc0b8 | ||
|
|
0928e936d7 | ||
|
|
a29011c6a2 | ||
|
|
c09fc4988a | ||
|
|
39ac49b258 | ||
|
|
cd55f946f0 | ||
|
|
b529f81115 | ||
|
|
e6109ef36d | ||
|
|
e00fcd846a | ||
|
|
060c86c090 | ||
|
|
26f54280a1 | ||
|
|
8a7923cba7 | ||
|
|
673b9f564c | ||
|
|
d1be03956c | ||
|
|
caa437d5e3 | ||
|
|
25036ce5d2 | ||
|
|
a8a34ccc7a | ||
|
|
f87e8020d8 | ||
|
|
4d67e63db4 | ||
|
|
3561dde19f | ||
|
|
9c48dec54d | ||
|
|
3d72d68e14 | ||
|
|
47b24470e6 | ||
|
|
1db6a3294b | ||
|
|
500dc019c1 | ||
|
|
e2aff890d7 | ||
|
|
cdfc2cfb9e | ||
|
|
f135508745 | ||
|
|
3e5e94790e | ||
|
|
62aace4b91 | ||
|
|
2412245a9f | ||
|
|
e872069093 | ||
|
|
5672208fd0 | ||
|
|
7379e9945d | ||
|
|
815417bf11 | ||
|
|
95fc5e1e9a | ||
|
|
f285d47a0b | ||
|
|
2483968f11 | ||
|
|
d0fde4e791 | ||
|
|
c7c2ac2a11 | ||
|
|
4f79ea0156 | ||
|
|
22943ca9cd | ||
|
|
5a10127c1c | ||
|
|
7de29687eb | ||
|
|
1a95475140 | ||
|
|
d2265aecae | ||
|
|
626746be8b | ||
|
|
f21f23c1f0 | ||
|
|
5005fcc5b5 | ||
|
|
008e446b93 | ||
|
|
50e0142f6c | ||
|
|
42640f2d1c | ||
|
|
4a8ee2ea96 | ||
|
|
acc55e3433 | ||
|
|
e267aa5100 | ||
|
|
5e41469452 | ||
|
|
55473701b8 | ||
|
|
546346ff48 | ||
|
|
4f0091f151 | ||
|
|
37367e142f | ||
|
|
8b1c79c0c3 | ||
|
|
bf26a44376 | ||
|
|
6721b09de9 | ||
|
|
0f9e130cf4 | ||
|
|
014b06cc46 | ||
|
|
6654b6fb48 | ||
|
|
f1eb632d9b | ||
|
|
34f8f82b63 | ||
|
|
b30e2da387 | ||
|
|
6b3ac84113 | ||
|
|
9541ef7dbc | ||
|
|
6a6bbef63d | ||
|
|
dc168a732b | ||
|
|
d06f5353c6 | ||
|
|
1b213783bc | ||
|
|
e83b9eb736 | ||
|
|
ad7c3696d5 | ||
|
|
7bfdfa3223 | ||
|
|
0f38d81cd0 | ||
|
|
dd92ef9732 | ||
|
|
408fd9627b | ||
|
|
3de4dd9463 | ||
|
|
7f0689524f | ||
|
|
a4afa5fbc2 | ||
|
|
29756511f3 | ||
|
|
56d8cd0fac | ||
|
|
4e6057171b | ||
|
|
ab8a5ed505 | ||
|
|
a6b424f5ff | ||
|
|
e5d6fd3b41 | ||
|
|
5d1efe0f3f | ||
|
|
c41ab845fd | ||
|
|
e45dc4b311 | ||
|
|
7c53de363d | ||
|
|
f352f175dd | ||
|
|
d1a5c9c897 | ||
|
|
51a7bca889 | ||
|
|
03528f653a | ||
|
|
9d182821d2 | ||
|
|
195bfc8fe2 | ||
|
|
2e89fb0054 | ||
|
|
48abe71645 | ||
|
|
eca46b7913 | ||
|
|
6736fa2f5d | ||
|
|
bbf41988d5 | ||
|
|
aa3288e889 | ||
|
|
92a0d06b75 | ||
|
|
4e7fd6295e | ||
|
|
0ee5b43996 | ||
|
|
625e60f2e2 | ||
|
|
3fb063b0b1 | ||
|
|
d7ef368f0b | ||
|
|
dd1fce892a | ||
|
|
f39357f596 | ||
|
|
3bfc6b94a4 | ||
|
|
996d5d5fea | ||
|
|
af6cbfdb66 | ||
|
|
01e451556e |
65
.drone.yml
65
.drone.yml
@@ -1,40 +1,84 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: gitnex-ci-test
|
||||
type: docker
|
||||
name: tests
|
||||
|
||||
steps:
|
||||
|
||||
- name: test
|
||||
- name: unit-tests
|
||||
image: nextcloudci/android:android-49
|
||||
depends_on: [ clone ]
|
||||
commands:
|
||||
- ./gradlew test
|
||||
|
||||
- name: check-formatting
|
||||
image: zosiab/eclint:latest
|
||||
depends_on: [ clone ]
|
||||
commands:
|
||||
- git pull origin main
|
||||
- eclint check $(git diff --name-only origin/main)
|
||||
|
||||
# This may be used in the future, because it makes of intellij's native code inspection/formatting capabilities.
|
||||
# Additional information: https://www.jetbrains.com/help/idea/command-line-formatter.html
|
||||
#
|
||||
# - name: do-or-check-formatting
|
||||
# image: dlsniper/docker-intellij
|
||||
# depends_on: [ clone ]
|
||||
# commands:
|
||||
# - /opt/intellij/bin/idea.sh inspect/format ...
|
||||
#
|
||||
# - name: do-or-check-formatting
|
||||
# image: dlsniper/docker-intellij
|
||||
# depends_on: [ clone ]
|
||||
# commands:
|
||||
# - /opt/intellij/bin/idea.sh format -s .idea/codeStyles/Project.xml -m *.java app/src/main/java
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: gitnex-ci-build
|
||||
type: docker
|
||||
name: code-analysis
|
||||
|
||||
steps:
|
||||
|
||||
- name: check-global-formatting
|
||||
image: zosiab/eclint:latest
|
||||
depends_on: [ clone ]
|
||||
commands:
|
||||
- eclint check $(git ls-files)
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- main
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: build
|
||||
|
||||
steps:
|
||||
|
||||
- name: build
|
||||
image: nextcloudci/android:android-49
|
||||
commands:
|
||||
- ./gradlew build
|
||||
- ./gradlew assembleFreeRelease
|
||||
|
||||
- name: sign
|
||||
image: nextcloudci/android:android-49
|
||||
environment:
|
||||
TOKEN:
|
||||
BOT_TOKEN:
|
||||
from_secret: BOT_TOKEN
|
||||
KS_PASS:
|
||||
from_secret: KS_PASS
|
||||
KEY_PASS:
|
||||
from_secret: KEY_PASS
|
||||
OUTPUT: signed.apk
|
||||
GITEA: https://gitea.com
|
||||
INSTANCE: https://codeberg.org
|
||||
KS_FILE: ci_keystore.jks
|
||||
KS_REPO:
|
||||
from_secret: KS_REPO
|
||||
@@ -47,11 +91,14 @@ steps:
|
||||
WEBDAV_USERNAME: GitNexBot
|
||||
WEBDAV_PASSWORD:
|
||||
from_secret: NC_TOKEN
|
||||
PLUGIN_FILE: signed.apk
|
||||
PLUGIN_DESTINATION: https://cloud.swatian.com/remote.php/dav/files/GitNexBot/GitNex-Builds/latest.apk
|
||||
PLUGIN_FILE: 'signed.apk'
|
||||
PLUGIN_TIMEOUT: 180
|
||||
PLUGIN_ATTEMPTS: 5
|
||||
PLUGIN_DESTINATION: 'https://cloud.swatian.com/remote.php/dav/files/GitNexBot/gitnex/builds/latest.apk'
|
||||
PLUGIN_CUSTOM_ARGUMENTS: '--progress-bar'
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- master
|
||||
- main
|
||||
|
||||
25
.editorconfig
Normal file
25
.editorconfig
Normal file
@@ -0,0 +1,25 @@
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 150
|
||||
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
line_comment = //
|
||||
block_comment_start = /*
|
||||
block_comment = *
|
||||
block_comment_end = */
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
|
||||
[{*.yml,*.yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
||||
@@ -1,31 +1,37 @@
|
||||
## # What do you want to address?
|
||||
(This step is required; examples are shown below)
|
||||
<!-- This step is required; examples are shown below -->
|
||||
|
||||
- [ ] Bug
|
||||
- [ ] Feature
|
||||
- [ ] Suggestion
|
||||
|
||||
## # Describe your matter briefly
|
||||
(This step is required)
|
||||
<!-- This step is required. -->
|
||||
<br><br>
|
||||
|
||||
|
||||
##### What did you expect? (Useful when addressing bugs)
|
||||
##### What did you expect? <!-- Useful when addressing bugs -->
|
||||
---
|
||||
_(This step is optional)_
|
||||
<!-- This step is optional. -->
|
||||
<br><br>
|
||||
|
||||
|
||||
##### Some additional details (Useful, when we are trying to reproduce a bug)
|
||||
##### Some additional details <!-- Useful, when we are trying to reproduce a bug -->
|
||||
---
|
||||
_(This step is optional; an example is shown below)_
|
||||
<!-- This step is optional; an example is shown below -->
|
||||
|
||||
* The version of **Gitea** you are using:
|
||||
* The version of **GitNex** you are using:
|
||||
* The type of certificate you are using (self-signed, signed):
|
||||
* Source of installation (Play Store, F-Droid, APK):
|
||||
* Current android version and phone model/manufacturer:
|
||||
* The type of certificate your instance is using (self-signed, signed):
|
||||
* How you used to log in (via password or token):
|
||||
|
||||
<br>
|
||||
|
||||
##### We would appreciate some screenshots or stacktrace's, but this is also not required.
|
||||
---
|
||||
_(Screenshots and stacktrace's can go here)_
|
||||
<!-- Screenshots and stacktrace's can go here. -->
|
||||
<br><br>
|
||||
|
||||
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
|
||||
<br>
|
||||
|
||||
#### Thank you for your time.
|
||||
@@ -1,8 +1,9 @@
|
||||
Please check the following:
|
||||
### Describe what your pull request does and which issue you’re targeting
|
||||
<!-- Create a new issue, if it doesn't exist yet -->
|
||||
<br><br>
|
||||
|
||||
1. Make sure you are targeting the `master` branch, pull requests on release branches are only allowed for bug fixes.
|
||||
2. Read contributing guidelines: [CONTRIBUTING.md](https://gitea.com/GitNex/GitNex/src/branch/master/CONTRIBUTING.md)
|
||||
3. Please follow the [Code-Standards](https://gitea.com/gitnex/GitNex/wiki/Code-Standards)
|
||||
4. Describe what your pull request does and which issue you’re targeting (create one if does not exist)
|
||||
<!-- Make sure you are targeting the "main" branch, pull requests on release branches are only allowed for bug fixes. -->
|
||||
|
||||
**You MUST delete the content above including this line before posting, otherwise your pull request will be invalid.**
|
||||
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
|
||||
- [ ] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards).
|
||||
- [ ] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/main/LICENSE).
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -11,6 +11,9 @@
|
||||
# Release dir
|
||||
app/release/*
|
||||
|
||||
# Pro dir
|
||||
app/pro/*
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
@@ -192,3 +195,6 @@ crowdin.yml
|
||||
!/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# End of https://www.gitignore.io/api/android,androidstudio
|
||||
|
||||
# Crowdin Config
|
||||
crowdin.yml
|
||||
|
||||
100
.gitlab-ci.yml
Normal file
100
.gitlab-ci.yml
Normal file
@@ -0,0 +1,100 @@
|
||||
stages:
|
||||
- build
|
||||
- sign
|
||||
- publish
|
||||
|
||||
on_setup:
|
||||
image: curlimages/curl:7.77.0
|
||||
stage: .pre
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
variables:
|
||||
INSTANCE: "https://codeberg.org"
|
||||
MAIN_REPO: gitnex/GitNex
|
||||
STATE: pending
|
||||
script:
|
||||
- ./scripts/add-commit-status.sh
|
||||
|
||||
build:
|
||||
image: nextcloudci/android:android-54
|
||||
stage: build
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
script:
|
||||
- ./gradlew assembleFreeRelease
|
||||
artifacts:
|
||||
paths:
|
||||
- app/build/outputs/
|
||||
expire_in: 15 minutes
|
||||
|
||||
sign:
|
||||
image: nextcloudci/android:android-54
|
||||
stage: sign
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
variables:
|
||||
OUTPUT: "signed.apk"
|
||||
INSTANCE: "https://codeberg.org"
|
||||
KS_FILE: "ci_keystore.jks"
|
||||
script:
|
||||
- ./scripts/sign-build.sh
|
||||
artifacts:
|
||||
paths:
|
||||
- signed.apk
|
||||
expire_in: 15 minutes
|
||||
|
||||
latest:
|
||||
image: curlimages/curl:7.77.0
|
||||
stage: publish
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
variables:
|
||||
WEBDAV_USERNAME: "GitNexBot"
|
||||
PLUGIN_FILE: "signed.apk"
|
||||
PLUGIN_DESTINATION: "https://cloud.swatian.com/remote.php/dav/files/GitNexBot/gitnex/builds/latest.apk"
|
||||
script:
|
||||
- curl -T "$PLUGIN_FILE" -u "$WEBDAV_USERNAME":"$WEBDAV_PASSWORD" "$PLUGIN_DESTINATION"
|
||||
|
||||
release:
|
||||
image: curlimages/curl:7.77.0
|
||||
stage: publish
|
||||
only:
|
||||
- tags
|
||||
variables:
|
||||
WEBDAV_USERNAME: "GitNexBot"
|
||||
PLUGIN_FILE: "signed.apk"
|
||||
script:
|
||||
- "[[ $CI_COMMIT_REF_NAME == *'-rc'* ]] && echo 'Upload blocked. Build seems to be a release candidate.' && exit 0"
|
||||
- curl -T "$PLUGIN_FILE" -u "$WEBDAV_USERNAME":"$WEBDAV_PASSWORD" 'https://cloud.swatian.com/remote.php/dav/files/GitNexBot/gitnex/releases/'"$CI_COMMIT_REF_NAME"'.apk'
|
||||
|
||||
on_success:
|
||||
image: curlimages/curl:7.77.0
|
||||
stage: .post
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
variables:
|
||||
INSTANCE: "https://codeberg.org"
|
||||
MAIN_REPO: gitnex/GitNex
|
||||
STATE: success
|
||||
script:
|
||||
- ./scripts/add-commit-status.sh
|
||||
when: on_success
|
||||
|
||||
on_failure:
|
||||
image: curlimages/curl:7.77.0
|
||||
stage: .post
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
variables:
|
||||
INSTANCE: "https://codeberg.org"
|
||||
MAIN_REPO: gitnex/GitNex
|
||||
STATE: failure
|
||||
script:
|
||||
- ./scripts/add-commit-status.sh
|
||||
when: on_failure
|
||||
28
.idea/codeStyles/Project.xml
generated
28
.idea/codeStyles/Project.xml
generated
@@ -16,6 +16,24 @@
|
||||
</value>
|
||||
</option>
|
||||
</JavaCodeStyleSettings>
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value>
|
||||
<package name="java.util" alias="false" withSubpackages="false" />
|
||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="java" alias="false" withSubpackages="true" />
|
||||
<package name="javax" alias="false" withSubpackages="true" />
|
||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="RIGHT_MARGIN" value="220" />
|
||||
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||
@@ -29,6 +47,7 @@
|
||||
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
|
||||
@@ -36,8 +55,13 @@
|
||||
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
|
||||
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="THROWS_LIST_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="WRAP_ON_TYPING" value="1" />
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
<option name="SMART_TABS" value="true" />
|
||||
@@ -156,4 +180,4 @@
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
</component>
|
||||
@@ -1,2 +1,2 @@
|
||||
# Changelog
|
||||
[Check out the release notes](https://gitea.com/gitnex/GitNex/releases)
|
||||
[Check out the release notes](https://codeberg.org/gitnex/GitNex/releases)
|
||||
|
||||
@@ -2,26 +2,35 @@
|
||||
|
||||
Please take a few minutes to read this document to make the process of contribution more easy and healthy for all involved.
|
||||
|
||||
## Pull Requests
|
||||
Patches, enhancements, features are always welcome. The PR should focus on the scope of work and avoid many unnecessary commits. Please provide as much detail and context as possible to explain the work submitted.
|
||||
### General
|
||||
> **Be polite and gentle while commenting or creating new issues to maintain a healthy environment in which __everyone__ is able to feel comfortable.**
|
||||
<br>
|
||||
|
||||
Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work.
|
||||
### Issues and Reports
|
||||
Before creating an issue please take a moment and search the repository issues(open/closed) to avoid duplicate issues either it's a bug or feature.
|
||||
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.<br><br>
|
||||
**Note:** Please contact the project directly via [email](mailto:gitnex@swatian.com) if have to share sensitive and security related details.
|
||||
<br>
|
||||
|
||||
**Code Standards**
|
||||
### Pull Requests
|
||||
Patches, enhancements and features are always welcome.
|
||||
The PR should focus on the scope of work and avoid many unnecessary commits.
|
||||
Please provide as much detail and context as possible to explain the work submitted.
|
||||
|
||||
**Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work.** (Submit an issue, __before__ submitting a PR)
|
||||
|
||||
**Code Standards**<br><br>
|
||||
Please follow the code standards, this will help other developers to understand your code too.
|
||||
It also helps maintaining the code afterwards.
|
||||
It is documented in the Wiki: [Code-Standards](https://gitea.com/gitnex/GitNex/wiki/Code-Standards)
|
||||
It is documented in the Wiki: [Code-Standards](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards)
|
||||
|
||||
**How to submit a PR**
|
||||
Fork this repository. Pull the forked repository from your namespace to your local machine. Create new branch and work on the bug/feature/enhancement you would like to submit. Push it to your forked version. From there create Pull Request(PR) against **master** branch.
|
||||
**How to submit a PR (Pull Request)**
|
||||
1. Fork this repository.
|
||||
2. Clone the forked repository from your namespace to your local machine.
|
||||
3. Create a new branch and work on your feature, enhancement or patch.
|
||||
4. Push your commits to your forked version.
|
||||
5. You can now create a PR using the web interface against **main** branch.
|
||||
|
||||
**IMPORTANT:** By submitting PR, you agree to allow GitNex to license your work under the same license as that used by GitNex.
|
||||
For more information, click [here](http://makeapullrequest.com/).
|
||||
|
||||
## Issues and Reports
|
||||
*1st of please be polite and gentle while commenting or creating new issue to maintain a healthy environment.*
|
||||
|
||||
Before creating an issue please take a moment and search the repository issues(open/closed) to avoid duplicate issues either it's a bug or feature.
|
||||
|
||||
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.
|
||||
**IMPORTANT:** By submitting PR, you agree to allow GitNex to license your work under the same license as that used by GitNex.
|
||||
@@ -3,6 +3,7 @@ This part lists all PUBLIC individuals having contributed content to the code.
|
||||
|
||||
* M M Arif (mmarif)
|
||||
* 6543
|
||||
* opyale
|
||||
* Unpublished
|
||||
|
||||
# Translators
|
||||
|
||||
63
LICENSE
63
LICENSE
@@ -1,7 +1,7 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -620,55 +620,18 @@ copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
GitNex is an Android client/application for Gitea.
|
||||
Copyright (C) 2019 The GitNex Authors
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Mastalab is a Mastodon client for Android devices
|
||||
Copyright (C) 2017 Thomas Schneider
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
Mastalab Copyright (C) 2017 Thomas Schneider
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
100
README.md
100
README.md
@@ -1,97 +1,99 @@
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://gitea.com/gitnex/GitNex/releases)
|
||||
[](https://drone.gitea.com/gitnex/GitNex)
|
||||
[](https://crowdin.com/project/gitnex)
|
||||
[](https://discord.gg/FbSS4rf)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0) [](https://gitlab.com/opyale/gitnex/-/pipelines) [](https://codeberg.org/gitnex/GitNex/releases) [](https://crowdin.com/project/gitnex) [](https://discord.gg/FbSS4rf)
|
||||
|
||||
[<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif)
|
||||
[<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate)
|
||||
|
||||
# GitNex - Android client for Gitea
|
||||
|
||||
GitNex is a free, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go.
|
||||
GitNex is a free/paid, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go.
|
||||
|
||||
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text.
|
||||
No trackers are used and source code is available here for anyone to audit.
|
||||
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. **No trackers are used** and source code is available here for anyone to audit.
|
||||
|
||||
## 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)
|
||||
[<img alt='Download APK' src='https://gitnex.com/img/download-apk.png' height="80"/>](https://gitea.com/gitnex/GitNex/releases)
|
||||
[<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex.pro)
|
||||
[<img alt='Download builds and releases' src='https://codeberg.org/gitnex/GitNex/raw/branch/main/assets/apk-badge.png' height="82"/>](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE)
|
||||
|
||||
## Note about Gitea version
|
||||
Please make sure that you are on latest stable release or later for better app experience.
|
||||
|
||||
Check the versions [compatibility page](https://gitea.com/gitnex/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio.
|
||||
Check the versions [compatibility page](https://codeberg.org/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.
|
||||
|
||||
Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew build`.
|
||||
Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew assembleFree`.
|
||||
|
||||
## Features
|
||||
- Multiple accounts support
|
||||
- File and directory browser
|
||||
- File viewer
|
||||
- Create files
|
||||
- Explore repositories
|
||||
- Issues list
|
||||
- Pull requests
|
||||
- Merge pull request
|
||||
- [MANY MORE](https://gitea.com/gitnex/GitNex/wiki/Features)
|
||||
- Files diff for PRs
|
||||
- Notifications
|
||||
- Drafts
|
||||
- Repositories / issues / org list
|
||||
- [MANY MORE](https://codeberg.org/gitnex/GitNex/wiki/Features)
|
||||
|
||||
## Contributing
|
||||
[CONTRIBUTING](https://gitea.com/gitnex/GitNex/src/branch/master/CONTRIBUTING.md)
|
||||
[CONTRIBUTING](https://codeberg.org/gitnex/GitNex/src/branch/main/CONTRIBUTING.md)
|
||||
|
||||
## Translation
|
||||
Help us translate GitNex to your native language.
|
||||
|
||||
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.
|
||||
We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your language is not listed, please request [here](https://codeberg.org/gitnex/GitNex/issues) to add it to the project.
|
||||
|
||||
**Link: https://crowdin.com/project/GitNex**
|
||||
|
||||
## Screenshots:
|
||||
|
||||
<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://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/001.png" alt="001.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/002.png" alt="002.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/003.png" alt="003.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/004.png" alt="004.png" width="200"/>
|
||||
---|---|---|---
|
||||
<img src="https://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/gitnex/GitNex/wiki/FAQ)
|
||||
<img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/005.png" alt="005.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/006.png" alt="006.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/007.png" alt="007.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/008.png" alt="008.png" width="200"/>
|
||||
|
||||
## Links
|
||||
[Website](https://gitnex.com)
|
||||
|
||||
[Wiki](https://gitea.com/gitnex/GitNex/wiki/Home)
|
||||
[Wiki](https://codeberg.org/gitnex/GitNex/wiki/Home)
|
||||
|
||||
[Website Repository](https://gitlab.com/mmarif4u/gitnex-website)
|
||||
|
||||
[Troubleshoot Guide](https://gitea.com/gitnex/GitNex/wiki/Troubleshoot-Guide)
|
||||
[Troubleshoot Guide](https://codeberg.org/gitnex/GitNex/wiki/Troubleshoot-Guide)
|
||||
|
||||
[Faq](https://codeberg.org/gitnex/GitNex/wiki/FAQ)
|
||||
|
||||
[Release Blog](https://gitnex.codeberg.page)
|
||||
|
||||
## Thanks
|
||||
Thanks to all the open source libraries, contributors and donators.
|
||||
|
||||
Open source libraries
|
||||
- Retrofit
|
||||
- Gson
|
||||
- Okhttp
|
||||
- ViHtarb/tooltip
|
||||
- Picasso
|
||||
- Markwon
|
||||
- Prettytime
|
||||
- Amulyakhare/textdrawable
|
||||
- Vdurmont/emoji-java
|
||||
- Abumoallim/android-multi-select-dialog
|
||||
- Pes/materialcolorpicker
|
||||
- Hendraanggrian/socialview
|
||||
- HamidrezaAmz/BreadcrumbsView
|
||||
- Chrisbanes/PhotoView
|
||||
- Pddstudio/highlightjs-android
|
||||
- Apache/commons-io
|
||||
- Caverock/androidsvg
|
||||
- Droidsonroids.gif/android-gif-drawable
|
||||
- Barteksc/AndroidPdfViewer
|
||||
- Mikepenz/fastadapter
|
||||
- Ge0rg/MemorizingTrustManager
|
||||
#### Open source libraries
|
||||
- [square/retrofit](https://github.com/square/retrofit)
|
||||
- [google/gson](https://github.com/google/gson)
|
||||
- [square/okhttp](https://github.com/square/okhttp)
|
||||
- [square/picasso](https://github.com/square/picasso)
|
||||
- [wasabeef/picasso-transformations](https://github.com/wasabeef/picasso-transformations)
|
||||
- [cats-oss/android-gpuimage](https://github.com/cats-oss/android-gpuimage)
|
||||
- [noties/Markwon](https://github.com/noties/Markwon)
|
||||
- [noties/Prism4j](https://github.com/noties/Prism4j)
|
||||
- [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime)
|
||||
- [amulyakhare/TextDrawable](https://github.com/amulyakhare/TextDrawable)
|
||||
- [vdurmont/emoji-java](https://github.com/vdurmont/emoji-java)
|
||||
- [Pes8/android-material-color-picker-dialog](https://github.com/Pes8/android-material-color-picker-dialog)
|
||||
- [HamidrezaAmz/BreadcrumbsView](https://github.com/HamidrezaAmz/BreadcrumbsView)
|
||||
- [Baseflow/PhotoView](https://github.com/Baseflow/PhotoView)
|
||||
- [apache/commons](https://github.com/apache/commons-io)
|
||||
- [ge0rg/MemorizingTrustManager](https://github.com/ge0rg/MemorizingTrustManager)
|
||||
- [mikaelhg/urlbuilder](https://github.com/mikaelhg/urlbuilder)
|
||||
- [ACRA/acra](https://github.com/ACRA/acra)
|
||||
- [chrisvest/stormpot](https://github.com/chrisvest/stormpot)
|
||||
|
||||
#### Icon sets
|
||||
- [feathericons/feather](https://github.com/feathericons/feather)
|
||||
- [primer/octicons](https://github.com/primer/octicons)
|
||||
- [google/material-design-icons](https://github.com/google/material-design-icons)
|
||||
|
||||
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)
|
||||
|
||||
*All trademarks and logos are the properties of their respective owners.*
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 30
|
||||
defaultConfig {
|
||||
applicationId "org.mian.gitnex"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
versionCode 251
|
||||
versionName "2.5.1"
|
||||
targetSdkVersion 30
|
||||
versionCode 405
|
||||
versionName "4.1.0-dev"
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
dexOptions {
|
||||
javaMaxHeapSize "4g"
|
||||
}
|
||||
flavorDimensions "default"
|
||||
productFlavors {
|
||||
free {
|
||||
applicationId "org.mian.gitnex"
|
||||
}
|
||||
pro {
|
||||
applicationId "org.mian.gitnex.pro"
|
||||
}
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
@@ -22,8 +38,13 @@ android {
|
||||
abortOnError false
|
||||
}
|
||||
compileOptions {
|
||||
targetCompatibility = "8"
|
||||
sourceCompatibility = "8"
|
||||
coreLibraryDesugaringEnabled true
|
||||
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
defaultConfig{
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,30 +54,32 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
def lifecycle_version = "2.2.0"
|
||||
def markwon_version = '4.3.1'
|
||||
def fastadapter = "3.3.1"
|
||||
def acra = "5.5.0"
|
||||
def lifecycle_version = '2.3.1'
|
||||
def markwon_version = '4.6.2'
|
||||
def work_version = "2.7.0-alpha05"
|
||||
def acra = "5.7.0"
|
||||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation "androidx.appcompat:appcompat:1.1.0"
|
||||
implementation "com.google.android.material:material:1.2.0-alpha06"
|
||||
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||
implementation 'androidx.appcompat:appcompat:1.4.0-alpha03'
|
||||
implementation 'com.google.android.material:material:1.4.0'
|
||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
|
||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
testImplementation "junit:junit:4.13"
|
||||
androidTestImplementation "androidx.test:runner:1.2.0"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
|
||||
implementation "com.github.vihtarb:tooltip:0.2.0"
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.5.0'
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test:runner:1.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2'
|
||||
implementation "com.google.code.gson:gson:2.8.6"
|
||||
implementation "com.squareup.picasso:picasso:2.71828"
|
||||
implementation 'jp.wasabeef:picasso-transformations:2.4.0'
|
||||
implementation 'jp.co.cyberagent.android:gpuimage:2.1.0'
|
||||
implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1"
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
|
||||
implementation 'com.squareup.retrofit2:converter-scalars:2.8.1'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:4.5.0'
|
||||
implementation 'org.ocpsoft.prettytime:prettytime:4.0.4.Final'
|
||||
implementation "com.vdurmont:emoji-java:5.1.1"
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2'
|
||||
implementation 'org.ocpsoft.prettytime:prettytime:5.0.0.Final'
|
||||
implementation "com.pes.materialcolorpicker:library:1.2.5"
|
||||
implementation "io.noties.markwon:core:$markwon_version"
|
||||
implementation "io.noties.markwon:ext-latex:$markwon_version"
|
||||
@@ -71,23 +94,24 @@ dependencies {
|
||||
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.19"
|
||||
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 "io.noties.markwon:image-picasso:$markwon_version"
|
||||
implementation "io.noties:prism4j:2.0.0"
|
||||
annotationProcessor "io.noties:prism4j-bundler:2.0.0"
|
||||
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
|
||||
implementation "commons-io:commons-io:20030203.000550"
|
||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||
implementation "com.github.chrisbanes:PhotoView:2.3.0"
|
||||
implementation "com.pddstudio:highlightjs-android:1.5.0"
|
||||
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
|
||||
//noinspection GradleDependency
|
||||
implementation "com.mikepenz:fastadapter:$fastadapter"
|
||||
implementation "com.mikepenz:fastadapter-commons:$fastadapter"
|
||||
implementation "com.mikepenz:fastadapter-extensions:$fastadapter"
|
||||
implementation "ch.acra:acra-mail:$acra"
|
||||
implementation "ch.acra:acra-limiter:$acra"
|
||||
implementation "ch.acra:acra-notification:$acra"
|
||||
implementation 'androidx.room:room-runtime:2.3.0'
|
||||
annotationProcessor 'androidx.room:room-compiler:2.3.0'
|
||||
implementation "androidx.work:work-runtime:$work_version"
|
||||
implementation "io.mikael:urlbuilder:2.0.9"
|
||||
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
|
||||
implementation "org.codeberg.gitnex:tea4j:1.0.16"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
|
||||
implementation 'androidx.biometric:biometric:1.1.0'
|
||||
implementation 'com.github.chrisvest:stormpot:2.4.2'
|
||||
|
||||
}
|
||||
|
||||
2
app/proguard-rules.pro
vendored
2
app/proguard-rules.pro
vendored
@@ -19,3 +19,5 @@
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
-optimizationpasses 30
|
||||
-allowaccessmodification
|
||||
|
||||
@@ -4,62 +4,92 @@
|
||||
package="org.mian.gitnex">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:name=".core.MainApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/app_logo"
|
||||
android:label="@string/app_name"
|
||||
android:label="@string/appName"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:resizeableActivity="true"
|
||||
android:roundIcon="@mipmap/app_logo_round"
|
||||
android:supportsRtl="true"
|
||||
tools:targetApi="n">
|
||||
<activity android:name=".activities.MergePullRequestActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.MergePullRequestActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.FileViewActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity
|
||||
android:name=".activities.CreateFileActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity
|
||||
android:name=".activities.RepoWatchersActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity
|
||||
android:name=".activities.RepoStargazersActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity android:name=".activities.AdminGetUsersActivity" />
|
||||
<activity
|
||||
android:name=".activities.AddRemoveAssigneesActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.Dialog" />
|
||||
<activity android:name=".activities.CreateReleaseActivity" />
|
||||
<activity android:name=".activities.EditIssueActivity" />
|
||||
<activity android:name=".activities.CreateNewUserActivity" />
|
||||
android:name=".activities.AdminGetUsersActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.AddRemoveLabelsActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.Dialog" />
|
||||
<activity android:name=".activities.ProfileEmailActivity" />
|
||||
<activity android:name=".activities.AddCollaboratorToRepositoryActivity" />
|
||||
<activity android:name=".activities.CreateTeamByOrgActivity" />
|
||||
<activity android:name=".activities.OrganizationTeamMembersActivity" />
|
||||
android:name=".activities.CreateReleaseActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.EditIssueActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.CreateNewUserActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.MyProfileEmailActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.AddCollaboratorToRepositoryActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.CreateTeamByOrgActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.OrganizationTeamMembersActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.OrganizationDetailActivity"
|
||||
android:label="@string/title_activity_org_detail"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:label="@string/titleActivityOrgDetail"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity android:name=".activities.SponsorsActivity" />
|
||||
<activity android:name=".activities.CreditsActivity" />
|
||||
<activity android:name=".activities.CreateLabelActivity" />
|
||||
<activity android:name=".activities.CreateIssueActivity" />
|
||||
<activity android:name=".activities.CreateMilestoneActivity" />
|
||||
<activity android:name=".activities.ReplyToIssueActivity" />
|
||||
<activity
|
||||
android:name=".activities.CreateLabelActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.CreateIssueActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.CreateMilestoneActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.IssueDetailActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:windowSoftInputMode="adjustNothing" />
|
||||
<activity
|
||||
android:name=".activities.RepoDetailActivity"
|
||||
android:label="@string/title_activity_repo_detail"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:label="@string/titleActivityRepoDetail"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity android:name=".activities.MainActivity" android:theme="@android:style/Theme.NoTitleBar">
|
||||
<activity
|
||||
android:name=".activities.MainActivity"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -68,13 +98,102 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activities.LoginActivity"
|
||||
android:launchMode="singleTask" android:theme="@android:style/Theme.NoTitleBar"/>
|
||||
<activity android:name=".activities.CreateRepoActivity" />
|
||||
<activity android:name=".activities.CreateOrganizationActivity" />
|
||||
<activity android:name=".activities.OpenRepoInBrowserActivity" />
|
||||
<activity android:name=".activities.FileDiffActivity" />
|
||||
<activity android:name=".activities.CommitsActivity" />
|
||||
<activity android:name=".helpers.ssl.MemorizingActivity" android:theme="@android:style/Theme.Material.Dialog" />
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@android:style/Theme.NoTitleBar"/>
|
||||
<activity
|
||||
android:name=".activities.CreateRepoActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.CreateOrganizationActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.OpenRepoInBrowserActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.FileDiffActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.CommitsActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".helpers.ssl.MemorizingActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:theme="@android:style/Theme.Material.Dialog" />
|
||||
<activity
|
||||
android:name=".activities.SettingsAppearanceActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.ProfileActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.SettingsSecurityActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.SettingsTranslationActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.SettingsReportsActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.AddNewTeamMemberActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.SettingsDraftsActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.RepoForksActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.AddNewAccountActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.RepositorySettingsActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.CreatePullRequestActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.SettingsGeneralActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.SettingsNotificationsActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.AdminCronTasksActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
|
||||
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
|
||||
<meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>
|
||||
<!-- Version >= 3.0. DeX Dual Mode support -->
|
||||
<meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="true"/>
|
||||
|
||||
<!-- deep links -->
|
||||
<activity
|
||||
android:name=".activities.DeepLinksActivity"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:noHistory="true"
|
||||
android:launchMode="singleTask"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="codeberg.org" />
|
||||
<data android:host="gitea.com" />
|
||||
<data android:host="try.gitea.io" />
|
||||
<data android:host="code.obermui.de" />
|
||||
<data android:host="git.fsfe.org" />
|
||||
<data android:host="opendev.org" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<!-- deep links -->
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
||||
BIN
app/src/main/app_logo-playstore.png
Normal file
BIN
app/src/main/app_logo-playstore.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
80
app/src/main/java/org/mian/gitnex/actions/ActionResult.java
Normal file
80
app/src/main/java/org/mian/gitnex/actions/ActionResult.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package org.mian.gitnex.actions;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class ActionResult<R> {
|
||||
|
||||
public enum Status { SUCCESS, FAILED }
|
||||
|
||||
private final BlockingQueue<Boolean> blockingQueue;
|
||||
private final List<OnFinishedListener<R>> onFinishedListeners;
|
||||
|
||||
private boolean invalidated = false;
|
||||
|
||||
public ActionResult() {
|
||||
|
||||
blockingQueue = new ArrayBlockingQueue<>(1);
|
||||
onFinishedListeners = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
public void finish(@NonNull Status status) {
|
||||
|
||||
finish(status, null);
|
||||
}
|
||||
|
||||
public void finish(@NonNull Status status, R result) {
|
||||
|
||||
try {
|
||||
if(blockingQueue.poll(5, TimeUnit.SECONDS)) {
|
||||
|
||||
for(OnFinishedListener<R> onFinishedListener : onFinishedListeners)
|
||||
onFinishedListener.onFinished(status, result);
|
||||
}
|
||||
|
||||
} catch (InterruptedException ignored) {}
|
||||
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
|
||||
if(invalidated) throw new IllegalStateException("Already invalidated");
|
||||
this.invalidated = true;
|
||||
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public synchronized final void accept(@NonNull OnFinishedListener<R>... onFinishedListeners) {
|
||||
|
||||
invalidate();
|
||||
|
||||
this.blockingQueue.add(true);
|
||||
this.onFinishedListeners.addAll(Arrays.asList(onFinishedListeners));
|
||||
|
||||
}
|
||||
|
||||
public synchronized final void discard() {
|
||||
|
||||
invalidate();
|
||||
this.blockingQueue.add(false);
|
||||
|
||||
}
|
||||
|
||||
public static class None {}
|
||||
|
||||
public interface OnFinishedListener<R> {
|
||||
|
||||
void onFinished(Status status, R result);
|
||||
}
|
||||
|
||||
}
|
||||
118
app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java
Normal file
118
app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package org.mian.gitnex.actions;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.Collaborators;
|
||||
import org.gitnex.tea4j.models.Issues;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.AssigneesListAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class AssigneesActions {
|
||||
|
||||
public static void getCurrentIssueAssignees(Context ctx, String repoOwner, String repoName, int issueIndex, List<String> currentAssignees) {
|
||||
|
||||
Call<Issues> callSingleIssueLabels = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getIssueByIndex(Authorization.get(ctx), repoOwner, repoName, issueIndex);
|
||||
|
||||
callSingleIssueLabels.enqueue(new Callback<Issues>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
Issues issueAssigneesList = response.body();
|
||||
assert issueAssigneesList != null;
|
||||
|
||||
if (issueAssigneesList.getAssignees() != null) {
|
||||
|
||||
if(issueAssigneesList.getAssignees().size() > 0) {
|
||||
|
||||
for(int i = 0; i < issueAssigneesList.getAssignees().size(); i++) {
|
||||
|
||||
currentAssignees.add(issueAssigneesList.getAssignees().get(i).getLogin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static void getRepositoryAssignees(Context ctx, String repoOwner, String repoName, List<Collaborators> assigneesList, Dialog dialogAssignees, AssigneesListAdapter assigneesAdapter, CustomAssigneesSelectionDialogBinding assigneesBinding) {
|
||||
|
||||
TinyDB tinyDB = TinyDB.getInstance(ctx);
|
||||
|
||||
Call<List<Collaborators>> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getCollaborators(Authorization.get(ctx), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Collaborators>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull retrofit2.Response<List<Collaborators>> response) {
|
||||
|
||||
assigneesList.clear();
|
||||
List<Collaborators> assigneesList_ = response.body();
|
||||
|
||||
assigneesBinding.progressBar.setVisibility(View.GONE);
|
||||
assigneesBinding.dialogFrame.setVisibility(View.VISIBLE);
|
||||
|
||||
if (response.code() == 200) {
|
||||
|
||||
assert assigneesList_ != null;
|
||||
|
||||
if(assigneesList_.size() > 0) {
|
||||
|
||||
assigneesList.add(new Collaborators(tinyDB.getString("userFullname"), tinyDB.getString("loginUid"), tinyDB.getString("userAvatar")));
|
||||
assigneesList.addAll(assigneesList_);
|
||||
}
|
||||
else {
|
||||
|
||||
dialogAssignees.dismiss();
|
||||
Toasty.warning(ctx, ctx.getResources().getString(R.string.noAssigneesFound));
|
||||
}
|
||||
|
||||
assigneesBinding.assigneesRecyclerView.setAdapter(assigneesAdapter);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.error(ctx, ctx.getResources().getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,18 +2,20 @@ package org.mian.gitnex.actions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.Collaborators;
|
||||
import org.gitnex.tea4j.models.Permission;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.AddCollaboratorToRepositoryActivity;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Collaborators;
|
||||
import org.mian.gitnex.models.Permission;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -23,21 +25,16 @@ public class CollaboratorActions {
|
||||
|
||||
public static void deleteCollaborator(final Context context, final String searchKeyword, String userName) {
|
||||
|
||||
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");
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
Call<Collaborators> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, context)
|
||||
.getApiInterface()
|
||||
.deleteCollaborator(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, userName);
|
||||
Call<Collaborators> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.deleteCollaborator(Authorization.get(context), repoOwner, repoName, userName);
|
||||
|
||||
call.enqueue(new Callback<Collaborators>() {
|
||||
|
||||
@@ -47,12 +44,12 @@ public class CollaboratorActions {
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 204) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.removeCollaboratorToastText));
|
||||
Toasty.success(context, context.getString(R.string.removeCollaboratorToastText));
|
||||
((AddCollaboratorToRepositoryActivity)context).finish();
|
||||
//Log.i("addCollaboratorSearch", addCollaboratorSearch.getText().toString());
|
||||
//tinyDb.putBoolean("updateDataSet", true);
|
||||
//AddCollaboratorToRepositoryActivity usersSearchData = new AddCollaboratorToRepositoryActivity();
|
||||
//usersSearchData.loadUserSearchList(instanceUrl, instanceToken, searchKeyword, context);
|
||||
//usersSearchData.loadUserSearchList(instanceToken, searchKeyword, context);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -66,17 +63,17 @@ public class CollaboratorActions {
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.authorizeError));
|
||||
Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.apiNotFound));
|
||||
Toasty.warning(context, context.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.genericError));
|
||||
Toasty.error(context, context.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
@@ -92,22 +89,18 @@ public class CollaboratorActions {
|
||||
|
||||
public static void addCollaborator(final Context context, String permission, String userName) {
|
||||
|
||||
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");
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
Permission permissionString = new Permission(permission);
|
||||
Call<Permission> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, context)
|
||||
.getApiInterface()
|
||||
.addCollaborator(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, userName, permissionString);
|
||||
Call<Permission> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.addCollaborator(Authorization.get(context), repoOwner, repoName, userName, permissionString);
|
||||
|
||||
call.enqueue(new Callback<Permission>() {
|
||||
|
||||
@@ -117,10 +110,10 @@ public class CollaboratorActions {
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 204) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.addCollaboratorToastText));
|
||||
Toasty.success(context, context.getString(R.string.addCollaboratorToastText));
|
||||
((AddCollaboratorToRepositoryActivity)context).finish();
|
||||
//AddCollaboratorToRepositoryActivity usersSearchData = new AddCollaboratorToRepositoryActivity();
|
||||
//usersSearchData.loadUserSearchList(instanceUrl, instanceToken, searchKeyword, context);
|
||||
//usersSearchData.loadUserSearchList(instanceToken, searchKeyword, context);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -134,17 +127,17 @@ public class CollaboratorActions {
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.authorizeError));
|
||||
Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.apiNotFound));
|
||||
Toasty.warning(context, context.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.genericError));
|
||||
Toasty.error(context, context.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
@@ -154,8 +147,50 @@ public class CollaboratorActions {
|
||||
public void onFailure(@NonNull Call<Permission> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static ActionResult<List<Collaborators>> getCollaborators(Context context) {
|
||||
|
||||
ActionResult<List<Collaborators>> actionResult = new ActionResult<>();
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
Call<List<Collaborators>> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.getCollaborators(Authorization.get(context), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Collaborators>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
actionResult.finish(ActionResult.Status.SUCCESS, response.body());
|
||||
}
|
||||
else {
|
||||
|
||||
actionResult.finish(ActionResult.Status.FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
|
||||
|
||||
actionResult.finish(ActionResult.Status.FAILED);
|
||||
}
|
||||
});
|
||||
|
||||
return actionResult;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
package org.mian.gitnex.actions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.gitnex.tea4j.models.IssueComments;
|
||||
import org.gitnex.tea4j.models.Issues;
|
||||
import org.gitnex.tea4j.models.UpdateIssueState;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.ReplyToIssueActivity;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.UpdateIssueState;
|
||||
import org.mian.gitnex.models.IssueComments;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -24,273 +22,306 @@ import retrofit2.Callback;
|
||||
|
||||
public class IssueActions {
|
||||
|
||||
public static void editIssueComment(final Context ctx, final int commentId, final String commentBody) {
|
||||
public static ActionResult<Response<?>> edit(Context context, String comment, int commentId) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(ctx);
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
ActionResult<Response<?>> actionResult = new ActionResult<>();
|
||||
|
||||
IssueComments commentBodyJson = new IssueComments(commentBody);
|
||||
Call<IssueComments> call;
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, ctx)
|
||||
.getApiInterface()
|
||||
.patchIssueComment(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, commentId, commentBodyJson);
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
|
||||
call.enqueue(new Callback<IssueComments>() {
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<IssueComments> call, @NonNull retrofit2.Response<IssueComments> response) {
|
||||
Call<IssueComments> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.patchIssueComment(Authorization.get(context), repoOwner, repoName, commentId, new IssueComments(comment));
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 200) {
|
||||
call.enqueue(new Callback<IssueComments>() {
|
||||
|
||||
tinyDb.putBoolean("commentEdited", true);
|
||||
Toasty.info(ctx, ctx.getString(R.string.editCommentUpdatedText));
|
||||
((ReplyToIssueActivity)ctx).finish();
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<IssueComments> call, @NonNull retrofit2.Response<IssueComments> response) {
|
||||
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
switch(response.code()) {
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
case 200:
|
||||
actionResult.finish(ActionResult.Status.SUCCESS);
|
||||
break;
|
||||
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
case 401:
|
||||
actionResult.finish(ActionResult.Status.FAILED, response);
|
||||
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));
|
||||
break;
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
|
||||
default:
|
||||
actionResult.finish(ActionResult.Status.FAILED, response);
|
||||
break;
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
}
|
||||
}
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<IssueComments> call, @NonNull Throwable t) {
|
||||
|
||||
}
|
||||
else {
|
||||
actionResult.finish(ActionResult.Status.FAILED);
|
||||
}
|
||||
});
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.genericError));
|
||||
return actionResult;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public static void closeReopenIssue(final Context ctx, final int issueIndex, final String issueState) {
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<IssueComments> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
final TinyDB tinyDb = TinyDB.getInstance(ctx);
|
||||
|
||||
}
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
|
||||
public static void closeReopenIssue(final Context ctx, final int issueIndex, final String issueState) {
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(ctx);
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
UpdateIssueState issueStatJson = new UpdateIssueState(issueState);
|
||||
Call<JsonElement> call;
|
||||
|
||||
UpdateIssueState issueStatJson = new UpdateIssueState(issueState);
|
||||
Call<JsonElement> call;
|
||||
call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.closeReopenIssue(Authorization.get(ctx), repoOwner, repoName, issueIndex, issueStatJson);
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, ctx)
|
||||
.getApiInterface()
|
||||
.closeReopenIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson);
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 201) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 201) {
|
||||
tinyDb.putBoolean("resumeIssues", true);
|
||||
tinyDb.putBoolean("resumeClosedIssues", true);
|
||||
|
||||
tinyDb.putBoolean("resumeIssues", true);
|
||||
tinyDb.putBoolean("resumeClosedIssues", true);
|
||||
if(issueState.equals("closed")) {
|
||||
|
||||
if(issueState.equals("closed")) {
|
||||
Toasty.success(ctx, ctx.getString(R.string.issueStateClosed));
|
||||
tinyDb.putString("issueState", "closed");
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.issueStateClosed));
|
||||
tinyDb.putString("issueState", "closed");
|
||||
}
|
||||
else if(issueState.equals("open")) {
|
||||
|
||||
}
|
||||
else if(issueState.equals("open")) {
|
||||
Toasty.success(ctx, ctx.getString(R.string.issueStateReopened));
|
||||
tinyDb.putString("issueState", "open");
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.issueStateReopened));
|
||||
tinyDb.putString("issueState", "open");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
else {
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericError));
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void subscribe(final Context ctx, final TextView subscribeIssue, final TextView unsubscribeIssue) {
|
||||
public static void subscribe(final Context ctx) {
|
||||
|
||||
final TinyDB tinyDB = new TinyDB(ctx);
|
||||
final TinyDB tinyDB = TinyDB.getInstance(ctx);
|
||||
|
||||
final String instanceUrl = tinyDB.getString("instanceUrl");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String loginUid = tinyDB.getString("loginUid");
|
||||
final String userLogin = tinyDB.getString("userLogin");
|
||||
final String token = "token " + tinyDB.getString(loginUid + "-token");
|
||||
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
|
||||
String[] repoFullName = tinyDB.getString("repoFullName").split("/");
|
||||
|
||||
Call<Void> call;
|
||||
if(repoFullName.length != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, ctx)
|
||||
.getApiInterface()
|
||||
.addIssueSubscriber(token, repoOwner, repoName, issueNr, userLogin);
|
||||
final String userLogin = tinyDB.getString("userLogin");
|
||||
final String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
|
||||
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
|
||||
|
||||
call.enqueue(new Callback<Void>() {
|
||||
Call<Void> call;
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.addIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin);
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
call.enqueue(new Callback<Void>() {
|
||||
|
||||
if(response.code() == 201) {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
|
||||
unsubscribeIssue.setVisibility(View.VISIBLE);
|
||||
subscribeIssue.setVisibility(View.GONE);
|
||||
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtion));
|
||||
tinyDB.putString("issueSubscriptionState", "unsubscribeToIssue");
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
}
|
||||
if(response.code() == 201) {
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
Toasty.success(ctx, ctx.getString(R.string.subscribedSuccessfully));
|
||||
tinyDB.putBoolean("issueSubscribed", true);
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
}
|
||||
else if(response.code() == 200) {
|
||||
|
||||
}
|
||||
else {
|
||||
tinyDB.putBoolean("issueSubscribed", true);
|
||||
Toasty.success(ctx, ctx.getString(R.string.alreadySubscribed));
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtionError));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
}
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtionError));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
Toasty.error(ctx, ctx.getString(R.string.subscriptionError));
|
||||
|
||||
public static void unsubscribe(final Context ctx, final TextView subscribeIssue, final TextView unsubscribeIssue) {
|
||||
}
|
||||
|
||||
final TinyDB tinyDB = new TinyDB(ctx);
|
||||
}
|
||||
|
||||
final String instanceUrl = tinyDB.getString("instanceUrl");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String loginUid = tinyDB.getString("loginUid");
|
||||
final String userLogin = tinyDB.getString("userLogin");
|
||||
final String token = "token " + tinyDB.getString(loginUid + "-token");
|
||||
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
|
||||
Call<Void> call;
|
||||
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, ctx)
|
||||
.getApiInterface()
|
||||
.delIssueSubscriber(token, repoOwner, repoName, issueNr, userLogin);
|
||||
}
|
||||
|
||||
call.enqueue(new Callback<Void>() {
|
||||
public static void unsubscribe(final Context ctx) {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
final TinyDB tinyDB = TinyDB.getInstance(ctx);
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
String[] repoFullName = tinyDB.getString("repoFullName").split("/");
|
||||
if(repoFullName.length != 2) {
|
||||
return;
|
||||
}
|
||||
final String userLogin = tinyDB.getString("userLogin");
|
||||
final String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
|
||||
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
|
||||
|
||||
if(response.code() == 201) {
|
||||
Call<Void> call;
|
||||
|
||||
unsubscribeIssue.setVisibility(View.GONE);
|
||||
subscribeIssue.setVisibility(View.VISIBLE);
|
||||
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtion));
|
||||
tinyDB.putString("issueSubscriptionState", "subscribeToIssue");
|
||||
call = RetrofitClient.getApiInterface(ctx).delIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin);
|
||||
|
||||
}
|
||||
call.enqueue(new Callback<Void>() {
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
}
|
||||
else {
|
||||
if(response.code() == 201) {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtionError));
|
||||
Toasty.success(ctx, ctx.getString(R.string.unsubscribedSuccessfully));
|
||||
tinyDB.putBoolean("issueSubscribed", false);
|
||||
|
||||
}
|
||||
}
|
||||
else if(response.code() == 200) {
|
||||
|
||||
}
|
||||
tinyDB.putBoolean("issueSubscribed", false);
|
||||
Toasty.success(ctx, ctx.getString(R.string.alreadyUnsubscribed));
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtionError));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.unSubscriptionError));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static ActionResult<ActionResult.None> reply(Context context, String comment, int issueIndex) {
|
||||
|
||||
ActionResult<ActionResult.None> actionResult = new ActionResult<>();
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
Issues issueComment = new Issues(comment);
|
||||
|
||||
Call<Issues> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.replyCommentToIssue(Authorization.get(context), repoOwner, repoName, issueIndex, issueComment);
|
||||
|
||||
call.enqueue(new Callback<Issues>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
actionResult.finish(ActionResult.Status.SUCCESS);
|
||||
|
||||
tinyDb.putBoolean("commentPosted", true);
|
||||
tinyDb.putBoolean("resumeIssues", true);
|
||||
tinyDb.putBoolean("resumePullRequests", true);
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(context, context.getString(R.string.alertDialogTokenRevokedTitle),
|
||||
context.getString(R.string.alertDialogTokenRevokedMessage),
|
||||
context.getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
context.getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
actionResult.finish(ActionResult.Status.FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
return actionResult;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
131
app/src/main/java/org/mian/gitnex/actions/LabelsActions.java
Normal file
131
app/src/main/java/org/mian/gitnex/actions/LabelsActions.java
Normal file
@@ -0,0 +1,131 @@
|
||||
package org.mian.gitnex.actions;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.Labels;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.LabelsListAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class LabelsActions {
|
||||
|
||||
public static void getCurrentIssueLabels(Context ctx, String repoOwner, String repoName, int issueIndex, List<Integer> currentLabelsIds) {
|
||||
|
||||
Call<List<Labels>> callSingleIssueLabels = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getIssueLabels(Authorization.get(ctx), repoOwner, repoName, issueIndex);
|
||||
|
||||
callSingleIssueLabels.enqueue(new Callback<List<Labels>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Labels> issueLabelsList = response.body();
|
||||
|
||||
assert issueLabelsList != null;
|
||||
|
||||
if(issueLabelsList.size() > 0) {
|
||||
|
||||
for (int i = 0; i < issueLabelsList.size(); i++) {
|
||||
|
||||
currentLabelsIds.add(issueLabelsList.get(i).getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static void getRepositoryLabels(Context ctx, String repoOwner, String repoName, List<Labels> labelsList, Dialog dialogLabels, LabelsListAdapter labelsAdapter, CustomLabelsSelectionDialogBinding labelsBinding) {
|
||||
|
||||
Call<List<Labels>> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getLabels(Authorization.get(ctx), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Labels>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
|
||||
|
||||
labelsList.clear();
|
||||
|
||||
if (response.code() == 200) {
|
||||
|
||||
if(response.body() != null) {
|
||||
|
||||
labelsList.addAll(response.body());
|
||||
}
|
||||
|
||||
// Load organization labels
|
||||
Call<List<Labels>> callOrgLabels = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getOrganizationLabels(Authorization.get(ctx), repoOwner);
|
||||
|
||||
callOrgLabels.enqueue(new Callback<List<Labels>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> responseOrg) {
|
||||
|
||||
labelsBinding.progressBar.setVisibility(View.GONE);
|
||||
labelsBinding.dialogFrame.setVisibility(View.VISIBLE);
|
||||
|
||||
if(responseOrg.body() != null) {
|
||||
|
||||
labelsList.addAll(responseOrg.body());
|
||||
}
|
||||
|
||||
if(labelsList.isEmpty()) {
|
||||
|
||||
dialogLabels.dismiss();
|
||||
Toasty.warning(ctx, ctx.getResources().getString(R.string.noLabelsFound));
|
||||
|
||||
}
|
||||
|
||||
labelsBinding.labelsRecyclerView.setAdapter(labelsAdapter);
|
||||
}
|
||||
|
||||
@Override public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.error(ctx, ctx.getResources().getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,14 +4,12 @@ import android.content.Context;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.gitnex.tea4j.models.Milestones;
|
||||
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.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Milestones;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.viewmodels.MilestonesViewModel;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@@ -25,9 +23,8 @@ public class MilestoneActions {
|
||||
|
||||
public static void closeMilestone(final Context ctx, int milestoneId_) {
|
||||
|
||||
final TinyDB tinyDB = new TinyDB(ctx);
|
||||
final TinyDB tinyDB = TinyDB.getInstance(ctx);
|
||||
|
||||
final String instanceUrl = tinyDB.getString("instanceUrl");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
@@ -39,8 +36,7 @@ public class MilestoneActions {
|
||||
Call<JsonElement> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, ctx)
|
||||
.getApiInterface()
|
||||
.getApiInterface(ctx)
|
||||
.closeReopenMilestone(token, repoOwner, repoName, milestoneId_, milestoneStateJson);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
@@ -50,8 +46,7 @@ public class MilestoneActions {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate));
|
||||
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, token), repoOwner, repoName, "all", ctx);
|
||||
Toasty.success(ctx, ctx.getString(R.string.milestoneStatusUpdate));
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
@@ -64,7 +59,7 @@ public class MilestoneActions {
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.genericError));
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
@@ -84,9 +79,8 @@ public class MilestoneActions {
|
||||
|
||||
public static void openMilestone(final Context ctx, int milestoneId_) {
|
||||
|
||||
final TinyDB tinyDB = new TinyDB(ctx);
|
||||
final TinyDB tinyDB = TinyDB.getInstance(ctx);
|
||||
|
||||
final String instanceUrl = tinyDB.getString("instanceUrl");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
@@ -98,8 +92,7 @@ public class MilestoneActions {
|
||||
Call<JsonElement> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, ctx)
|
||||
.getApiInterface()
|
||||
.getApiInterface(ctx)
|
||||
.closeReopenMilestone(token, repoOwner, repoName, milestoneId_, milestoneStateJson);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
@@ -109,8 +102,7 @@ public class MilestoneActions {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate));
|
||||
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, token), repoOwner, repoName, "all", ctx);
|
||||
Toasty.success(ctx, ctx.getString(R.string.milestoneStatusUpdate));
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
@@ -123,7 +115,7 @@ public class MilestoneActions {
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.genericError));
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.mian.gitnex.actions;
|
||||
|
||||
import android.content.Context;
|
||||
import org.gitnex.tea4j.models.NotificationThread;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import retrofit2.Call;
|
||||
|
||||
/**
|
||||
* Author opyale
|
||||
*/
|
||||
|
||||
public class NotificationsActions {
|
||||
|
||||
public enum NotificationStatus {READ, UNREAD, PINNED}
|
||||
|
||||
private TinyDB tinyDB;
|
||||
private Context context;
|
||||
private String instanceToken;
|
||||
|
||||
public NotificationsActions(Context context) {
|
||||
|
||||
this.context = context;
|
||||
this.tinyDB = TinyDB.getInstance(context);
|
||||
|
||||
String loginUid = tinyDB.getString("loginUid");
|
||||
|
||||
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
|
||||
}
|
||||
|
||||
public void setNotificationStatus(NotificationThread notificationThread, NotificationStatus notificationStatus) throws IOException {
|
||||
|
||||
Call<Void> call = RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadAsRead(instanceToken, notificationThread.getId(), notificationStatus.name());
|
||||
|
||||
if(!call.execute().isSuccessful()) {
|
||||
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setAllNotificationsRead(Date date) throws IOException {
|
||||
|
||||
Call<Void> call = RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadsAsRead(instanceToken, AppUtil.getTimestampFromDate(context, date), true,
|
||||
new String[]{"unread", "pinned"}, "read");
|
||||
|
||||
return call.execute().isSuccessful();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.mian.gitnex.actions;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author qwerty287
|
||||
*/
|
||||
|
||||
public class PullRequestActions {
|
||||
|
||||
public static void deleteHeadBranch(Context context, String repoOwner, String repoName, String headBranch, boolean showToasts) {
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.deleteBranch(Authorization.get(context), repoOwner, repoName, headBranch);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
if(response.code() == 204) {
|
||||
|
||||
if(showToasts) Toasty.success(context, context.getString(R.string.deleteBranchSuccess));
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
AlertDialogs
|
||||
.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle), context.getResources().getString(R.string.alertDialogTokenRevokedMessage), context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
if(showToasts) Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
if(showToasts) Toasty.warning(context, context.getString(R.string.deleteBranchErrorNotFound));
|
||||
}
|
||||
else {
|
||||
|
||||
if(showToasts) Toasty.error(context, context.getString(R.string.genericError));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
if(showToasts) Toasty.error(context, context.getString(R.string.deleteBranchError));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,8 +8,8 @@ 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.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@@ -21,10 +21,8 @@ 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");
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
@@ -33,9 +31,8 @@ public class RepositoryActions {
|
||||
Call<JsonElement> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, context)
|
||||
.getApiInterface()
|
||||
.starRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
|
||||
.getApiInterface(context)
|
||||
.starRepository(Authorization.get(context), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@@ -46,7 +43,7 @@ public class RepositoryActions {
|
||||
if(response.code() == 204) {
|
||||
|
||||
tinyDb.putBoolean("repoCreated", true);
|
||||
Toasty.info(context, context.getString(R.string.starRepositorySuccess));
|
||||
Toasty.success(context, context.getString(R.string.starRepositorySuccess));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -60,17 +57,17 @@ public class RepositoryActions {
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.authorizeError));
|
||||
Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.apiNotFound));
|
||||
Toasty.warning(context, context.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.genericError));
|
||||
Toasty.error(context, context.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
@@ -86,10 +83,8 @@ public class RepositoryActions {
|
||||
|
||||
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");
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
@@ -98,9 +93,8 @@ public class RepositoryActions {
|
||||
Call<JsonElement> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, context)
|
||||
.getApiInterface()
|
||||
.unStarRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
|
||||
.getApiInterface(context)
|
||||
.unStarRepository(Authorization.get(context), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@@ -111,7 +105,7 @@ public class RepositoryActions {
|
||||
if(response.code() == 204) {
|
||||
|
||||
tinyDb.putBoolean("repoCreated", true);
|
||||
Toasty.info(context, context.getString(R.string.unStarRepositorySuccess));
|
||||
Toasty.success(context, context.getString(R.string.unStarRepositorySuccess));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -125,17 +119,17 @@ public class RepositoryActions {
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.authorizeError));
|
||||
Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.apiNotFound));
|
||||
Toasty.warning(context, context.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.genericError));
|
||||
Toasty.error(context, context.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
@@ -151,10 +145,8 @@ public class RepositoryActions {
|
||||
|
||||
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");
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
@@ -163,9 +155,8 @@ public class RepositoryActions {
|
||||
Call<JsonElement> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, context)
|
||||
.getApiInterface()
|
||||
.watchRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
|
||||
.getApiInterface(context)
|
||||
.watchRepository(Authorization.get(context), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@@ -176,7 +167,7 @@ public class RepositoryActions {
|
||||
if(response.code() == 200) {
|
||||
|
||||
tinyDb.putBoolean("repoCreated", true);
|
||||
Toasty.info(context, context.getString(R.string.watchRepositorySuccess));
|
||||
Toasty.success(context, context.getString(R.string.watchRepositorySuccess));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -190,17 +181,17 @@ public class RepositoryActions {
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.authorizeError));
|
||||
Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.apiNotFound));
|
||||
Toasty.warning(context, context.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.genericError));
|
||||
Toasty.error(context, context.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
@@ -216,10 +207,8 @@ public class RepositoryActions {
|
||||
|
||||
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");
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
@@ -228,9 +217,8 @@ public class RepositoryActions {
|
||||
Call<JsonElement> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, context)
|
||||
.getApiInterface()
|
||||
.unWatchRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
|
||||
.getApiInterface(context)
|
||||
.unWatchRepository(Authorization.get(context), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@@ -240,7 +228,7 @@ public class RepositoryActions {
|
||||
if(response.code() == 204) {
|
||||
|
||||
tinyDb.putBoolean("repoCreated", true);
|
||||
Toasty.info(context, context.getString(R.string.unWatchRepositorySuccess));
|
||||
Toasty.success(context, context.getString(R.string.unWatchRepositorySuccess));
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
@@ -253,17 +241,17 @@ public class RepositoryActions {
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.authorizeError));
|
||||
Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.apiNotFound));
|
||||
Toasty.warning(context, context.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.genericError));
|
||||
Toasty.error(context, context.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
|
||||
144
app/src/main/java/org/mian/gitnex/actions/TeamActions.java
Normal file
144
app/src/main/java/org/mian/gitnex/actions/TeamActions.java
Normal file
@@ -0,0 +1,144 @@
|
||||
package org.mian.gitnex.actions;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.AddNewTeamMemberActivity;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class TeamActions {
|
||||
|
||||
public static void removeTeamMember(final Context context, String userName, int teamId) {
|
||||
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
Call<JsonElement> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.removeTeamMember(Authorization.get(context), teamId, userName);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
if(response.code() == 204) {
|
||||
|
||||
tinyDb.putBoolean("teamActionFlag", true);
|
||||
Toasty.success(context, context.getString(R.string.memberRemovedMessage));
|
||||
((AddNewTeamMemberActivity)context).finish();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.warning(context, context.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.error(context, context.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static void addTeamMember(final Context context, String userName, int teamId) {
|
||||
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.addTeamMember(Authorization.get(context), teamId, userName);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
if(response.code() == 204) {
|
||||
|
||||
tinyDb.putBoolean("teamActionFlag", true);
|
||||
Toasty.success(context, context.getString(R.string.memberAddedMessage));
|
||||
((AddNewTeamMemberActivity)context).finish();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
Toasty.error(context, context.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.warning(context, context.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.error(context, context.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +1,28 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import org.mian.gitnex.R;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.gitnex.tea4j.models.UserSearch;
|
||||
import org.mian.gitnex.adapters.UserSearchAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityAddCollaboratorToRepositoryBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.models.UserSearch;
|
||||
import org.mian.gitnex.models.UserInfo;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -33,36 +31,27 @@ import java.util.List;
|
||||
public class AddCollaboratorToRepositoryActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
final Context ctx = this;
|
||||
private TextView addCollaboratorSearch;
|
||||
private TextView noData;
|
||||
private ProgressBar mProgressBar;
|
||||
|
||||
private RecyclerView mRecyclerView;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_add_collaborator_to_repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityAddCollaboratorToRepositoryBinding activityAddCollaboratorToRepositoryBinding = ActivityAddCollaboratorToRepositoryBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityAddCollaboratorToRepositoryBinding.getRoot());
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
addCollaboratorSearch = findViewById(R.id.addCollaboratorSearch);
|
||||
mRecyclerView = findViewById(R.id.recyclerViewUserSearch);
|
||||
mProgressBar = findViewById(R.id.progress_bar);
|
||||
noData = findViewById(R.id.noData);
|
||||
ImageView closeActivity = activityAddCollaboratorToRepositoryBinding.close;
|
||||
addCollaboratorSearch = activityAddCollaboratorToRepositoryBinding.addCollaboratorSearch;
|
||||
mRecyclerView = activityAddCollaboratorToRepositoryBinding.recyclerViewUserSearch;
|
||||
mProgressBar = activityAddCollaboratorToRepositoryBinding.progressBar;
|
||||
noData = activityAddCollaboratorToRepositoryBinding.noData;
|
||||
|
||||
addCollaboratorSearch.requestFocus();
|
||||
assert imm != null;
|
||||
@@ -71,36 +60,43 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
addCollaboratorSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
||||
if(!addCollaboratorSearch.getText().toString().equals("")) {
|
||||
loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), getApplicationContext(), loginUid);
|
||||
}
|
||||
addCollaboratorSearch.setOnEditorActionListener((v, actionId, event) -> {
|
||||
|
||||
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
||||
|
||||
if(!addCollaboratorSearch.getText().toString().equals("")) {
|
||||
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
loadUserSearchList(addCollaboratorSearch.getText().toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, final Context context, String loginUid) {
|
||||
public void loadUserSearchList(String searchKeyword) {
|
||||
|
||||
Call<UserSearch> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getUserBySearch(Authorization.returnAuthentication(getApplicationContext(), loginUid, token), searchKeyword, 10);
|
||||
.getApiInterface(appCtx)
|
||||
.getUserBySearch(Authorization.get(ctx), searchKeyword, 10);
|
||||
|
||||
call.enqueue(new Callback<UserSearch>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<UserSearch> call, @NonNull Response<UserSearch> response) {
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
|
||||
if (response.code() == 200) {
|
||||
|
||||
assert response.body() != null;
|
||||
getUsersList(response.body().getData(), context);
|
||||
} else {
|
||||
getUsersList(response.body().getData(), ctx);
|
||||
}
|
||||
else {
|
||||
|
||||
Log.i("onResponse", String.valueOf(response.code()));
|
||||
}
|
||||
|
||||
@@ -119,7 +115,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
|
||||
UserSearchAdapter adapter = new UserSearchAdapter(dataList, context);
|
||||
|
||||
mRecyclerView.setHasFixedSize(true);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
@@ -127,25 +123,20 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
if(adapter.getItemCount() > 0) {
|
||||
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
noData.setVisibility(View.GONE);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import org.gitnex.tea4j.models.GiteaVersion;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.UserAccountsApi;
|
||||
import org.mian.gitnex.databinding.ActivityAddNewAccountBinding;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.PathsHelper;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.UrlHelper;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.net.URI;
|
||||
import io.mikael.urlbuilder.UrlBuilder;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class AddNewAccountActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private ActivityAddNewAccountBinding viewBinding;
|
||||
|
||||
private enum Protocol {HTTPS, HTTP}
|
||||
private String spinnerSelectedValue;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
viewBinding = ActivityAddNewAccountBinding.inflate(getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
|
||||
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
|
||||
|
||||
initCloseListener();
|
||||
viewBinding.close.setOnClickListener(onClickListener);
|
||||
viewBinding.instanceUrl.setText(getIntent().getStringExtra("instanceUrl"));
|
||||
|
||||
ArrayAdapter<Protocol> adapterProtocols = new ArrayAdapter<>(ctx, R.layout.list_spinner_items, Protocol.values());
|
||||
|
||||
viewBinding.protocolSpinner.setAdapter(adapterProtocols);
|
||||
viewBinding.protocolSpinner.setOnItemClickListener((parent, view1, position, id) -> spinnerSelectedValue = String.valueOf(parent.getItemAtPosition(position)));
|
||||
viewBinding.addNewAccount.setOnClickListener(login -> {
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
}
|
||||
else {
|
||||
|
||||
processLogin();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void processLogin() {
|
||||
|
||||
try {
|
||||
|
||||
String instanceUrlET = String.valueOf(viewBinding.instanceUrl.getText());
|
||||
String loginToken = String.valueOf(viewBinding.loginToken.getText());
|
||||
String protocol = spinnerSelectedValue;
|
||||
|
||||
if(protocol == null) {
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.protocolEmptyError));
|
||||
return;
|
||||
}
|
||||
|
||||
if(instanceUrlET.equals("")) {
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.emptyFieldURL));
|
||||
return;
|
||||
}
|
||||
|
||||
if(loginToken.equals("")) {
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.loginTokenError));
|
||||
return;
|
||||
}
|
||||
|
||||
URI rawInstanceUrl = UrlBuilder.fromString(UrlHelper.fixScheme(instanceUrlET, "http")).toUri();
|
||||
|
||||
URI instanceUrl = UrlBuilder.fromUri(rawInstanceUrl).withScheme(protocol.toLowerCase()).withPath(PathsHelper.join(rawInstanceUrl.getPath(), "/api/v1/"))
|
||||
.toUri();
|
||||
|
||||
versionCheck(instanceUrl.toString(), loginToken);
|
||||
|
||||
}
|
||||
catch(Exception e) {
|
||||
|
||||
Log.e("onFailure-login", e.toString());
|
||||
Toasty.error(ctx, getResources().getString(R.string.malformedUrl));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void versionCheck(final String instanceUrl, final String loginToken) {
|
||||
|
||||
Call<GiteaVersion> callVersion;
|
||||
callVersion = RetrofitClient.getApiInterface(ctx, instanceUrl).getGiteaVersionWithToken("token " + loginToken);
|
||||
callVersion.enqueue(new Callback<GiteaVersion>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) {
|
||||
|
||||
if(responseVersion.code() == 200) {
|
||||
|
||||
GiteaVersion version = responseVersion.body();
|
||||
|
||||
assert version != null;
|
||||
|
||||
if(!Version.valid(version.getVersion())) {
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.versionUnknown));
|
||||
return;
|
||||
}
|
||||
|
||||
tinyDB.putString("giteaVersion", version.getVersion());
|
||||
Version giteaVersion = new Version(version.getVersion());
|
||||
|
||||
if(giteaVersion.less(getString(R.string.versionLow))) {
|
||||
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader))
|
||||
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setIcon(R.drawable.ic_warning)
|
||||
.setCancelable(true);
|
||||
|
||||
alertDialogBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
|
||||
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
alertDialogBuilder.setPositiveButton(getString(R.string.textContinue), (dialog, which) -> {
|
||||
|
||||
dialog.dismiss();
|
||||
login(instanceUrl, loginToken);
|
||||
});
|
||||
|
||||
alertDialogBuilder.create().show();
|
||||
}
|
||||
else if(giteaVersion.lessOrEqual(getString(R.string.versionHigh))) {
|
||||
|
||||
login(instanceUrl, loginToken);
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.warning(ctx, getResources().getString(R.string.versionUnsupportedNew));
|
||||
login(instanceUrl, loginToken);
|
||||
}
|
||||
|
||||
}
|
||||
else if(responseVersion.code() == 403) {
|
||||
|
||||
login(instanceUrl, loginToken);
|
||||
}
|
||||
}
|
||||
|
||||
private void login(String instanceUrl, String loginToken) {
|
||||
|
||||
setupNewAccountWithToken(instanceUrl, loginToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<GiteaVersion> callVersion, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure-versionCheck", t.toString());
|
||||
Toasty.error(ctx, getResources().getString(R.string.errorOnLogin));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupNewAccountWithToken(String instanceUrl, final String loginToken) {
|
||||
|
||||
Call<UserInfo> call = RetrofitClient.getApiInterface(ctx, instanceUrl).getUserInfo("token " + loginToken);
|
||||
|
||||
call.enqueue(new Callback<UserInfo>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<UserInfo> call, @NonNull retrofit2.Response<UserInfo> response) {
|
||||
|
||||
UserInfo userDetails = response.body();
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 200:
|
||||
|
||||
assert userDetails != null;
|
||||
// insert new account to db if does not exist
|
||||
String accountName = userDetails.getUsername() + "@" + instanceUrl;
|
||||
UserAccountsApi userAccountsApi = BaseApi.getInstance(ctx, UserAccountsApi.class);
|
||||
boolean userAccountExists = userAccountsApi.userAccountExists(accountName);
|
||||
|
||||
if(!userAccountExists) {
|
||||
|
||||
userAccountsApi.createNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, "");
|
||||
Toasty.success(ctx, getResources().getString(R.string.accountAddedMessage));
|
||||
finish();
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.warning(ctx, getResources().getString(R.string.accountAlreadyExistsError));
|
||||
}
|
||||
break;
|
||||
|
||||
case 401:
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.unauthorizedApiError));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
Toasty.error(ctx, getResources().getString(R.string.genericError));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.gitnex.tea4j.models.UserSearch;
|
||||
import org.mian.gitnex.adapters.UserSearchForTeamMemberAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityAddNewTeamMemberBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class AddNewTeamMemberActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView addNewTeamMember;
|
||||
private TextView noData;
|
||||
private ProgressBar mProgressBar;
|
||||
|
||||
private RecyclerView mRecyclerView;
|
||||
private List<UserInfo> dataList;
|
||||
private UserSearchForTeamMemberAdapter adapter;
|
||||
|
||||
private String teamId;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityAddNewTeamMemberBinding activityAddNewTeamMemberBinding = ActivityAddNewTeamMemberBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityAddNewTeamMemberBinding.getRoot());
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
ImageView closeActivity = activityAddNewTeamMemberBinding.close;
|
||||
addNewTeamMember = activityAddNewTeamMemberBinding.addNewTeamMember;
|
||||
mRecyclerView = activityAddNewTeamMemberBinding.recyclerViewUserSearch;
|
||||
mProgressBar = activityAddNewTeamMemberBinding.progressBar;
|
||||
noData = activityAddNewTeamMemberBinding.noData;
|
||||
|
||||
addNewTeamMember.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(addNewTeamMember, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")) {
|
||||
|
||||
teamId = getIntent().getStringExtra("teamId");
|
||||
}
|
||||
else {
|
||||
|
||||
teamId = "0";
|
||||
}
|
||||
|
||||
mRecyclerView.setHasFixedSize(true);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
dataList = new ArrayList<>();
|
||||
|
||||
addNewTeamMember.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
if(!addNewTeamMember.getText().toString().equals("") && addNewTeamMember.getText().toString().length() > 1) {
|
||||
|
||||
adapter = new UserSearchForTeamMemberAdapter(dataList, ctx, Integer.parseInt(teamId));
|
||||
loadUserSearchList(addNewTeamMember.getText().toString(), teamId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void loadUserSearchList(String searchKeyword, String teamId) {
|
||||
|
||||
Call<UserSearch> call = RetrofitClient.getApiInterface(ctx).getUserBySearch(Authorization.get(ctx), searchKeyword, 10);
|
||||
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
call.enqueue(new Callback<UserSearch>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<UserSearch> call, @NonNull Response<UserSearch> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
if(response.body().getData().size() > 0) {
|
||||
|
||||
dataList.clear();
|
||||
dataList.addAll(response.body().getData());
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
noData.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<UserSearch> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,292 +0,0 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
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.MultiSelectDialog;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Collaborators;
|
||||
import org.mian.gitnex.models.Issues;
|
||||
import org.mian.gitnex.models.MultiSelectModel;
|
||||
import org.mian.gitnex.models.UpdateIssueAssignees;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class AddRemoveAssigneesActivity extends BaseActivity {
|
||||
|
||||
private ArrayList<MultiSelectModel> listOfCollaborators = new ArrayList<>();
|
||||
private ArrayList<Integer> issueAssigneesIds = new ArrayList<>();
|
||||
private Boolean assigneesFlag = false;
|
||||
private MultiSelectDialog multiSelectDialogAssignees;
|
||||
final Context ctx = this;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_add_remove_assignees;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
|
||||
|
||||
getAssignees(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
|
||||
|
||||
}
|
||||
|
||||
private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
Call<List<Collaborators>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Collaborators>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<List<Collaborators>> call, @NonNull final retrofit2.Response<List<Collaborators>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 200) {
|
||||
|
||||
final List<Collaborators> collaboratorsList_ = response.body();
|
||||
|
||||
assert collaboratorsList_ != null;
|
||||
if(collaboratorsList_.size() > 0) {
|
||||
for (int i = 0; i < collaboratorsList_.size(); i++) {
|
||||
|
||||
listOfCollaborators.add(new MultiSelectModel(collaboratorsList_.get(i).getId(), collaboratorsList_.get(i).getUsername().trim()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// get current issue assignees
|
||||
Call<Issues> callSingleIssueAssignees = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
|
||||
|
||||
callSingleIssueAssignees.enqueue(new Callback<Issues>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
Issues issueAssigneesList = response.body();
|
||||
|
||||
assert issueAssigneesList != null;
|
||||
if (issueAssigneesList.getAssignees() != null) {
|
||||
if (issueAssigneesList.getAssignees().size() > 0) {
|
||||
for (int i = 0; i < issueAssigneesList.getAssignees().size(); i++) {
|
||||
|
||||
issueAssigneesIds.add(issueAssigneesList.getAssignees().get(i).getId());
|
||||
|
||||
if(issueAssigneesList.getAssignees().get(i).getUsername().equals(loginUid)) {
|
||||
listOfCollaborators.add(new MultiSelectModel(issueAssigneesList.getAssignees().get(i).getId(), issueAssigneesList.getAssignees().get(i).getUsername().trim()));
|
||||
}
|
||||
|
||||
}
|
||||
assigneesFlag = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
listOfCollaborators.add(new MultiSelectModel(tinyDb.getInt("userId"), loginUid));
|
||||
}
|
||||
|
||||
if(assigneesFlag) {
|
||||
|
||||
multiSelectDialogAssignees = new MultiSelectDialog()
|
||||
.title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
|
||||
.titleSize(25)
|
||||
.positiveText(getResources().getString(R.string.saveButton))
|
||||
.negativeText(getResources().getString(R.string.cancelButton))
|
||||
.setMinSelectionLimit(0)
|
||||
.preSelectIDsList(issueAssigneesIds)
|
||||
.setMaxSelectionLimit(listOfCollaborators.size())
|
||||
.multiSelectList(listOfCollaborators)
|
||||
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
|
||||
@Override
|
||||
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
|
||||
|
||||
Log.i("selectedNames", String.valueOf(selectedNames));
|
||||
|
||||
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
|
||||
tinyDb.putBoolean("singleIssueUpdate", true);
|
||||
CloseActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
CloseActivity();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
multiSelectDialogAssignees = new MultiSelectDialog()
|
||||
.title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
|
||||
.titleSize(25)
|
||||
.positiveText(getResources().getString(R.string.saveButton))
|
||||
.negativeText(getResources().getString(R.string.cancelButton))
|
||||
.setMinSelectionLimit(0)
|
||||
.setMaxSelectionLimit(listOfCollaborators.size())
|
||||
.multiSelectList(listOfCollaborators)
|
||||
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
|
||||
@Override
|
||||
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
|
||||
|
||||
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
|
||||
tinyDb.putBoolean("singleIssueUpdate", true);
|
||||
CloseActivity();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
CloseActivity();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
multiSelectDialogAssignees.show(getSupportFragmentManager(), "issueMultiSelectDialog");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
// get current issue assignees
|
||||
|
||||
}
|
||||
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.genericError));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void CloseActivity() {
|
||||
this.finish();
|
||||
}
|
||||
|
||||
private void updateIssueAssignees(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, int issueIndex, List<String> issueAssigneesList) {
|
||||
|
||||
UpdateIssueAssignees updateAssigneeJson = new UpdateIssueAssignees(issueAssigneesList);
|
||||
|
||||
Call<JsonElement> call3;
|
||||
|
||||
call3 = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.patchIssueAssignees(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson);
|
||||
|
||||
call3.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response2) {
|
||||
|
||||
if(response2.code() == 201) {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.assigneesUpdated));
|
||||
|
||||
}
|
||||
else if(response2.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(response2.code() == 403) {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response2.code() == 404) {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.genericError));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,305 +0,0 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
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.MultiSelectDialog;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Labels;
|
||||
import org.mian.gitnex.models.MultiSelectModel;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class AddRemoveLabelsActivity extends BaseActivity {
|
||||
|
||||
private ArrayList<MultiSelectModel> listOfLabels = new ArrayList<>();
|
||||
private ArrayList<Integer> issueLabelIds = new ArrayList<>();
|
||||
private Boolean labelsFlag = false;
|
||||
private MultiSelectDialog multiSelectDialogLabels;
|
||||
final Context ctx = this;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_add_remove_labels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
|
||||
|
||||
getLabels(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
|
||||
|
||||
}
|
||||
|
||||
private void getLabels(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
Call<List<Labels>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Labels>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Labels> labelsList_ = response.body();
|
||||
|
||||
assert labelsList_ != null;
|
||||
if(labelsList_.size() > 0) {
|
||||
for (int i = 0; i < labelsList_.size(); i++) {
|
||||
|
||||
listOfLabels.add(new MultiSelectModel(labelsList_.get(i).getId(), labelsList_.get(i).getName().trim()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// get current issue labels
|
||||
Call<List<Labels>> callSingleIssueLabels = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getIssueLabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
|
||||
|
||||
callSingleIssueLabels.enqueue(new Callback<List<Labels>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Labels> issueLabelsList = response.body();
|
||||
|
||||
assert issueLabelsList != null;
|
||||
if(issueLabelsList.size() > 0) {
|
||||
for (int i = 0; i < issueLabelsList.size(); i++) {
|
||||
|
||||
issueLabelIds.add(issueLabelsList.get(i).getId());
|
||||
|
||||
}
|
||||
labelsFlag = true;
|
||||
}
|
||||
|
||||
if(labelsFlag) {
|
||||
|
||||
multiSelectDialogLabels = new MultiSelectDialog()
|
||||
.title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
|
||||
.titleSize(25)
|
||||
.positiveText(getResources().getString(R.string.saveButton))
|
||||
.negativeText(getResources().getString(R.string.cancelButton))
|
||||
.setMinSelectionLimit(0)
|
||||
.preSelectIDsList(issueLabelIds)
|
||||
.setMaxSelectionLimit(listOfLabels.size())
|
||||
.multiSelectList(listOfLabels)
|
||||
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
|
||||
@Override
|
||||
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
|
||||
|
||||
String labelIds = selectedIds.toString();
|
||||
int[] integers;
|
||||
if (selectedIds.size() > 0) {
|
||||
|
||||
String[] items = labelIds.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
|
||||
integers = new int[items.length];
|
||||
for (int i = 0; i < integers.length; i++) {
|
||||
integers[i] = Integer.parseInt(items[i]);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
integers = new int[0];
|
||||
}
|
||||
|
||||
updateIssueLabels(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
|
||||
tinyDb.putBoolean("singleIssueUpdate", true);
|
||||
CloseActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
CloseActivity();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
multiSelectDialogLabels = new MultiSelectDialog()
|
||||
.title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
|
||||
.titleSize(25)
|
||||
.positiveText(getResources().getString(R.string.saveButton))
|
||||
.negativeText(getResources().getString(R.string.cancelButton))
|
||||
.setMinSelectionLimit(0)
|
||||
.setMaxSelectionLimit(listOfLabels.size())
|
||||
.multiSelectList(listOfLabels)
|
||||
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
|
||||
@Override
|
||||
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
|
||||
|
||||
String labelIds = selectedIds.toString();
|
||||
int[] integers;
|
||||
if (selectedIds.size() > 0) {
|
||||
|
||||
String[] items = labelIds.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
|
||||
integers = new int[items.length];
|
||||
for (int i = 0; i < integers.length; i++) {
|
||||
integers[i] = Integer.parseInt(items[i]);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
integers = new int[0];
|
||||
}
|
||||
|
||||
updateIssueLabels(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
|
||||
tinyDb.putBoolean("singleIssueUpdate", true);
|
||||
CloseActivity();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
CloseActivity();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
multiSelectDialogLabels.show(getSupportFragmentManager(), "issueMultiSelectDialog");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
// get current issue labels
|
||||
|
||||
}
|
||||
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.genericError));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void updateIssueLabels(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, int issueIndex, int[] issueLabels, String loginUid) {
|
||||
|
||||
Labels patchIssueLabels = new Labels(issueLabels);
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.updateIssueLabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
Toasty.info(ctx, ctx.getString(R.string.labelsUpdated));
|
||||
|
||||
}
|
||||
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.genericError));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void CloseActivity() {
|
||||
this.finish();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import org.mian.gitnex.adapters.AdminCronTasksAdapter;
|
||||
import org.mian.gitnex.databinding.ActivityAdminCronTasksBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.viewmodels.AdminCronTasksViewModel;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class AdminCronTasksActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private AdminCronTasksAdapter adapter;
|
||||
|
||||
private ActivityAdminCronTasksBinding activityAdminCronTasksBinding;
|
||||
|
||||
public static final int PAGE = 1;
|
||||
public static final int LIMIT = 50;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
activityAdminCronTasksBinding = ActivityAdminCronTasksBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityAdminCronTasksBinding.getRoot());
|
||||
|
||||
initCloseListener();
|
||||
activityAdminCronTasksBinding.close.setOnClickListener(onClickListener);
|
||||
|
||||
Toolbar toolbar = activityAdminCronTasksBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
activityAdminCronTasksBinding.recyclerView.setHasFixedSize(true);
|
||||
activityAdminCronTasksBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(activityAdminCronTasksBinding.recyclerView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
activityAdminCronTasksBinding.recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
activityAdminCronTasksBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
activityAdminCronTasksBinding.pullToRefresh.setRefreshing(false);
|
||||
AdminCronTasksViewModel.loadCronTasksList(ctx, Authorization.get(ctx), PAGE, LIMIT);
|
||||
|
||||
}, 500));
|
||||
|
||||
fetchDataAsync(ctx, Authorization.get(ctx));
|
||||
}
|
||||
|
||||
private void fetchDataAsync(Context ctx, String instanceToken) {
|
||||
|
||||
AdminCronTasksViewModel cronTasksViewModel = new ViewModelProvider(this).get(AdminCronTasksViewModel.class);
|
||||
|
||||
cronTasksViewModel.getCronTasksList(ctx, instanceToken, PAGE, LIMIT).observe(this, cronTasksListMain -> {
|
||||
|
||||
adapter = new AdminCronTasksAdapter(ctx, cronTasksListMain);
|
||||
|
||||
if(adapter.getItemCount() > 0) {
|
||||
|
||||
activityAdminCronTasksBinding.recyclerView.setVisibility(View.VISIBLE);
|
||||
activityAdminCronTasksBinding.recyclerView.setAdapter(adapter);
|
||||
activityAdminCronTasksBinding.noData.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
activityAdminCronTasksBinding.recyclerView.setVisibility(View.GONE);
|
||||
activityAdminCronTasksBinding.noData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,10 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
@@ -19,16 +12,20 @@ import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.AdminGetUsersAdapter;
|
||||
import org.mian.gitnex.databinding.ActivityAdminGetUsersBinding;
|
||||
import org.mian.gitnex.fragments.BottomSheetAdminUsersFragment;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.models.UserInfo;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.viewmodels.AdminGetUsersViewModel;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -37,84 +34,69 @@ import java.util.Objects;
|
||||
public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAdminUsersFragment.BottomSheetListener {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
final Context ctx = this;
|
||||
private AdminGetUsersAdapter adapter;
|
||||
private RecyclerView mRecyclerView;
|
||||
private TextView noDataUsers;
|
||||
private Boolean searchFilter = false;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_admin_get_users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
ActivityAdminGetUsersBinding activityAdminGetUsersBinding = ActivityAdminGetUsersBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityAdminGetUsersBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
noDataUsers = findViewById(R.id.noDataUsers);
|
||||
mRecyclerView = findViewById(R.id.recyclerView);
|
||||
ImageView closeActivity = activityAdminGetUsersBinding.close;
|
||||
noDataUsers = activityAdminGetUsersBinding.noDataUsers;
|
||||
mRecyclerView = activityAdminGetUsersBinding.recyclerView;
|
||||
|
||||
final SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh);
|
||||
final SwipeRefreshLayout swipeRefresh = activityAdminGetUsersBinding.pullToRefresh;
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
Toolbar toolbar = activityAdminGetUsersBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
mRecyclerView.setHasFixedSize(true);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
swipeRefresh.setRefreshing(false);
|
||||
AdminGetUsersViewModel.loadUsersList(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken));
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
fetchDataAsync(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken));
|
||||
swipeRefresh.setRefreshing(false);
|
||||
AdminGetUsersViewModel.loadUsersList(ctx, Authorization.get(ctx));
|
||||
|
||||
}, 500));
|
||||
|
||||
fetchDataAsync(ctx, Authorization.get(ctx));
|
||||
|
||||
}
|
||||
|
||||
private void fetchDataAsync(Context ctx, String instanceUrl, String instanceToken) {
|
||||
private void fetchDataAsync(Context ctx, String instanceToken) {
|
||||
|
||||
AdminGetUsersViewModel usersModel = ViewModelProviders.of(this).get(AdminGetUsersViewModel.class);
|
||||
AdminGetUsersViewModel usersModel = new ViewModelProvider(this).get(AdminGetUsersViewModel.class);
|
||||
|
||||
usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable List<UserInfo> usersListMain) {
|
||||
adapter = new AdminGetUsersAdapter(getApplicationContext(), usersListMain);
|
||||
if(adapter.getItemCount() > 0) {
|
||||
mRecyclerView.setVisibility(View.VISIBLE);
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
noDataUsers.setVisibility(View.GONE);
|
||||
searchFilter = true;
|
||||
}
|
||||
else {
|
||||
//adapter.notifyDataSetChanged();
|
||||
//mRecyclerView.setAdapter(adapter);
|
||||
mRecyclerView.setVisibility(View.GONE);
|
||||
noDataUsers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
usersModel.getUsersList(ctx, instanceToken).observe(this, usersListMain -> {
|
||||
|
||||
adapter = new AdminGetUsersAdapter(ctx, usersListMain);
|
||||
if(adapter.getItemCount() > 0) {
|
||||
|
||||
mRecyclerView.setVisibility(View.VISIBLE);
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
noDataUsers.setVisibility(View.GONE);
|
||||
searchFilter = true;
|
||||
}
|
||||
else {
|
||||
|
||||
mRecyclerView.setVisibility(View.GONE);
|
||||
noDataUsers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
@@ -125,37 +107,37 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
|
||||
final MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
|
||||
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(searchFilter) {
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getApplicationContext()));
|
||||
if(searchFilter) {
|
||||
|
||||
inflater.inflate(R.menu.search_menu, menu);
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
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);
|
||||
inflater.inflate(R.menu.search_menu, menu);
|
||||
|
||||
if(!connToInternet) {
|
||||
return;
|
||||
MenuItem searchItem = menu.findItem(R.id.action_search);
|
||||
SearchView searchView = (SearchView) searchItem.getActionView();
|
||||
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
|
||||
if(!connToInternet) {
|
||||
return;
|
||||
}
|
||||
|
||||
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) { return true; }
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
|
||||
adapter.getFilter().filter(newText);
|
||||
return false;
|
||||
}
|
||||
|
||||
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
adapter.getFilter().filter(newText);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, 500);
|
||||
|
||||
return true;
|
||||
@@ -166,18 +148,21 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
case R.id.genericMenu:
|
||||
BottomSheetAdminUsersFragment bottomSheet = new BottomSheetAdminUsersFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet");
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
if(id == android.R.id.home) {
|
||||
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.genericMenu) {
|
||||
|
||||
BottomSheetAdminUsersFragment bottomSheet = new BottomSheetAdminUsersFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -192,12 +177,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,109 +1,136 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import org.acra.ACRA;
|
||||
import org.acra.BuildConfig;
|
||||
import org.acra.annotation.AcraNotification;
|
||||
import org.acra.config.CoreConfigurationBuilder;
|
||||
import org.acra.config.LimiterConfigurationBuilder;
|
||||
import org.acra.config.MailSenderConfigurationBuilder;
|
||||
import org.acra.data.StringFormat;
|
||||
import androidx.biometric.BiometricPrompt;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.helpers.FontsOverride;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.notifications.Notifications;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
@AcraNotification(resIcon = R.drawable.gitnex_transparent,
|
||||
resTitle = R.string.crashTitle,
|
||||
resChannelName = R.string.setCrashReports,
|
||||
resText = R.string.crashMessage)
|
||||
|
||||
public abstract class BaseActivity extends AppCompatActivity {
|
||||
|
||||
protected TinyDB tinyDB;
|
||||
|
||||
protected Context ctx = this;
|
||||
protected Context appCtx;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if(tinyDb.getInt("themeId") == 1) {
|
||||
setTheme(R.style.AppThemeLight);
|
||||
}
|
||||
else if(tinyDb.getInt("themeId") == 2) {
|
||||
this.appCtx = getApplicationContext();
|
||||
this.tinyDB = TinyDB.getInstance(appCtx);
|
||||
|
||||
boolean timeSetterFlag = TimeHelper.timeBetweenHours(18, 6); // 6pm to 6am
|
||||
switch(tinyDB.getInt("themeId")) {
|
||||
|
||||
if(timeSetterFlag) {
|
||||
setTheme(R.style.AppTheme);
|
||||
}
|
||||
else {
|
||||
case 1:
|
||||
|
||||
tinyDB.putString("currentTheme", "light");
|
||||
setTheme(R.style.AppThemeLight);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
||||
if(TimeHelper.timeBetweenHours(tinyDB.getInt("darkThemeTimeHour"), tinyDB.getInt("lightThemeTimeHour"), tinyDB.getInt("darkThemeTimeMinute"), tinyDB.getInt("lightThemeTimeMinute"))) {
|
||||
|
||||
tinyDB.putString("currentTheme", "dark");
|
||||
setTheme(R.style.AppTheme);
|
||||
}
|
||||
else {
|
||||
|
||||
tinyDB.putString("currentTheme", "light");
|
||||
setTheme(R.style.AppThemeLight);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
|
||||
tinyDB.putString("currentTheme", "light");
|
||||
setTheme(R.style.AppThemeRetro);
|
||||
break;
|
||||
case 4:
|
||||
if(TimeHelper.timeBetweenHours(tinyDB.getInt("darkThemeTimeHour"), tinyDB.getInt("lightThemeTimeHour"), tinyDB.getInt("darkThemeTimeMinute"), tinyDB.getInt("lightThemeTimeMinute"))) {
|
||||
|
||||
tinyDB.putString("currentTheme", "dark");
|
||||
setTheme(R.style.AppTheme);
|
||||
}
|
||||
else {
|
||||
|
||||
tinyDB.putString("currentTheme", "light");
|
||||
setTheme(R.style.AppThemeRetro);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
|
||||
tinyDB.putString("currentTheme", "dark");
|
||||
setTheme(R.style.AppThemePitchBlack);
|
||||
break;
|
||||
default:
|
||||
|
||||
tinyDB.putString("currentTheme", "dark");
|
||||
setTheme(R.style.AppTheme);
|
||||
|
||||
}
|
||||
|
||||
String locale = tinyDB.getString("locale");
|
||||
if (locale.isEmpty()) {
|
||||
AppUtil.setAppLocale(getResources(), Locale.getDefault().getLanguage());
|
||||
}
|
||||
else {
|
||||
setTheme(R.style.AppTheme);
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getLayoutResourceId());
|
||||
|
||||
switch(tinyDb.getInt("customFontId", -1)) {
|
||||
|
||||
case 0:
|
||||
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/roboto.ttf");
|
||||
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/roboto.ttf");
|
||||
FontsOverride.setDefaultFont(this, "SERIF", "fonts/roboto.ttf");
|
||||
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/roboto.ttf");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/sourcecodeproregular.ttf");
|
||||
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/sourcecodeproregular.ttf");
|
||||
FontsOverride.setDefaultFont(this, "SERIF", "fonts/sourcecodeproregular.ttf");
|
||||
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/sourcecodeproregular.ttf");
|
||||
break;
|
||||
|
||||
default:
|
||||
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/manroperegular.ttf");
|
||||
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/manroperegular.ttf");
|
||||
FontsOverride.setDefaultFont(this, "SERIF", "fonts/manroperegular.ttf");
|
||||
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/manroperegular.ttf");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// enabling counter badges by default
|
||||
if(tinyDb.getString("enableCounterBadgesInit").isEmpty()) {
|
||||
tinyDb.putBoolean("enableCounterBadges", true);
|
||||
tinyDb.putString("enableCounterBadgesInit", "yes");
|
||||
}
|
||||
|
||||
// enable crash reports by default
|
||||
if(tinyDb.getString("crashReportingEnabledInit").isEmpty()) {
|
||||
tinyDb.putBoolean("crashReportingEnabled", true);
|
||||
tinyDb.putString("crashReportingEnabledInit", "yes");
|
||||
}
|
||||
|
||||
if (tinyDb.getBoolean("crashReportingEnabled")) {
|
||||
|
||||
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);
|
||||
ACRABuilder.setBuildConfigClass(BuildConfig.class).setReportFormat(StringFormat.KEY_VALUE_LIST);
|
||||
ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class).setReportAsFile(true).setMailTo(getResources().getString(R.string.appEmail)).setSubject(getResources().getString(R.string.crashReportEmailSubject, AppUtil.getAppBuildNo(getApplicationContext()))).setEnabled(true);
|
||||
ACRABuilder.getPluginConfigurationBuilder(LimiterConfigurationBuilder.class).setEnabled(true);
|
||||
ACRA.init(getApplication(), ACRABuilder);
|
||||
|
||||
AppUtil.setAppLocale(getResources(), locale);
|
||||
}
|
||||
|
||||
Notifications.startWorker(appCtx);
|
||||
}
|
||||
|
||||
protected abstract int getLayoutResourceId();
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if(tinyDB.getBoolean("biometricStatus") && !tinyDB.getBoolean("biometricLifeCycle")) {
|
||||
|
||||
Executor executor = ContextCompat.getMainExecutor(this);
|
||||
|
||||
BiometricPrompt biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() {
|
||||
|
||||
@Override
|
||||
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
|
||||
|
||||
super.onAuthenticationError(errorCode, errString);
|
||||
|
||||
// Authentication error, close the app
|
||||
if(errorCode == BiometricPrompt.ERROR_USER_CANCELED ||
|
||||
errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
// Authentication succeeded, continue to app
|
||||
@Override public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) { super.onAuthenticationSucceeded(result); tinyDB.putBoolean("biometricLifeCycle", true); }
|
||||
|
||||
// Authentication failed, close the app
|
||||
@Override public void onAuthenticationFailed() { super.onAuthenticationFailed(); }
|
||||
|
||||
});
|
||||
|
||||
BiometricPrompt.PromptInfo biometricPromptBuilder = new BiometricPrompt.PromptInfo.Builder()
|
||||
.setTitle(getString(R.string.biometricAuthTitle))
|
||||
.setSubtitle(getString(R.string.biometricAuthSubTitle))
|
||||
.setNegativeButtonText(getString(R.string.cancelButton)).build();
|
||||
|
||||
biometricPrompt.authenticate(biometricPromptBuilder);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
@@ -13,312 +14,254 @@ import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import com.mikepenz.fastadapter.IItemAdapter;
|
||||
import com.mikepenz.fastadapter.adapters.ItemAdapter;
|
||||
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
|
||||
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
|
||||
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
|
||||
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
|
||||
import org.gitnex.tea4j.models.Commits;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.adapters.CommitsAdapter;
|
||||
import org.mian.gitnex.models.Commits;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCommitsBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class CommitsActivity extends BaseActivity implements ItemFilterListener<CommitsAdapter> {
|
||||
public class CommitsActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView noData;
|
||||
private ProgressBar progressBar;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private String TAG = "CommitsActivity - ";
|
||||
private int resultLimit = 50;
|
||||
private boolean loadNextFlag = false;
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView noData;
|
||||
private ProgressBar progressBar;
|
||||
private String TAG = "CommitsActivity";
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private int pageSize = 1;
|
||||
|
||||
private List<CommitsAdapter> items = new ArrayList<>();
|
||||
private FastItemAdapter<CommitsAdapter> fastItemAdapter;
|
||||
private ItemAdapter footerAdapter;
|
||||
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
|
||||
private RecyclerView recyclerView;
|
||||
private List<Commits> commitsList;
|
||||
private CommitsAdapter adapter;
|
||||
private ProgressBar progressLoadMore;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_commits;
|
||||
}
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActivityCommitsBinding activityCommitsBinding = ActivityCommitsBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCommitsBinding.getRoot());
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
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];
|
||||
Toolbar toolbar = activityCommitsBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
String branchName = getIntent().getStringExtra("branchName");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
TextView toolbar_title = findViewById(R.id.toolbar_title);
|
||||
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
|
||||
toolbar_title.setText(branchName);
|
||||
String branchName = getIntent().getStringExtra("branchName");
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
noData = findViewById(R.id.noDataCommits);
|
||||
progressBar = findViewById(R.id.progress_bar);
|
||||
swipeRefreshLayout = findViewById(R.id.pullToRefresh);
|
||||
TextView toolbar_title = activityCommitsBinding.toolbarTitle;
|
||||
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
|
||||
toolbar_title.setText(branchName);
|
||||
|
||||
RecyclerView recyclerView = findViewById(R.id.recyclerView);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
|
||||
recyclerView.setHasFixedSize(true);
|
||||
ImageView closeActivity = activityCommitsBinding.close;
|
||||
noData = activityCommitsBinding.noDataCommits;
|
||||
progressLoadMore = activityCommitsBinding.progressLoadMore;
|
||||
progressBar = activityCommitsBinding.progressBar;
|
||||
SwipeRefreshLayout swipeRefresh = activityCommitsBinding.pullToRefresh;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
fastItemAdapter = new FastItemAdapter<>();
|
||||
fastItemAdapter.withSelectable(true);
|
||||
// if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances)
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12")) {
|
||||
|
||||
footerAdapter = items();
|
||||
//noinspection unchecked
|
||||
fastItemAdapter.addAdapter(1, footerAdapter);
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<CommitsAdapter>) (item, constraint) -> item.getCommitTitle().toLowerCase().contains(Objects.requireNonNull(constraint).toString().toLowerCase()));
|
||||
recyclerView = activityCommitsBinding.recyclerView;
|
||||
commitsList = new ArrayList<>();
|
||||
|
||||
fastItemAdapter.getItemFilter().withItemFilterListener(this);
|
||||
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
|
||||
recyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
recyclerView.setAdapter(fastItemAdapter);
|
||||
swipeRefresh.setRefreshing(false);
|
||||
loadInitial(Authorization.get(ctx), repoOwner, repoName, branchName, resultLimit);
|
||||
adapter.notifyDataChanged();
|
||||
}, 200));
|
||||
|
||||
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
|
||||
adapter = new CommitsAdapter(ctx, commitsList);
|
||||
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
|
||||
|
||||
@Override
|
||||
public void onLoadMore(final int currentPage) {
|
||||
if(commitsList.size() == resultLimit || pageSize == resultLimit) {
|
||||
|
||||
loadNext(instanceUrl, instanceToken, repoOwner, repoName, currentPage, branchName);
|
||||
int page = (commitsList.size() + resultLimit) / resultLimit;
|
||||
loadMore(Authorization.get(ctx), repoOwner, repoName, page, branchName, resultLimit);
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
};
|
||||
loadInitial(Authorization.get(ctx), repoOwner, repoName, branchName, resultLimit);
|
||||
}
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
private void loadInitial(String token, String repoOwner, String repoName, String branchName, int resultLimit) {
|
||||
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
fastItemAdapter.clear();
|
||||
endlessRecyclerOnScrollListener.resetPageCount();
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
Call<List<Commits>> call = RetrofitClient.getApiInterface(ctx).getRepositoryCommits(token, repoOwner, repoName, 1, branchName, resultLimit);
|
||||
|
||||
});
|
||||
call.enqueue(new Callback<List<Commits>>() {
|
||||
|
||||
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
|
||||
|
||||
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, branchName);
|
||||
if(response.code() == 200) {
|
||||
|
||||
assert savedInstanceState != null;
|
||||
fastItemAdapter.withSavedInstanceState(savedInstanceState);
|
||||
assert response.body() != null;
|
||||
if(response.body().size() > 0) {
|
||||
|
||||
}
|
||||
commitsList.clear();
|
||||
commitsList.addAll(response.body());
|
||||
adapter.notifyDataChanged();
|
||||
noData.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String branchName) {
|
||||
commitsList.clear();
|
||||
adapter.notifyDataChanged();
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
if(response.code() == 409) {
|
||||
|
||||
Call<List<Commits>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getRepositoryCommits(token, repoOwner, repoName, 1, branchName);
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
|
||||
call.enqueue(new Callback<List<Commits>>() {
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
|
||||
|
||||
assert response.body() != null;
|
||||
Toasty.error(ctx, getResources().getString(R.string.errorOnLogin));
|
||||
}
|
||||
|
||||
if(response.body().size() > 0) {
|
||||
});
|
||||
|
||||
if(response.body().size() == resultLimit) {
|
||||
loadNextFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < response.body().size(); i++) {
|
||||
private void loadMore(String token, String repoOwner, String repoName, final int page, String branchName, int resultLimit) {
|
||||
|
||||
items.add(new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(), response.body().get(i).getHtml_url(),
|
||||
response.body().get(i).getCommit().getCommitter().getName(), response.body().get(i).getCommit().getCommitter().getDate()));
|
||||
progressLoadMore.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
Call<List<Commits>> call = RetrofitClient.getApiInterface(ctx).getRepositoryCommits(token, repoOwner, repoName, page, branchName, resultLimit);
|
||||
|
||||
fastItemAdapter.add(items);
|
||||
call.enqueue(new Callback<List<Commits>>() {
|
||||
|
||||
}
|
||||
else {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
|
||||
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
}
|
||||
List<Commits> result = response.body();
|
||||
assert result != null;
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
if(result.size() > 0) {
|
||||
|
||||
}
|
||||
else {
|
||||
pageSize = result.size();
|
||||
commitsList.addAll(result);
|
||||
}
|
||||
else {
|
||||
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
adapter.setMoreDataAvailable(false);
|
||||
}
|
||||
|
||||
}
|
||||
adapter.notifyDataChanged();
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
|
||||
progressLoadMore.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Log.e(TAG, t.toString());
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
|
||||
|
||||
}
|
||||
Toasty.error(ctx, getResources().getString(R.string.errorOnLogin));
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, final int currentPage, String branchName) {
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
footerAdapter.clear();
|
||||
//noinspection unchecked
|
||||
footerAdapter.add(new ProgressItem().withEnabled(false));
|
||||
Handler handler = new Handler();
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.search_menu, menu);
|
||||
|
||||
handler.postDelayed(() -> {
|
||||
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);
|
||||
|
||||
Call<List<Commits>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getRepositoryCommits(token, repoOwner, repoName, currentPage + 1, branchName);
|
||||
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
|
||||
|
||||
call.enqueue(new Callback<List<Commits>>() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
|
||||
assert response.body() != null;
|
||||
filter(newText);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (response.body().size() > 0) {
|
||||
});
|
||||
|
||||
loadNextFlag = response.body().size() == resultLimit;
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
for (int i = 0; i < response.body().size(); i++) {
|
||||
private void filter(String text) {
|
||||
|
||||
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(),
|
||||
response.body().get(i).getHtml_url(), response.body().get(i).getCommit().getCommitter().getName(),
|
||||
response.body().get(i).getCommit().getCommitter().getDate()));
|
||||
List<Commits> arr = new ArrayList<>();
|
||||
|
||||
}
|
||||
for(Commits d : commitsList) {
|
||||
|
||||
footerAdapter.clear();
|
||||
if(d.getCommit().getMessage().toLowerCase().contains(text) || d.getSha().toLowerCase().contains(text)) {
|
||||
|
||||
}
|
||||
else {
|
||||
arr.add(d);
|
||||
}
|
||||
}
|
||||
|
||||
footerAdapter.clear();
|
||||
}
|
||||
adapter.updateList(arr);
|
||||
}
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
private void initCloseListener() {
|
||||
|
||||
}
|
||||
else {
|
||||
onClickListener = view -> {
|
||||
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e(TAG, t.toString());
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}, 1000);
|
||||
|
||||
if(!loadNextFlag) {
|
||||
|
||||
footerAdapter.clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.search_menu, menu);
|
||||
|
||||
MenuItem searchItem = menu.findItem(R.id.action_search);
|
||||
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
|
||||
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
|
||||
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
fastItemAdapter.filter(newText);
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
endlessRecyclerOnScrollListener.enable();
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<CommitsAdapter> results) {
|
||||
endlessRecyclerOnScrollListener.disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReset() {
|
||||
endlessRecyclerOnScrollListener.enable();
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = view -> {
|
||||
getIntent().removeExtra("branchName");
|
||||
finish();
|
||||
};
|
||||
}
|
||||
getIntent().removeExtra("branchName");
|
||||
finish();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.gitnex.tea4j.models.Branches;
|
||||
import org.gitnex.tea4j.models.DeleteFile;
|
||||
import org.gitnex.tea4j.models.EditFile;
|
||||
import org.gitnex.tea4j.models.NewFile;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateFileBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.NetworkStatusObserver;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Branches;
|
||||
import org.mian.gitnex.models.NewFile;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
@@ -35,311 +34,355 @@ import retrofit2.Callback;
|
||||
|
||||
public class CreateFileActivity extends BaseActivity {
|
||||
|
||||
public ImageView closeActivity;
|
||||
private View.OnClickListener onClickListener;
|
||||
private Button newFileCreate;
|
||||
private ActivityCreateFileBinding binding;
|
||||
|
||||
private EditText newFileName;
|
||||
private EditText newFileContent;
|
||||
private EditText newFileBranchName;
|
||||
private EditText newFileCommitMessage;
|
||||
private Spinner newFileBranchesSpinner;
|
||||
final Context ctx = this;
|
||||
public static final int FILE_ACTION_CREATE = 0;
|
||||
public static final int FILE_ACTION_DELETE = 1;
|
||||
public static final int FILE_ACTION_EDIT = 2;
|
||||
|
||||
List<Branches> branchesList = new ArrayList<>();
|
||||
private int fileAction = FILE_ACTION_CREATE;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_new_file;
|
||||
}
|
||||
private String filePath;
|
||||
private String fileSha;
|
||||
|
||||
private final List<String> branches = new ArrayList<>();
|
||||
|
||||
private String repoOwner;
|
||||
private String repoName;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
binding = ActivityCreateFileBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
repoOwner = parts[0];
|
||||
repoName = parts[1];
|
||||
|
||||
closeActivity = findViewById(R.id.close);
|
||||
newFileName = findViewById(R.id.newFileName);
|
||||
newFileContent = findViewById(R.id.newFileContent);
|
||||
newFileBranchName = findViewById(R.id.newFileBranchName);
|
||||
newFileCommitMessage = findViewById(R.id.newFileCommitMessage);
|
||||
TextView toolbarTitle = binding.toolbarTitle;
|
||||
|
||||
newFileName.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(newFileName, InputMethodManager.SHOW_IMPLICIT);
|
||||
binding.newFileName.requestFocus();
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
assert inputMethodManager != null;
|
||||
inputMethodManager.showSoftInput(binding.newFileName, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
newFileCreate = findViewById(R.id.newFileCreate);
|
||||
binding.close.setOnClickListener(view -> finish());
|
||||
binding.newFileContent.setOnTouchListener((touchView, motionEvent) -> {
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
newFileBranchesSpinner = findViewById(R.id.newFileBranchesSpinner);
|
||||
newFileBranchesSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
|
||||
getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 &&
|
||||
(motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
|
||||
newFileBranchesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
|
||||
{
|
||||
public void onItemSelected(AdapterView<?> arg0,
|
||||
View arg1, int arg2, long arg3)
|
||||
{
|
||||
Branches bModelValue = (Branches) newFileBranchesSpinner.getSelectedItem();
|
||||
Log.i("bModelSelected", bModelValue.toString());
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
|
||||
if(bModelValue.toString().equals("No branch")) {
|
||||
newFileBranchName.setEnabled(true);
|
||||
}
|
||||
else {
|
||||
newFileBranchName.setEnabled(false);
|
||||
newFileBranchName.setText("");
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
public void onNothingSelected(AdapterView<?> arg0) {}
|
||||
});
|
||||
if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", FILE_ACTION_DELETE) == FILE_ACTION_DELETE) {
|
||||
|
||||
fileAction = getIntent().getIntExtra("fileAction", FILE_ACTION_DELETE);
|
||||
filePath = getIntent().getStringExtra("filePath");
|
||||
fileSha = getIntent().getStringExtra("fileSha");
|
||||
|
||||
toolbarTitle.setText(getString(R.string.deleteFileText, filePath));
|
||||
|
||||
binding.newFileCreate.setText(R.string.deleteFile);
|
||||
|
||||
binding.newFileNameLayout.setVisibility(View.GONE);
|
||||
binding.newFileContentLayout.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", FILE_ACTION_EDIT) == FILE_ACTION_EDIT) {
|
||||
|
||||
fileAction = getIntent().getIntExtra("fileAction", FILE_ACTION_EDIT);
|
||||
filePath = getIntent().getStringExtra("filePath");
|
||||
fileSha = getIntent().getStringExtra("fileSha");
|
||||
|
||||
toolbarTitle.setText(getString(R.string.editFileText, filePath));
|
||||
|
||||
binding.newFileCreate.setText(R.string.editFile);
|
||||
binding.newFileName.setText(filePath);
|
||||
binding.newFileName.setEnabled(false);
|
||||
binding.newFileName.setFocusable(false);
|
||||
|
||||
binding.newFileContent.setText(getIntent().getStringExtra("fileContents"));
|
||||
|
||||
}
|
||||
|
||||
getBranches(repoOwner, repoName);
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
if(!connToInternet) {
|
||||
NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.getInstance(ctx);
|
||||
networkStatusObserver.registerNetworkStatusListener(binding.newFileCreate::setEnabled);
|
||||
|
||||
newFileCreate.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
newFileCreate.setBackground(shape);
|
||||
|
||||
} else {
|
||||
|
||||
newFileCreate.setOnClickListener(createFileListener);
|
||||
|
||||
}
|
||||
binding.newFileCreate.setOnClickListener(v -> processNewFile());
|
||||
|
||||
}
|
||||
|
||||
private View.OnClickListener createFileListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processNewFile();
|
||||
}
|
||||
};
|
||||
|
||||
private void processNewFile() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
AppUtil appUtil = new AppUtil();
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
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];
|
||||
String newFileName = binding.newFileName.getText() != null ? binding.newFileName.getText().toString() : "";
|
||||
String newFileContent = binding.newFileContent.getText() != null ? binding.newFileContent.getText().toString() : "";
|
||||
String newFileBranchName = binding.newFileBranches.getText() != null ? binding.newFileBranches.getText().toString() : "";
|
||||
String newFileCommitMessage = binding.newFileCommitMessage.getText() != null ? binding.newFileCommitMessage.getText().toString() : "";
|
||||
|
||||
String newFileName_ = newFileName.getText().toString();
|
||||
String newFileContent_ = newFileContent.getText().toString();
|
||||
String newFileBranchName_ = newFileBranchName.getText().toString();
|
||||
String newFileCommitMessage_ = newFileCommitMessage.getText().toString();
|
||||
|
||||
Branches currentBranch = (Branches) newFileBranchesSpinner.getSelectedItem();
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
if(!AppUtil.hasNetworkConnection(appCtx)) {
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.newFileRequiredFields));
|
||||
if(((newFileName.isEmpty() || newFileContent.isEmpty()) && fileAction != FILE_ACTION_DELETE) || newFileCommitMessage.isEmpty()) {
|
||||
Toasty.error(ctx, getString(R.string.newFileRequiredFields));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(currentBranch.toString().equals("No branch")) {
|
||||
|
||||
if(newFileBranchName_.equals("")) {
|
||||
Toasty.info(getApplicationContext(), getString(R.string.newFileRequiredFieldNewBranchName));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if(!appUtil.checkStringsWithDash(newFileBranchName_)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.newFileInvalidBranchName));
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
if(!AppUtil.checkStringsWithDash(newFileBranchName)) {
|
||||
Toasty.error(ctx, getString(R.string.newFileInvalidBranchName));
|
||||
return;
|
||||
}
|
||||
|
||||
if(newFileCommitMessage.length() > 255) {
|
||||
Toasty.warning(ctx, getString(R.string.newFileCommitMessageError));
|
||||
return;
|
||||
}
|
||||
|
||||
if(appUtil.charactersLength(newFileCommitMessage_) > 255) {
|
||||
disableProcessButton();
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.newFileCommitMessageError));
|
||||
switch(fileAction) {
|
||||
|
||||
case FILE_ACTION_CREATE:
|
||||
createNewFile(repoOwner, repoName, newFileName, AppUtil.encodeBase64(newFileContent), newFileCommitMessage, newFileBranchName);
|
||||
break;
|
||||
|
||||
case FILE_ACTION_DELETE:
|
||||
deleteFile(repoOwner, repoName, filePath, newFileCommitMessage, newFileBranchName, fileSha);
|
||||
break;
|
||||
|
||||
case FILE_ACTION_EDIT:
|
||||
editFile(repoOwner, repoName, filePath, AppUtil.encodeBase64(newFileContent), newFileCommitMessage, newFileBranchName, fileSha);
|
||||
break;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
disableProcessButton();
|
||||
createNewFile(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newFileName_, appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createNewFile(final String instanceUrl, final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileBranchName, String fileCommitMessage, String currentBranch) {
|
||||
private void createNewFile(String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName) {
|
||||
|
||||
NewFile createNewFileJsonStr;
|
||||
if(currentBranch.equals("No branch")) {
|
||||
createNewFileJsonStr = new NewFile("", fileContent, fileCommitMessage, fileBranchName);
|
||||
}
|
||||
else {
|
||||
createNewFileJsonStr = new NewFile(currentBranch, fileContent, fileCommitMessage, "");
|
||||
}
|
||||
NewFile createNewFileJsonStr = branches.contains(branchName) ?
|
||||
new NewFile(branchName, fileContent, fileCommitMessage, "") :
|
||||
new NewFile("", fileContent, fileCommitMessage, branchName);
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr);
|
||||
.getApiInterface(ctx)
|
||||
.createNewFile(Authorization.get(ctx), repoOwner, repoName, fileName, createNewFileJsonStr);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
if(response.code() == 201) {
|
||||
switch(response.code()) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.newFileSuccessMessage));
|
||||
finish();
|
||||
case 201:
|
||||
enableProcessButton();
|
||||
Toasty.success(ctx, getString(R.string.newFileSuccessMessage));
|
||||
finish();
|
||||
break;
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
case 401:
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
case 404:
|
||||
enableProcessButton();
|
||||
Toasty.warning(ctx, getString(R.string.apiNotFound));
|
||||
break;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
if(response.code() == 404) {
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
|
||||
}
|
||||
else {
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.orgCreatedError));
|
||||
}
|
||||
|
||||
}
|
||||
default:
|
||||
enableProcessButton();
|
||||
Toasty.error(ctx, getString(R.string.orgCreatedError));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
|
||||
private void deleteFile(String repoOwner, String repoName, String fileName, String fileCommitMessage, String branchName, String fileSha) {
|
||||
|
||||
DeleteFile deleteFileJsonStr = branches.contains(branchName) ?
|
||||
new DeleteFile(branchName, fileCommitMessage, "", fileSha) :
|
||||
new DeleteFile("", fileCommitMessage, branchName, fileSha);
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.deleteFile(Authorization.get(ctx), repoOwner, repoName, fileName, deleteFileJsonStr);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 200:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.deleteFileMessage, tinyDB.getString("repoBranch")));
|
||||
getIntent().removeExtra("filePath");
|
||||
getIntent().removeExtra("fileSha");
|
||||
getIntent().removeExtra("fileContents");
|
||||
finish();
|
||||
break;
|
||||
|
||||
case 401:
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
case 404:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.apiNotFound));
|
||||
break;
|
||||
|
||||
default:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.genericError));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void editFile(String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName, String fileSha) {
|
||||
|
||||
EditFile editFileJsonStr = branches.contains(branchName) ?
|
||||
new EditFile(branchName, fileCommitMessage, "", fileSha, fileContent) :
|
||||
new EditFile("", fileCommitMessage, branchName, fileSha, fileContent);
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.editFile(Authorization.get(ctx), repoOwner, repoName, fileName, editFileJsonStr);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 200:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.editFileMessage, branchName));
|
||||
getIntent().removeExtra("filePath");
|
||||
getIntent().removeExtra("fileSha");
|
||||
getIntent().removeExtra("fileContents");
|
||||
tinyDB.putBoolean("fileModified", true);
|
||||
finish();
|
||||
break;
|
||||
|
||||
case 401:
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
case 404:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.apiNotFound));
|
||||
break;
|
||||
|
||||
default:
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, getString(R.string.genericError));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void getBranches(String repoOwner, String repoName) {
|
||||
|
||||
Call<List<Branches>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getBranches(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
.getApiInterface(ctx)
|
||||
.getBranches(Authorization.get(ctx), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Branches>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Branches>> call, @NonNull retrofit2.Response<List<Branches>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 200) {
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Branches> branchesList_ = response.body();
|
||||
assert response.body() != null;
|
||||
for(Branches branch : response.body()) branches.add(branch.getName());
|
||||
|
||||
branchesList.add(new Branches("No branch"));
|
||||
assert branchesList_ != null;
|
||||
if(branchesList_.size() > 0) {
|
||||
for (int i = 0; i < branchesList_.size(); i++) {
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(CreateFileActivity.this, R.layout.list_spinner_items, branches);
|
||||
|
||||
Branches data = new Branches(
|
||||
branchesList_.get(i).getName()
|
||||
);
|
||||
branchesList.add(data);
|
||||
binding.newFileBranches.setAdapter(adapter);
|
||||
binding.newFileBranches.setText(tinyDB.getString("repoBranch"), false);
|
||||
|
||||
}
|
||||
}
|
||||
enableProcessButton();
|
||||
|
||||
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateFileActivity.this,
|
||||
R.layout.spinner_item, branchesList);
|
||||
|
||||
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
newFileBranchesSpinner.setAdapter(adapter);
|
||||
enableProcessButton();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
newFileCreate.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
newFileCreate.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
newFileCreate.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
newFileCreate.setBackground(shape);
|
||||
|
||||
}
|
||||
private void disableProcessButton() { binding.newFileCreate.setEnabled(false); }
|
||||
private void enableProcessButton() { binding.newFileCreate.setEnabled(true); }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,299 +1,262 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.DatePicker;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.hendraanggrian.appcompat.socialview.Mention;
|
||||
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
|
||||
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
|
||||
import org.gitnex.tea4j.models.Collaborators;
|
||||
import org.gitnex.tea4j.models.CreateIssue;
|
||||
import org.gitnex.tea4j.models.Labels;
|
||||
import org.gitnex.tea4j.models.Milestones;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.AssigneesActions;
|
||||
import org.mian.gitnex.actions.LabelsActions;
|
||||
import org.mian.gitnex.adapters.AssigneesListAdapter;
|
||||
import org.mian.gitnex.adapters.LabelsListAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateIssueBinding;
|
||||
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
|
||||
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.MultiSelectDialog;
|
||||
import org.mian.gitnex.models.Collaborators;
|
||||
import org.mian.gitnex.models.CreateIssue;
|
||||
import org.mian.gitnex.models.Labels;
|
||||
import org.mian.gitnex.models.Milestones;
|
||||
import org.mian.gitnex.models.MultiSelectModel;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class CreateIssueActivity extends BaseActivity implements View.OnClickListener {
|
||||
public class CreateIssueActivity extends BaseActivity implements View.OnClickListener, LabelsListAdapter.LabelsListAdapterListener, AssigneesListAdapter.AssigneesListAdapterListener {
|
||||
|
||||
private ActivityCreateIssueBinding viewBinding;
|
||||
private CustomLabelsSelectionDialogBinding labelsBinding;
|
||||
private CustomAssigneesSelectionDialogBinding assigneesBinding;
|
||||
private View.OnClickListener onClickListener;
|
||||
MultiSelectDialog multiSelectDialog;
|
||||
MultiSelectDialog multiSelectDialogLabels;
|
||||
private TextView assigneesList;
|
||||
private TextView newIssueLabels;
|
||||
private TextView newIssueDueDate;
|
||||
private Spinner newIssueMilestoneSpinner;
|
||||
private EditText newIssueTitle;
|
||||
private SocialAutoCompleteTextView newIssueDescription;
|
||||
private Button createNewIssueButton;
|
||||
private TextView labelsIdHolder;
|
||||
private boolean assigneesFlag;
|
||||
private boolean labelsFlag;
|
||||
final Context ctx = this;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private Dialog dialogLabels;
|
||||
private Dialog dialogAssignees;
|
||||
private String labelsSetter;
|
||||
private String assigneesSetter;
|
||||
private int milestoneId;
|
||||
|
||||
List<Milestones> milestonesList = new ArrayList<>();
|
||||
ArrayList<MultiSelectModel> listOfAssignees = new ArrayList<>();
|
||||
ArrayList<MultiSelectModel> listOfLabels= new ArrayList<>();
|
||||
private ArrayAdapter<Mention> defaultMentionAdapter;
|
||||
private String loginUid;
|
||||
private String repoOwner;
|
||||
private String repoName;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_create_issue;
|
||||
}
|
||||
private LabelsListAdapter labelsAdapter;
|
||||
private AssigneesListAdapter assigneesAdapter;
|
||||
|
||||
private List<Integer> labelsIds = new ArrayList<>();
|
||||
private List<Labels> labelsList = new ArrayList<>();
|
||||
private List<Milestones> milestonesList = new ArrayList<>();
|
||||
private List<Collaborators> assigneesList = new ArrayList<>();
|
||||
private List<String> assigneesListData = new ArrayList<>();
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
viewBinding = ActivityCreateIssueBinding.inflate(getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String loginFullName = tinyDb.getString("userFullname");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
loginUid = tinyDB.getString("loginUid");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
repoOwner = parts[0];
|
||||
repoName = parts[1];
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
assigneesList = findViewById(R.id.newIssueAssigneesList);
|
||||
newIssueLabels = findViewById(R.id.newIssueLabels);
|
||||
newIssueDueDate = findViewById(R.id.newIssueDueDate);
|
||||
createNewIssueButton = findViewById(R.id.createNewIssueButton);
|
||||
newIssueTitle = findViewById(R.id.newIssueTitle);
|
||||
newIssueDescription = findViewById(R.id.newIssueDescription);
|
||||
labelsIdHolder = findViewById(R.id.labelsIdHolder);
|
||||
// require gitea 1.12 or higher
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
|
||||
newIssueTitle.requestFocus();
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
viewBinding.newIssueTitle.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(newIssueTitle, InputMethodManager.SHOW_IMPLICIT);
|
||||
imm.showSoftInput(viewBinding.newIssueTitle, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
defaultMentionAdapter = new MentionArrayAdapter<>(this);
|
||||
loadCollaboratorsList();
|
||||
viewBinding.newIssueDescription.setOnTouchListener((touchView, motionEvent) -> {
|
||||
|
||||
newIssueDescription.setMentionAdapter(defaultMentionAdapter);
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
labelsAdapter = new LabelsListAdapter(labelsList, CreateIssueActivity.this, labelsIds);
|
||||
assigneesAdapter = new AssigneesListAdapter(ctx, assigneesList, CreateIssueActivity.this, assigneesListData);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
viewBinding.close.setOnClickListener(onClickListener);
|
||||
|
||||
assigneesList.setOnClickListener(this);
|
||||
newIssueLabels.setOnClickListener(this);
|
||||
newIssueDueDate.setOnClickListener(this);
|
||||
viewBinding.newIssueAssigneesList.setOnClickListener(this);
|
||||
viewBinding.newIssueLabels.setOnClickListener(this);
|
||||
viewBinding.newIssueDueDate.setOnClickListener(this);
|
||||
|
||||
newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner);
|
||||
newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
|
||||
getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
|
||||
|
||||
getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
|
||||
getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName);
|
||||
getMilestones(repoOwner, repoName, resultLimit);
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
viewBinding.newIssueLabels.setOnClickListener(newIssueLabels -> showLabels());
|
||||
|
||||
viewBinding.newIssueAssigneesList.setOnClickListener(newIssueAssigneesList -> showAssignees());
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
createNewIssueButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createNewIssueButton.setBackground(shape);
|
||||
|
||||
} else {
|
||||
|
||||
createNewIssueButton.setOnClickListener(this);
|
||||
viewBinding.createNewIssueButton.setEnabled(false);
|
||||
}
|
||||
else {
|
||||
|
||||
viewBinding.createNewIssueButton.setOnClickListener(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assigneesInterface(List<String> data) {
|
||||
|
||||
assigneesSetter = String.valueOf(data);
|
||||
viewBinding.newIssueAssigneesList.setText(assigneesSetter.replace("]", "").replace("[", ""));
|
||||
assigneesListData = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void labelsInterface(List<String> data) {
|
||||
|
||||
labelsSetter = String.valueOf(data);
|
||||
viewBinding.newIssueLabels.setText(labelsSetter.replace("]", "").replace("[", ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void labelsIdsInterface(List<Integer> data) {
|
||||
|
||||
labelsIds = data;
|
||||
}
|
||||
|
||||
private void showAssignees() {
|
||||
|
||||
dialogAssignees = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
|
||||
|
||||
if (dialogAssignees.getWindow() != null) {
|
||||
|
||||
dialogAssignees.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
assigneesBinding = CustomAssigneesSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
|
||||
|
||||
View view = assigneesBinding.getRoot();
|
||||
dialogAssignees.setContentView(view);
|
||||
|
||||
assigneesBinding.cancel.setOnClickListener(assigneesBinding_ -> dialogAssignees.dismiss());
|
||||
|
||||
dialogAssignees.show();
|
||||
AssigneesActions.getRepositoryAssignees(ctx, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding);
|
||||
}
|
||||
|
||||
private void showLabels() {
|
||||
|
||||
dialogLabels = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
|
||||
|
||||
if (dialogLabels.getWindow() != null) {
|
||||
|
||||
dialogLabels.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
labelsBinding = CustomLabelsSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
|
||||
|
||||
View view = labelsBinding.getRoot();
|
||||
dialogLabels.setContentView(view);
|
||||
|
||||
labelsBinding.cancel.setOnClickListener(labelsBinding_ -> dialogLabels.dismiss());
|
||||
|
||||
dialogLabels.show();
|
||||
LabelsActions.getRepositoryLabels(ctx, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding);
|
||||
}
|
||||
|
||||
private void processNewIssue() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
Milestones mModel = (Milestones) newIssueMilestoneSpinner.getSelectedItem();
|
||||
|
||||
int newIssueMilestoneIdForm = mModel.getId();
|
||||
String newIssueTitleForm = newIssueTitle.getText().toString();
|
||||
String newIssueDescriptionForm = newIssueDescription.getText().toString();
|
||||
String newIssueAssigneesListForm = assigneesList.getText().toString();
|
||||
//String newIssueLabelsForm = newIssueLabels.getText().toString();
|
||||
String newIssueDueDateForm = newIssueDueDate.getText().toString();
|
||||
String newIssueLabelsIdHolderForm = labelsIdHolder.getText().toString();
|
||||
String newIssueTitleForm = Objects.requireNonNull(viewBinding.newIssueTitle.getText()).toString();
|
||||
String newIssueDescriptionForm = Objects.requireNonNull(viewBinding.newIssueDescription.getText()).toString();
|
||||
String newIssueDueDateForm = Objects.requireNonNull(viewBinding.newIssueDueDate.getText()).toString();
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (newIssueTitleForm.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty));
|
||||
Toasty.error(ctx, getString(R.string.issueTitleEmpty));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*if (newIssueDescriptionForm.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty));
|
||||
return;
|
||||
|
||||
}*/
|
||||
|
||||
if (newIssueDueDateForm.equals("")) {
|
||||
|
||||
newIssueDueDateForm = null;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
newIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(newIssueDueDateForm)));
|
||||
}
|
||||
|
||||
List<String> newIssueAssigneesListForm_ = new ArrayList<>(Arrays.asList(newIssueAssigneesListForm.split(",")));
|
||||
|
||||
for (int i = 0; i < newIssueAssigneesListForm_.size(); i++) {
|
||||
newIssueAssigneesListForm_.set(i, newIssueAssigneesListForm_.get(i).trim());
|
||||
}
|
||||
|
||||
int[] integers;
|
||||
if (!newIssueLabelsIdHolderForm.equals("")) {
|
||||
|
||||
String[] items = newIssueLabelsIdHolderForm.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
|
||||
integers = new int[items.length];
|
||||
for (int i = 0; i < integers.length; i++) {
|
||||
integers[i] = Integer.parseInt(items[i]);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
integers = new int[0];
|
||||
}
|
||||
|
||||
//Log.i("FormData", String.valueOf(newIssueLabelsForm));
|
||||
disableProcessButton();
|
||||
createNewIssueFunc(instanceUrl, instanceToken, repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, newIssueAssigneesListForm_, integers);
|
||||
|
||||
createNewIssueFunc(repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, milestoneId, newIssueTitleForm);
|
||||
}
|
||||
|
||||
public void loadCollaboratorsList() {
|
||||
private void createNewIssueFunc(String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
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<List<Collaborators>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Collaborators>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
String fullName = "";
|
||||
for (int i = 0; i < response.body().size(); i++) {
|
||||
if(!response.body().get(i).getFull_name().equals("")) {
|
||||
fullName = response.body().get(i).getFull_name();
|
||||
}
|
||||
defaultMentionAdapter.add(
|
||||
new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
Log.i("onResponse", String.valueOf(response.code()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
|
||||
Log.i("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void createNewIssueFunc(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm, List<String> newIssueAssigneesListForm, int[] newIssueLabelsForm) {
|
||||
|
||||
CreateIssue createNewIssueJson = new CreateIssue(loginUid, newIssueDescriptionForm, false, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, newIssueAssigneesListForm, newIssueLabelsForm);
|
||||
CreateIssue createNewIssueJson = new CreateIssue(loginUid, newIssueDescriptionForm, false, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, assigneesListData, labelsIds);
|
||||
|
||||
Call<JsonElement> call3;
|
||||
|
||||
call3 = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.createNewIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createNewIssueJson);
|
||||
.getApiInterface(ctx)
|
||||
.createNewIssue(Authorization.get(ctx), repoOwner, repoName, createNewIssueJson);
|
||||
|
||||
call3.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response2) {
|
||||
|
||||
if(response2.isSuccessful()) {
|
||||
if(response2.code() == 201) {
|
||||
if(response2.code() == 201) {
|
||||
|
||||
//Log.i("isSuccessful1", String.valueOf(response2.body()));
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
tinyDb.putBoolean("resumeIssues", true);
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.issueCreated));
|
||||
enableProcessButton();
|
||||
finish();
|
||||
|
||||
}
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
tinyDb.putBoolean("resumeIssues", true);
|
||||
|
||||
Toasty.success(ctx, getString(R.string.issueCreated));
|
||||
enableProcessButton();
|
||||
finish();
|
||||
}
|
||||
else if(response2.code() == 401) {
|
||||
|
||||
@@ -302,21 +265,19 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.issueCreatedError));
|
||||
Toasty.error(ctx, getString(R.string.issueCreatedError));
|
||||
enableProcessButton();
|
||||
//Log.i("isSuccessful2", String.valueOf(response2.body()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
enableProcessButton();
|
||||
}
|
||||
});
|
||||
@@ -324,21 +285,16 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
|
||||
private void getMilestones(String repoOwner, String repoName, int resultLimit) {
|
||||
|
||||
String msState = "open";
|
||||
Call<List<Milestones>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState);
|
||||
.getApiInterface(ctx)
|
||||
.getMilestones(Authorization.get(ctx), repoOwner, repoName, 1, resultLimit, msState);
|
||||
|
||||
call.enqueue(new Callback<List<Milestones>>() {
|
||||
|
||||
@@ -346,13 +302,16 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull retrofit2.Response<List<Milestones>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Milestones> milestonesList_ = response.body();
|
||||
|
||||
milestonesList.add(new Milestones(0,getString(R.string.issueCreatedNoMilestone)));
|
||||
assert milestonesList_ != null;
|
||||
|
||||
if(milestonesList_.size() > 0) {
|
||||
|
||||
for (int i = 0; i < milestonesList_.size(); i++) {
|
||||
|
||||
//Don't translate "open" is a enum
|
||||
@@ -363,17 +322,20 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
);
|
||||
milestonesList.add(data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreateIssueActivity.this,
|
||||
R.layout.spinner_item, milestonesList);
|
||||
R.layout.list_spinner_items, milestonesList);
|
||||
|
||||
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
newIssueMilestoneSpinner.setAdapter(adapter);
|
||||
viewBinding.newIssueMilestoneSpinner.setAdapter(adapter);
|
||||
enableProcessButton();
|
||||
|
||||
viewBinding.newIssueMilestoneSpinner.setOnItemClickListener ((parent, view, position, id) ->
|
||||
|
||||
milestoneId = milestonesList.get(position).getId()
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,143 +343,8 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, String loginFullName) {
|
||||
|
||||
Call<List<Collaborators>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
listOfAssignees.add(new MultiSelectModel(-1, loginFullName));
|
||||
|
||||
call.enqueue(new Callback<List<Collaborators>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull retrofit2.Response<List<Collaborators>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Collaborators> assigneesList_ = response.body();
|
||||
|
||||
assert assigneesList_ != null;
|
||||
if(assigneesList_.size() > 0) {
|
||||
for (int i = 0; i < assigneesList_.size(); i++) {
|
||||
|
||||
/*String assigneesCopy;
|
||||
if(!assigneesList_.get(i).getFull_name().equals("")) {
|
||||
assigneesCopy = getString(R.string.dialogAssignessText, assigneesList_.get(i).getFull_name(), assigneesList_.get(i).getLogin());
|
||||
}
|
||||
else {
|
||||
assigneesCopy = assigneesList_.get(i).getLogin();
|
||||
}*/
|
||||
listOfAssignees.add(new MultiSelectModel(assigneesList_.get(i).getId(), assigneesList_.get(i).getLogin().trim()));
|
||||
|
||||
}
|
||||
assigneesFlag = true;
|
||||
}
|
||||
|
||||
multiSelectDialog = new MultiSelectDialog()
|
||||
.title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
|
||||
.titleSize(25)
|
||||
.positiveText(getResources().getString(R.string.okButton))
|
||||
.negativeText(getResources().getString(R.string.cancelButton))
|
||||
.setMinSelectionLimit(0)
|
||||
.setMaxSelectionLimit(listOfAssignees.size())
|
||||
.multiSelectList(listOfAssignees)
|
||||
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
|
||||
@Override
|
||||
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
|
||||
|
||||
assigneesList.setText(dataString);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
//Log.d("multiSelect","Dialog cancelled");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
|
||||
|
||||
Call<List<Labels>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Labels>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Labels> labelsList_ = response.body();
|
||||
|
||||
assert labelsList_ != null;
|
||||
if(labelsList_.size() > 0) {
|
||||
for (int i = 0; i < labelsList_.size(); i++) {
|
||||
|
||||
listOfLabels.add(new MultiSelectModel(labelsList_.get(i).getId(), labelsList_.get(i).getName().trim()));
|
||||
|
||||
}
|
||||
labelsFlag = true;
|
||||
}
|
||||
|
||||
multiSelectDialogLabels = new MultiSelectDialog()
|
||||
.title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
|
||||
.titleSize(25)
|
||||
.positiveText(getResources().getString(R.string.okButton))
|
||||
.negativeText(getResources().getString(R.string.cancelButton))
|
||||
.setMinSelectionLimit(0)
|
||||
.setMaxSelectionLimit(listOfLabels.size())
|
||||
.multiSelectList(listOfLabels)
|
||||
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
|
||||
@Override
|
||||
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
|
||||
|
||||
newIssueLabels.setText(dataString.trim());
|
||||
labelsIdHolder.setText(selectedIds.toString());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
//Log.d("multiSelect","Dialog cancelled");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -525,23 +352,8 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v == assigneesList) {
|
||||
if(assigneesFlag) {
|
||||
multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog");
|
||||
}
|
||||
else {
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.noAssigneesFound));
|
||||
}
|
||||
}
|
||||
else if (v == newIssueLabels) {
|
||||
if(labelsFlag) {
|
||||
multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels");
|
||||
}
|
||||
else {
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.noLabelsFound));
|
||||
}
|
||||
}
|
||||
else if (v == newIssueDueDate) {
|
||||
|
||||
if (v == viewBinding.newIssueDueDate) {
|
||||
|
||||
final Calendar c = Calendar.getInstance();
|
||||
int mYear = c.get(Calendar.YEAR);
|
||||
@@ -549,41 +361,22 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
|
||||
final int mDay = c.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
|
||||
new DatePickerDialog.OnDateSetListener() {
|
||||
|
||||
@Override
|
||||
public void onDateSet(DatePicker view, int year,
|
||||
int monthOfYear, int dayOfMonth) {
|
||||
|
||||
newIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth));
|
||||
|
||||
}
|
||||
}, mYear, mMonth, mDay);
|
||||
(view, year, monthOfYear, dayOfMonth) -> viewBinding.newIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay);
|
||||
datePickerDialog.show();
|
||||
}
|
||||
else if(v == createNewIssueButton) {
|
||||
else if(v == viewBinding.createNewIssueButton) {
|
||||
|
||||
processNewIssue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
createNewIssueButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createNewIssueButton.setBackground(shape);
|
||||
|
||||
viewBinding.createNewIssueButton.setEnabled(false);
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
createNewIssueButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
createNewIssueButton.setBackground(shape);
|
||||
|
||||
viewBinding.createNewIssueButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -16,19 +10,24 @@ import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.pes.androidmaterialcolorpickerdialog.ColorPicker;
|
||||
import com.pes.androidmaterialcolorpickerdialog.ColorPickerCallback;
|
||||
import org.gitnex.tea4j.models.CreateLabel;
|
||||
import org.gitnex.tea4j.models.Labels;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateLabelBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.CreateLabel;
|
||||
import org.mian.gitnex.models.Labels;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.viewmodels.LabelsViewModel;
|
||||
import org.mian.gitnex.viewmodels.OrganizationLabelsViewModel;
|
||||
import java.util.Objects;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -40,42 +39,37 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
private TextView colorPicker;
|
||||
private EditText labelName;
|
||||
private Button createLabelButton;
|
||||
final Context ctx = this;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_create_label;
|
||||
}
|
||||
private TinyDB tinyDB;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityCreateLabelBinding activityCreateLabelBinding = ActivityCreateLabelBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCreateLabelBinding.getRoot());
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
tinyDB = TinyDB.getInstance(appCtx);
|
||||
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");
|
||||
|
||||
if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("delete")) {
|
||||
|
||||
deleteLabel(instanceUrl, instanceToken, repoOwner, repoName, Integer.parseInt(Objects.requireNonNull(getIntent().getStringExtra("labelId"))), loginUid);
|
||||
deleteLabel(repoOwner, repoName, Integer.parseInt(Objects.requireNonNull(getIntent().getStringExtra("labelId"))));
|
||||
finish();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
colorPicker = findViewById(R.id.colorPicker);
|
||||
labelName = findViewById(R.id.labelName);
|
||||
createLabelButton = findViewById(R.id.createLabelButton);
|
||||
ImageView closeActivity = activityCreateLabelBinding.close;
|
||||
colorPicker = activityCreateLabelBinding.colorPicker;
|
||||
labelName = activityCreateLabelBinding.labelName;
|
||||
createLabelButton = activityCreateLabelBinding.createLabelButton;
|
||||
|
||||
labelName.requestFocus();
|
||||
assert imm != null;
|
||||
@@ -85,22 +79,14 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
colorPicker.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
cp.show();
|
||||
}
|
||||
});
|
||||
colorPicker.setOnClickListener(v -> cp.show());
|
||||
|
||||
cp.setCallback(new ColorPickerCallback() {
|
||||
@Override
|
||||
public void onColorChosen(@ColorInt int color) {
|
||||
cp.setCallback(color -> {
|
||||
|
||||
//Log.i("#Hex no alpha", String.format("#%06X", (0xFFFFFF & color)));
|
||||
colorPicker.setBackgroundColor(color);
|
||||
tinyDb.putString("labelColor", String.format("#%06X", (0xFFFFFF & color)));
|
||||
cp.dismiss();
|
||||
|
||||
}
|
||||
//Log.i("#Hex no alpha", String.format("#%06X", (0xFFFFFF & color)));
|
||||
colorPicker.setBackgroundColor(color);
|
||||
tinyDB.putString("labelColor", String.format("#%06X", (0xFFFFFF & color)));
|
||||
cp.dismiss();
|
||||
});
|
||||
|
||||
if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("edit")) {
|
||||
@@ -108,154 +94,133 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
labelName.setText(getIntent().getStringExtra("labelTitle"));
|
||||
int labelColor_ = Color.parseColor("#" + getIntent().getStringExtra("labelColor"));
|
||||
colorPicker.setBackgroundColor(labelColor_);
|
||||
tinyDb.putString("labelColorDefault", "#" + getIntent().getStringExtra("labelColor"));
|
||||
tinyDB.putString("labelColorDefault", "#" + getIntent().getStringExtra("labelColor"));
|
||||
|
||||
TextView toolbar_title = findViewById(R.id.toolbar_title);
|
||||
TextView toolbar_title = activityCreateLabelBinding.toolbarTitle;
|
||||
toolbar_title.setText(getResources().getString(R.string.pageTitleLabelUpdate));
|
||||
createLabelButton.setText(getResources().getString(R.string.newUpdateButtonCopy));
|
||||
|
||||
createLabelButton.setOnClickListener(updateLabelListener);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
createLabelButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createLabelButton.setBackground(shape);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
createLabelButton.setOnClickListener(createLabelListener);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private View.OnClickListener createLabelListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processCreateLabel();
|
||||
}
|
||||
};
|
||||
private final View.OnClickListener createLabelListener = v -> processCreateLabel();
|
||||
|
||||
private View.OnClickListener updateLabelListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processUpdateLabel();
|
||||
}
|
||||
};
|
||||
private final View.OnClickListener updateLabelListener = v -> processUpdateLabel();
|
||||
|
||||
private void processUpdateLabel() {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
AppUtil appUtil = new AppUtil();
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
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");
|
||||
|
||||
String updateLabelName = labelName.getText().toString();
|
||||
|
||||
String updateLabelColor;
|
||||
if(tinyDb.getString("labelColor").isEmpty()) {
|
||||
updateLabelColor = tinyDb.getString("labelColorDefault");
|
||||
if(tinyDB.getString("labelColor").isEmpty()) {
|
||||
|
||||
updateLabelColor = tinyDB.getString("labelColorDefault");
|
||||
}
|
||||
else {
|
||||
updateLabelColor = tinyDb.getString("labelColor");
|
||||
|
||||
updateLabelColor = tinyDB.getString("labelColor");
|
||||
}
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(updateLabelName.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError));
|
||||
Toasty.error(ctx, getString(R.string.labelEmptyError));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!appUtil.checkStrings(updateLabelName)) {
|
||||
if(!AppUtil.checkStrings(updateLabelName)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelNameError));
|
||||
Toasty.error(ctx, getString(R.string.labelNameError));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
disableProcessButton();
|
||||
patchLabel(instanceUrl, instanceToken, repoOwner, repoName, updateLabelName, updateLabelColor, Integer.valueOf(getIntent().getStringExtra("labelId")), loginUid);
|
||||
patchLabel(repoOwner, repoName, updateLabelName, updateLabelColor, Integer.parseInt(
|
||||
Objects.requireNonNull(getIntent().getStringExtra("labelId"))));
|
||||
|
||||
}
|
||||
|
||||
private void processCreateLabel() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
AppUtil appUtil = new AppUtil();
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
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");
|
||||
|
||||
String newLabelName = labelName.getText().toString();
|
||||
String newLabelColor;
|
||||
if(tinyDb.getString("labelColor").isEmpty()) {
|
||||
newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(getApplicationContext(), R.color.releasePre)));
|
||||
|
||||
if(tinyDB.getString("labelColor").isEmpty()) {
|
||||
|
||||
newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(ctx, R.color.releasePre)));
|
||||
}
|
||||
else {
|
||||
newLabelColor = tinyDb.getString("labelColor");
|
||||
|
||||
newLabelColor = tinyDB.getString("labelColor");
|
||||
}
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(newLabelName.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError));
|
||||
Toasty.error(ctx, getString(R.string.labelEmptyError));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!appUtil.checkStrings(newLabelName)) {
|
||||
if(!AppUtil.checkStrings(newLabelName)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelNameError));
|
||||
Toasty.error(ctx, getString(R.string.labelNameError));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
disableProcessButton();
|
||||
createNewLabel(instanceUrl, instanceToken, repoOwner, repoName, newLabelName, newLabelColor, loginUid);
|
||||
|
||||
createNewLabel(repoOwner, repoName, newLabelName, newLabelColor);
|
||||
}
|
||||
|
||||
private void createNewLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String newLabelName, String newLabelColor, String loginUid) {
|
||||
private void createNewLabel(String repoOwner, String repoName, String newLabelName, String newLabelColor) {
|
||||
|
||||
CreateLabel createLabelFunc = new CreateLabel(newLabelName, newLabelColor);
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
Call<CreateLabel> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.createLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createLabelFunc);
|
||||
if(getIntent().getStringExtra("type") != null && Objects.requireNonNull(getIntent().getStringExtra("type")).equals("org")) {
|
||||
|
||||
call = RetrofitClient.getApiInterface(ctx).createOrganizationLabel(Authorization.get(ctx), getIntent().getStringExtra("orgName"), createLabelFunc);
|
||||
}
|
||||
else {
|
||||
|
||||
call = RetrofitClient.getApiInterface(ctx).createLabel(Authorization.get(ctx), repoOwner, repoName, createLabelFunc);
|
||||
}
|
||||
|
||||
call.enqueue(new Callback<CreateLabel>() {
|
||||
|
||||
@@ -264,11 +229,10 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelCreated));
|
||||
tinyDb.putString("labelColor", "");
|
||||
tinyDb.putBoolean("labelsRefresh", true);
|
||||
Toasty.success(ctx, getString(R.string.labelCreated));
|
||||
tinyDB.putString("labelColor", "");
|
||||
tinyDB.putBoolean("labelsRefresh", true);
|
||||
finish();
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
@@ -277,21 +241,19 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
tinyDb.putString("labelColor", "");
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
|
||||
|
||||
tinyDB.putString("labelColor", "");
|
||||
Toasty.error(ctx, getString(R.string.labelGeneralError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<CreateLabel> call, @NonNull Throwable t) {
|
||||
tinyDb.putString("labelColor", "");
|
||||
|
||||
tinyDB.putString("labelColor", "");
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -299,17 +261,20 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
|
||||
}
|
||||
|
||||
private void patchLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId, String loginUid) {
|
||||
private void patchLabel(String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId) {
|
||||
|
||||
CreateLabel createLabelFunc = new CreateLabel(updateLabelName, updateLabelColor);
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
Call<CreateLabel> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.patchLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc);
|
||||
if(getIntent().getStringExtra("type") != null && Objects.requireNonNull(getIntent().getStringExtra("type")).equals("org")) {
|
||||
|
||||
call = RetrofitClient.getApiInterface(ctx).patchOrganizationLabel(Authorization.get(ctx), getIntent().getStringExtra("orgName"), labelId, createLabelFunc);
|
||||
}
|
||||
else {
|
||||
|
||||
call = RetrofitClient.getApiInterface(appCtx).patchLabel(Authorization.get(ctx), repoOwner, repoName, labelId, createLabelFunc);
|
||||
}
|
||||
|
||||
call.enqueue(new Callback<CreateLabel>() {
|
||||
|
||||
@@ -317,18 +282,19 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
public void onResponse(@NonNull Call<CreateLabel> call, @NonNull retrofit2.Response<CreateLabel> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelUpdated));
|
||||
tinyDb.putString("labelColor", "");
|
||||
tinyDb.putBoolean("labelsRefresh", true);
|
||||
tinyDb.putString("labelColorDefault", "");
|
||||
Toasty.success(ctx, getString(R.string.labelUpdated));
|
||||
tinyDB.putString("labelColor", "");
|
||||
tinyDB.putBoolean("labelsRefresh", true);
|
||||
tinyDB.putString("labelColorDefault", "");
|
||||
getIntent().removeExtra("labelAction");
|
||||
getIntent().removeExtra("labelId");
|
||||
getIntent().removeExtra("labelTitle");
|
||||
getIntent().removeExtra("labelColor");
|
||||
getIntent().removeExtra("type");
|
||||
finish();
|
||||
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
@@ -338,23 +304,21 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
tinyDb.putString("labelColor", "");
|
||||
tinyDb.putString("labelColorDefault", "");
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
|
||||
|
||||
tinyDB.putString("labelColor", "");
|
||||
tinyDB.putString("labelColorDefault", "");
|
||||
Toasty.error(ctx, getString(R.string.labelGeneralError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<CreateLabel> call, @NonNull Throwable t) {
|
||||
tinyDb.putString("labelColor", "");
|
||||
tinyDb.putString("labelColorDefault", "");
|
||||
|
||||
tinyDB.putString("labelColor", "");
|
||||
tinyDB.putString("labelColorDefault", "");
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -363,26 +327,30 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
getIntent().removeExtra("labelAction");
|
||||
getIntent().removeExtra("labelId");
|
||||
getIntent().removeExtra("labelTitle");
|
||||
getIntent().removeExtra("labelColor");
|
||||
finish();
|
||||
}
|
||||
|
||||
onClickListener = view -> {
|
||||
|
||||
getIntent().removeExtra("labelAction");
|
||||
getIntent().removeExtra("labelId");
|
||||
getIntent().removeExtra("labelTitle");
|
||||
getIntent().removeExtra("labelColor");
|
||||
getIntent().removeExtra("type");
|
||||
finish();
|
||||
};
|
||||
}
|
||||
|
||||
private void deleteLabel(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, int labelId, String loginUid) {
|
||||
private void deleteLabel(final String repoOwner, final String repoName, int labelId) {
|
||||
|
||||
Call<Labels> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.deleteLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId);
|
||||
if(getIntent().getStringExtra("type") != null && Objects.requireNonNull(getIntent().getStringExtra("type")).equals("org")) {
|
||||
|
||||
call = RetrofitClient.getApiInterface(appCtx).deleteOrganizationLabel(Authorization.get(ctx), getIntent().getStringExtra("orgName"), labelId);
|
||||
}
|
||||
else {
|
||||
|
||||
call = RetrofitClient.getApiInterface(appCtx).deleteLabel(Authorization.get(ctx), repoOwner, repoName, labelId);
|
||||
}
|
||||
|
||||
call.enqueue(new Callback<Labels>() {
|
||||
|
||||
@@ -390,13 +358,21 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
public void onResponse(@NonNull Call<Labels> call, @NonNull retrofit2.Response<Labels> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
if(response.code() == 204) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelDeleteText));
|
||||
LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, getApplicationContext());
|
||||
Toasty.success(ctx, getString(R.string.labelDeleteText));
|
||||
if(getIntent().getStringExtra("type") != null && Objects.requireNonNull(getIntent().getStringExtra("type")).equals("org")) {
|
||||
|
||||
OrganizationLabelsViewModel.loadOrgLabelsList(Authorization.get(ctx), getIntent().getStringExtra("orgName"), ctx, null, null);
|
||||
}
|
||||
else {
|
||||
|
||||
LabelsViewModel.loadLabelsList(Authorization.get(ctx), repoOwner, repoName, ctx);
|
||||
}
|
||||
getIntent().removeExtra("labelAction");
|
||||
getIntent().removeExtra("labelId");
|
||||
|
||||
getIntent().removeExtra("type");
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
@@ -405,14 +381,11 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelDeleteErrorText));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.labelDeleteErrorText));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -426,21 +399,11 @@ public class CreateLabelActivity extends BaseActivity {
|
||||
private void disableProcessButton() {
|
||||
|
||||
createLabelButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createLabelButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
createLabelButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
createLabelButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.DatePicker;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.Milestones;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateMilestoneBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.VersionCheck;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Milestones;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.Calendar;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -36,31 +37,41 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
|
||||
private EditText milestoneTitle;
|
||||
private EditText milestoneDescription;
|
||||
private Button createNewMilestoneButton;
|
||||
final Context ctx = this;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_new_milestone;
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
ActivityCreateMilestoneBinding activityCreateMilestoneBinding = ActivityCreateMilestoneBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCreateMilestoneBinding.getRoot());
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
milestoneDueDate = findViewById(R.id.milestoneDueDate);
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
createNewMilestoneButton = findViewById(R.id.createNewMilestoneButton);
|
||||
milestoneTitle = findViewById(R.id.milestoneTitle);
|
||||
milestoneDescription = findViewById(R.id.milestoneDescription);
|
||||
milestoneDueDate = activityCreateMilestoneBinding.milestoneDueDate;
|
||||
ImageView closeActivity = activityCreateMilestoneBinding.close;
|
||||
createNewMilestoneButton = activityCreateMilestoneBinding.createNewMilestoneButton;
|
||||
milestoneTitle = activityCreateMilestoneBinding.milestoneTitle;
|
||||
milestoneDescription = activityCreateMilestoneBinding.milestoneDescription;
|
||||
|
||||
milestoneTitle.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(milestoneTitle, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
milestoneDescription.setOnTouchListener((touchView, motionEvent) -> {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
milestoneDueDate.setOnClickListener(this);
|
||||
@@ -68,38 +79,25 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
|
||||
if(!connToInternet) {
|
||||
|
||||
createNewMilestoneButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createNewMilestoneButton.setBackground(shape);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
createNewMilestoneButton.setOnClickListener(createMilestoneListener);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private View.OnClickListener createMilestoneListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processNewMilestone();
|
||||
}
|
||||
};
|
||||
private final View.OnClickListener createMilestoneListener = v -> processNewMilestone();
|
||||
|
||||
private void processNewMilestone() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
AppUtil appUtil = new AppUtil();
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
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");
|
||||
//String appLocale = tinyDb.getString("locale");
|
||||
|
||||
String newMilestoneTitle = milestoneTitle.getText().toString();
|
||||
String newMilestoneDescription = milestoneDescription.getText().toString();
|
||||
@@ -107,50 +105,50 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(newMilestoneTitle.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.milestoneNameErrorEmpty));
|
||||
Toasty.error(ctx, getString(R.string.milestoneNameErrorEmpty));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!newMilestoneDescription.equals("")) {
|
||||
if (appUtil.charactersLength(newMilestoneDescription) > 255) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.milestoneDescError));
|
||||
if (newMilestoneDescription.length() > 255) {
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.milestoneDescError));
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
String finalMilestoneDueDate = null;
|
||||
|
||||
if(!newMilestoneDueDate.isEmpty()) {
|
||||
|
||||
finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate)));
|
||||
} else if (VersionCheck.compareVersion("1.10.0", tinyDb.getString("giteaVersion")) > 1) {
|
||||
}
|
||||
else if (new Version(tinyDb.getString("giteaVersion")).less("1.10.0")) {
|
||||
|
||||
// if Gitea version is less than 1.10.0 DueDate is required
|
||||
Toasty.info(getApplicationContext(), getString(R.string.milestoneDateEmpty));
|
||||
Toasty.warning(ctx, getString(R.string.milestoneDateEmpty));
|
||||
return;
|
||||
}
|
||||
|
||||
disableProcessButton();
|
||||
createNewMilestone(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate);
|
||||
|
||||
createNewMilestone(Authorization.get(ctx), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate);
|
||||
}
|
||||
|
||||
private void createNewMilestone(final String instanceUrl, final String token, String repoOwner, String repoName, String newMilestoneTitle, String newMilestoneDescription, String newMilestoneDueDate) {
|
||||
private void createNewMilestone(final String token, String repoOwner, String repoName, String newMilestoneTitle, String newMilestoneDescription, String newMilestoneDueDate) {
|
||||
|
||||
Milestones createMilestone = new Milestones(newMilestoneDescription, newMilestoneTitle, newMilestoneDueDate);
|
||||
|
||||
Call<Milestones> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getApiInterface(appCtx)
|
||||
.createMilestone(token, repoOwner, repoName, createMilestone);
|
||||
|
||||
call.enqueue(new Callback<Milestones>() {
|
||||
@@ -159,14 +157,14 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
|
||||
public void onResponse(@NonNull Call<Milestones> call, @NonNull retrofit2.Response<Milestones> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
tinyDb.putBoolean("milestoneCreated", true);
|
||||
Toasty.info(getApplicationContext(), getString(R.string.milestoneCreated));
|
||||
Toasty.success(ctx, getString(R.string.milestoneCreated));
|
||||
enableProcessButton();
|
||||
finish();
|
||||
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
@@ -176,19 +174,17 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.milestoneCreatedError));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.milestoneCreatedError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Milestones> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -207,48 +203,25 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
|
||||
final int mDay = c.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
|
||||
new DatePickerDialog.OnDateSetListener() {
|
||||
|
||||
@Override
|
||||
public void onDateSet(DatePicker view, int year,
|
||||
int monthOfYear, int dayOfMonth) {
|
||||
|
||||
milestoneDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth));
|
||||
|
||||
}
|
||||
}, mYear, mMonth, mDay);
|
||||
(view, year, monthOfYear, dayOfMonth) -> milestoneDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay);
|
||||
datePickerDialog.show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
createNewMilestoneButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createNewMilestoneButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
createNewMilestoneButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
createNewMilestoneButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
@@ -13,14 +9,17 @@ import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateNewUserBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.UserInfo;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -34,28 +33,25 @@ public class CreateNewUserActivity extends BaseActivity {
|
||||
private EditText userEmail;
|
||||
private EditText userPassword;
|
||||
private Button createUserButton;
|
||||
final Context ctx = this;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_create_new_user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
ActivityCreateNewUserBinding activityCreateNewUserBinding = ActivityCreateNewUserBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCreateNewUserBinding.getRoot());
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
createUserButton = findViewById(R.id.createUserButton);
|
||||
fullName = findViewById(R.id.fullName);
|
||||
userUserName = findViewById(R.id.userUserName);
|
||||
userEmail = findViewById(R.id.userEmail);
|
||||
userPassword = findViewById(R.id.userPassword);
|
||||
ImageView closeActivity = activityCreateNewUserBinding.close;
|
||||
createUserButton = activityCreateNewUserBinding.createUserButton;
|
||||
fullName = activityCreateNewUserBinding.fullName;
|
||||
userUserName = activityCreateNewUserBinding.userUserName;
|
||||
userEmail = activityCreateNewUserBinding.userEmail;
|
||||
userPassword = activityCreateNewUserBinding.userPassword;
|
||||
|
||||
fullName.requestFocus();
|
||||
assert imm != null;
|
||||
@@ -67,23 +63,16 @@ public class CreateNewUserActivity extends BaseActivity {
|
||||
if(!connToInternet) {
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
createUserButton.setOnClickListener(createNewUserListener);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void processCreateNewUser() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
AppUtil appUtil = new AppUtil();
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
String newFullName = fullName.getText().toString().trim();
|
||||
String newUserName = userUserName.getText().toString().trim();
|
||||
@@ -92,53 +81,46 @@ public class CreateNewUserActivity extends BaseActivity {
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.emptyFields));
|
||||
Toasty.error(ctx, getString(R.string.emptyFields));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!appUtil.checkStrings(newFullName)) {
|
||||
if(!AppUtil.checkStrings(newFullName)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.userInvalidFullName));
|
||||
Toasty.error(ctx, getString(R.string.userInvalidFullName));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) {
|
||||
if(!AppUtil.checkStringsWithAlphaNumeric(newUserName)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.userInvalidUserName));
|
||||
Toasty.error(ctx, getString(R.string.userInvalidUserName));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.userInvalidEmail));
|
||||
Toasty.error(ctx, getString(R.string.userInvalidEmail));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
disableProcessButton();
|
||||
createNewUser(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newFullName, newUserName, newUserEmail, newUserPassword);
|
||||
|
||||
createNewUser(Authorization.get(ctx), newFullName, newUserName, newUserEmail, newUserPassword);
|
||||
}
|
||||
|
||||
private void createNewUser(final String instanceUrl, final String instanceToken, String newFullName, String newUserName, String newUserEmail, String newUserPassword) {
|
||||
private void createNewUser(final String instanceToken, String newFullName, String newUserName, String newUserEmail, String newUserPassword) {
|
||||
|
||||
UserInfo createUser = new UserInfo(newUserEmail, newFullName, newUserName, newUserPassword, newUserName, 0, true);
|
||||
|
||||
Call<UserInfo> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getApiInterface(appCtx)
|
||||
.createNewUser(instanceToken, createUser);
|
||||
|
||||
call.enqueue(new Callback<UserInfo>() {
|
||||
@@ -148,10 +130,9 @@ public class CreateNewUserActivity extends BaseActivity {
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.userCreatedText));
|
||||
Toasty.success(ctx, getString(R.string.userCreatedText));
|
||||
enableProcessButton();
|
||||
finish();
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
@@ -160,37 +141,32 @@ public class CreateNewUserActivity extends BaseActivity {
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
|
||||
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
}
|
||||
else if(response.code() == 422) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.userExistsError));
|
||||
|
||||
Toasty.warning(ctx, ctx.getString(R.string.userExistsError));
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.genericError));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -198,39 +174,21 @@ public class CreateNewUserActivity extends BaseActivity {
|
||||
|
||||
}
|
||||
|
||||
private View.OnClickListener createNewUserListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processCreateNewUser();
|
||||
}
|
||||
};
|
||||
private final View.OnClickListener createNewUserListener = v -> processCreateNewUser();
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
createUserButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createUserButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
createUserButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
createUserButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.UserOrganizations;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateOrganizationBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.UserOrganizations;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@@ -33,119 +35,106 @@ public class CreateOrganizationActivity extends BaseActivity {
|
||||
|
||||
private EditText orgName;
|
||||
private EditText orgDesc;
|
||||
final Context ctx = this;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_new_organization;
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
ActivityCreateOrganizationBinding activityCreateOrganizationBinding = ActivityCreateOrganizationBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCreateOrganizationBinding.getRoot());
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
closeActivity = findViewById(R.id.close);
|
||||
orgName = findViewById(R.id.newOrganizationName);
|
||||
orgDesc = findViewById(R.id.newOrganizationDescription);
|
||||
closeActivity = activityCreateOrganizationBinding.close;
|
||||
orgName = activityCreateOrganizationBinding.newOrganizationName;
|
||||
orgDesc = activityCreateOrganizationBinding.newOrganizationDescription;
|
||||
|
||||
orgName.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(orgName, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
orgDesc.setOnTouchListener((touchView, motionEvent) -> {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
createOrganizationButton = findViewById(R.id.createNewOrganizationButton);
|
||||
createOrganizationButton = activityCreateOrganizationBinding.createNewOrganizationButton;
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
createOrganizationButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createOrganizationButton.setBackground(shape);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
createOrganizationButton.setOnClickListener(createOrgListener);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private View.OnClickListener createOrgListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processNewOrganization();
|
||||
}
|
||||
};
|
||||
private final View.OnClickListener createOrgListener = v -> processNewOrganization();
|
||||
|
||||
private void processNewOrganization() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
AppUtil appUtil = new AppUtil();
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
String newOrgName = orgName.getText().toString();
|
||||
String newOrgDesc = orgDesc.getText().toString();
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!newOrgDesc.equals("")) {
|
||||
if (appUtil.charactersLength(newOrgDesc) > 255) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.orgDescError));
|
||||
if (newOrgDesc.length() > 255) {
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.orgDescError));
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(newOrgName.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.orgNameErrorEmpty));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.orgNameErrorEmpty));
|
||||
}
|
||||
else if(!appUtil.checkStrings(newOrgName)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.orgNameErrorInvalid));
|
||||
else if(!AppUtil.checkStrings(newOrgName)) {
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.orgNameErrorInvalid));
|
||||
}
|
||||
else {
|
||||
|
||||
disableProcessButton();
|
||||
createNewOrganization(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newOrgName, newOrgDesc);
|
||||
|
||||
createNewOrganization(Authorization.get(ctx), newOrgName, newOrgDesc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createNewOrganization(final String instanceUrl, final String token, String orgName, String orgDesc) {
|
||||
private void createNewOrganization(final String token, String orgName, String orgDesc) {
|
||||
|
||||
UserOrganizations createOrganization = new UserOrganizations(orgName, null, orgDesc, null, null);
|
||||
|
||||
Call<UserOrganizations> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getApiInterface(appCtx)
|
||||
.createNewOrganization(token, createOrganization);
|
||||
|
||||
call.enqueue(new Callback<UserOrganizations>() {
|
||||
@@ -155,12 +144,11 @@ public class CreateOrganizationActivity extends BaseActivity {
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
tinyDb.putBoolean("orgCreated", true);
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.orgCreated));
|
||||
Toasty.success(ctx, getString(R.string.orgCreated));
|
||||
finish();
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
@@ -169,37 +157,35 @@ public class CreateOrganizationActivity extends BaseActivity {
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else if(response.code() == 409) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.orgExistsError));
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.orgExistsError));
|
||||
}
|
||||
else if(response.code() == 422) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.orgExistsError));
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.orgExistsError));
|
||||
}
|
||||
else {
|
||||
|
||||
if(response.code() == 404) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
|
||||
Toasty.warning(ctx, getString(R.string.apiNotFound));
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.orgCreatedError));
|
||||
Toasty.error(ctx, getString(R.string.orgCreatedError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<UserOrganizations> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -210,21 +196,11 @@ public class CreateOrganizationActivity extends BaseActivity {
|
||||
private void disableProcessButton() {
|
||||
|
||||
createOrganizationButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createOrganizationButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
createOrganizationButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
createOrganizationButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.app.Dialog;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.Branches;
|
||||
import org.gitnex.tea4j.models.CreatePullRequest;
|
||||
import org.gitnex.tea4j.models.Labels;
|
||||
import org.gitnex.tea4j.models.Milestones;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.LabelsActions;
|
||||
import org.mian.gitnex.adapters.LabelsListAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreatePrBinding;
|
||||
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class CreatePullRequestActivity extends BaseActivity implements LabelsListAdapter.LabelsListAdapterListener {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private ActivityCreatePrBinding viewBinding;
|
||||
private CustomLabelsSelectionDialogBinding labelsBinding;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private Dialog dialogLabels;
|
||||
private String labelsSetter;
|
||||
private List<Integer> labelsIds = new ArrayList<>();
|
||||
private List<String> assignees = new ArrayList<>();
|
||||
private int milestoneId;
|
||||
|
||||
private String loginUid;
|
||||
private String instanceToken;
|
||||
private String repoOwner;
|
||||
private String repoName;
|
||||
|
||||
private LabelsListAdapter labelsAdapter;
|
||||
|
||||
List<Milestones> milestonesList = new ArrayList<>();
|
||||
List<Branches> branchesList = new ArrayList<>();
|
||||
List<Labels> labelsList = new ArrayList<>();
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
viewBinding = ActivityCreatePrBinding.inflate(getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
|
||||
loginUid = tinyDB.getString("loginUid");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
repoOwner = parts[0];
|
||||
repoName = parts[1];
|
||||
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
|
||||
// require gitea 1.12 or higher
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
viewBinding.prBody.setOnTouchListener((touchView, motionEvent) -> {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
labelsAdapter = new LabelsListAdapter(labelsList, CreatePullRequestActivity.this, labelsIds);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
viewBinding.prDueDate.setOnClickListener(dueDate ->
|
||||
setDueDate()
|
||||
);
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
getMilestones(repoOwner, repoName, resultLimit);
|
||||
getBranches(repoOwner, repoName);
|
||||
|
||||
viewBinding.prLabels.setOnClickListener(prLabels -> showLabels());
|
||||
|
||||
viewBinding.createPr.setOnClickListener(createPr -> processPullRequest());
|
||||
}
|
||||
|
||||
private void processPullRequest() {
|
||||
|
||||
String prTitle = String.valueOf(viewBinding.prTitle.getText());
|
||||
String prDescription = String.valueOf(viewBinding.prBody.getText());
|
||||
String mergeInto = viewBinding.mergeIntoBranchSpinner.getText().toString();
|
||||
String pullFrom = viewBinding.pullFromBranchSpinner.getText().toString();
|
||||
String dueDate = String.valueOf(viewBinding.prDueDate.getText());
|
||||
|
||||
assignees.add("");
|
||||
|
||||
if (labelsIds.size() == 0) {
|
||||
|
||||
labelsIds.add(0);
|
||||
}
|
||||
|
||||
if (dueDate.matches("")) {
|
||||
|
||||
dueDate = null;
|
||||
}
|
||||
else {
|
||||
|
||||
dueDate = AppUtil.customDateCombine(AppUtil.customDateFormat(dueDate));
|
||||
}
|
||||
|
||||
if(prTitle.matches("")) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.titleError));
|
||||
}
|
||||
else if(mergeInto.matches("")) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.mergeIntoError));
|
||||
}
|
||||
else if(pullFrom.matches("")) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.pullFromError));
|
||||
}
|
||||
else if(pullFrom.equals(mergeInto)) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.sameBranchesError));
|
||||
}
|
||||
else {
|
||||
|
||||
createPullRequest(prTitle, prDescription, mergeInto, pullFrom, milestoneId, dueDate, assignees);
|
||||
}
|
||||
}
|
||||
|
||||
private void createPullRequest(String prTitle, String prDescription, String mergeInto, String pullFrom, int milestoneId, String dueDate, List<String> assignees) {
|
||||
|
||||
CreatePullRequest createPullRequest = new CreatePullRequest(prTitle, prDescription, loginUid, mergeInto, pullFrom, milestoneId, dueDate, assignees, labelsIds);
|
||||
|
||||
Call<Void> transferCall = RetrofitClient
|
||||
.getApiInterface(appCtx)
|
||||
.createPullRequest(instanceToken, repoOwner, repoName, createPullRequest);
|
||||
|
||||
transferCall.enqueue(new Callback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
if (response.code() == 201) {
|
||||
|
||||
Toasty.success(ctx, getString(R.string.prCreateSuccess));
|
||||
finish();
|
||||
}
|
||||
else if (response.code() == 409 && response.message().equals("Conflict")) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.error(ctx, getString(R.string.prAlreadyExists));
|
||||
}
|
||||
else if (response.code() == 404) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.error(ctx, getString(R.string.apiNotFound));
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void labelsInterface(List<String> data) {
|
||||
|
||||
labelsSetter = String.valueOf(data);
|
||||
viewBinding.prLabels.setText(labelsSetter.replace("]", "").replace("[", ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void labelsIdsInterface(List<Integer> data) {
|
||||
|
||||
labelsIds = data;
|
||||
}
|
||||
|
||||
private void showLabels() {
|
||||
|
||||
dialogLabels = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
|
||||
|
||||
if (dialogLabels.getWindow() != null) {
|
||||
|
||||
dialogLabels.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
labelsBinding = CustomLabelsSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
|
||||
|
||||
View view = labelsBinding.getRoot();
|
||||
dialogLabels.setContentView(view);
|
||||
|
||||
labelsBinding.cancel.setOnClickListener(editProperties -> dialogLabels.dismiss());
|
||||
|
||||
dialogLabels.show();
|
||||
LabelsActions.getRepositoryLabels(ctx, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding);
|
||||
}
|
||||
|
||||
private void getBranches(String repoOwner, String repoName) {
|
||||
|
||||
Call<List<Branches>> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getBranches(Authorization.get(ctx), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Branches>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Branches>> call, @NonNull retrofit2.Response<List<Branches>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Branches> branchesList_ = response.body();
|
||||
assert branchesList_ != null;
|
||||
|
||||
if(branchesList_.size() > 0) {
|
||||
|
||||
for (int i = 0; i < branchesList_.size(); i++) {
|
||||
|
||||
Branches data = new Branches(branchesList_.get(i).getName());
|
||||
branchesList.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreatePullRequestActivity.this,
|
||||
R.layout.list_spinner_items, branchesList);
|
||||
|
||||
viewBinding.mergeIntoBranchSpinner.setAdapter(adapter);
|
||||
viewBinding.pullFromBranchSpinner.setAdapter(adapter);
|
||||
enableProcessButton();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void getMilestones(String repoOwner, String repoName, int resultLimit) {
|
||||
|
||||
String msState = "open";
|
||||
Call<List<Milestones>> call = RetrofitClient
|
||||
.getApiInterface(appCtx)
|
||||
.getMilestones(Authorization.get(ctx), repoOwner, repoName, 1, resultLimit, msState);
|
||||
|
||||
call.enqueue(new Callback<List<Milestones>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull retrofit2.Response<List<Milestones>> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Milestones> milestonesList_ = response.body();
|
||||
|
||||
milestonesList.add(new Milestones(0,getString(R.string.issueCreatedNoMilestone)));
|
||||
assert milestonesList_ != null;
|
||||
|
||||
if(milestonesList_.size() > 0) {
|
||||
|
||||
for (int i = 0; i < milestonesList_.size(); i++) {
|
||||
|
||||
//Don't translate "open" is a enum
|
||||
if(milestonesList_.get(i).getState().equals("open")) {
|
||||
Milestones data = new Milestones(
|
||||
milestonesList_.get(i).getId(),
|
||||
milestonesList_.get(i).getTitle()
|
||||
);
|
||||
milestonesList.add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreatePullRequestActivity.this,
|
||||
R.layout.list_spinner_items, milestonesList);
|
||||
|
||||
viewBinding.milestonesSpinner.setAdapter(adapter);
|
||||
enableProcessButton();
|
||||
|
||||
viewBinding.milestonesSpinner.setOnItemClickListener ((parent, view, position, id) ->
|
||||
|
||||
milestoneId = milestonesList.get(position).getId()
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void setDueDate() {
|
||||
|
||||
final Calendar c = Calendar.getInstance();
|
||||
int mYear = c.get(Calendar.YEAR);
|
||||
final int mMonth = c.get(Calendar.MONTH);
|
||||
final int mDay = c.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
|
||||
(view, year, monthOfYear, dayOfMonth) -> viewBinding.prDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay);
|
||||
datePickerDialog.show();
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
viewBinding.createPr.setEnabled(false);
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
viewBinding.createPr.setEnabled(true);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,32 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.Branches;
|
||||
import org.gitnex.tea4j.models.Releases;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateReleaseBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Branches;
|
||||
import org.mian.gitnex.models.Releases;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -38,144 +37,128 @@ public class CreateReleaseActivity extends BaseActivity {
|
||||
private View.OnClickListener onClickListener;
|
||||
public ImageView closeActivity;
|
||||
private EditText releaseTagName;
|
||||
private Spinner releaseBranch;
|
||||
private AutoCompleteTextView releaseBranch;
|
||||
private EditText releaseTitle;
|
||||
private EditText releaseContent;
|
||||
private CheckBox releaseType;
|
||||
private CheckBox releaseDraft;
|
||||
private Button createNewRelease;
|
||||
final Context ctx = this;
|
||||
private String selectedBranch;
|
||||
|
||||
private String repoOwner;
|
||||
private String repoName;
|
||||
|
||||
List<Branches> branchesList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_create_release;
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
ActivityCreateReleaseBinding activityCreateReleaseBinding = ActivityCreateReleaseBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCreateReleaseBinding.getRoot());
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
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 repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
repoOwner = parts[0];
|
||||
repoName = parts[1];
|
||||
|
||||
closeActivity = findViewById(R.id.close);
|
||||
releaseTagName = findViewById(R.id.releaseTagName);
|
||||
releaseTitle = findViewById(R.id.releaseTitle);
|
||||
releaseContent = findViewById(R.id.releaseContent);
|
||||
releaseType = findViewById(R.id.releaseType);
|
||||
releaseDraft = findViewById(R.id.releaseDraft);
|
||||
closeActivity = activityCreateReleaseBinding.close;
|
||||
releaseTagName = activityCreateReleaseBinding.releaseTagName;
|
||||
releaseTitle = activityCreateReleaseBinding.releaseTitle;
|
||||
releaseContent = activityCreateReleaseBinding.releaseContent;
|
||||
releaseType = activityCreateReleaseBinding.releaseType;
|
||||
releaseDraft = activityCreateReleaseBinding.releaseDraft;
|
||||
|
||||
releaseTagName.requestFocus();
|
||||
releaseTitle.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(releaseTagName, InputMethodManager.SHOW_IMPLICIT);
|
||||
imm.showSoftInput(releaseTitle, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
releaseContent.setOnTouchListener((touchView, motionEvent) -> {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
releaseBranch = findViewById(R.id.releaseBranch);
|
||||
releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
|
||||
getBranches(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
Branches branch = (Branches) parent.getSelectedItem();
|
||||
}
|
||||
releaseBranch = activityCreateReleaseBinding.releaseBranch;
|
||||
getBranches(Authorization.get(ctx), repoOwner, repoName);
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
createNewRelease = findViewById(R.id.createNewRelease);
|
||||
createNewRelease = activityCreateReleaseBinding.createNewRelease;
|
||||
disableProcessButton();
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
createNewRelease.setOnClickListener(createReleaseListener);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private View.OnClickListener createReleaseListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processNewRelease();
|
||||
}
|
||||
};
|
||||
private final View.OnClickListener createReleaseListener = v -> processNewRelease();
|
||||
|
||||
private void processNewRelease() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
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];
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
String newReleaseTagName = releaseTagName.getText().toString();
|
||||
String newReleaseTitle = releaseTitle.getText().toString();
|
||||
String newReleaseContent = releaseContent.getText().toString();
|
||||
String newReleaseBranch = releaseBranch.getSelectedItem().toString();
|
||||
String checkBranch = selectedBranch;
|
||||
boolean newReleaseType = releaseType.isChecked();
|
||||
boolean newReleaseDraft = releaseDraft.isChecked();
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(newReleaseTitle.equals("")) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.titleErrorEmpty));
|
||||
return;
|
||||
}
|
||||
|
||||
if(newReleaseTagName.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.tagNameErrorEmpty));
|
||||
Toasty.error(ctx, getString(R.string.tagNameErrorEmpty));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(newReleaseTitle.equals("")) {
|
||||
if(checkBranch == null) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.titleErrorEmpty));
|
||||
return;
|
||||
|
||||
}
|
||||
Toasty.error(ctx, getString(R.string.selectBranchError));
|
||||
return;
|
||||
}
|
||||
|
||||
disableProcessButton();
|
||||
createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, newReleaseBranch, newReleaseType, newReleaseDraft);
|
||||
|
||||
createNewReleaseFunc(Authorization.get(ctx), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, selectedBranch, newReleaseType, newReleaseDraft);
|
||||
}
|
||||
|
||||
private void createNewReleaseFunc(final String instanceUrl, final String token, String repoOwner, String repoName, String newReleaseTagName, String newReleaseTitle, String newReleaseContent, String newReleaseBranch, boolean newReleaseType, boolean newReleaseDraft) {
|
||||
private void createNewReleaseFunc(final String token, String repoOwner, String repoName, String newReleaseTagName, String newReleaseTitle, String newReleaseContent, String selectedBranch, boolean newReleaseType, boolean newReleaseDraft) {
|
||||
|
||||
Releases createReleaseJson = new Releases(newReleaseContent, newReleaseDraft, newReleaseTitle, newReleaseType, newReleaseTagName, newReleaseBranch);
|
||||
Releases createReleaseJson = new Releases(newReleaseContent, newReleaseDraft, newReleaseTitle, newReleaseType, newReleaseTagName, selectedBranch);
|
||||
|
||||
Call<Releases> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getApiInterface(ctx)
|
||||
.createNewRelease(token, repoOwner, repoName, createReleaseJson);
|
||||
|
||||
call.enqueue(new Callback<Releases>() {
|
||||
@@ -185,12 +168,10 @@ public class CreateReleaseActivity extends BaseActivity {
|
||||
|
||||
if (response.code() == 201) {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
tinyDb.putBoolean("updateReleases", true);
|
||||
Toasty.info(getApplicationContext(), getString(R.string.releaseCreatedText));
|
||||
tinyDB.putBoolean("updateReleases", true);
|
||||
Toasty.success(ctx, getString(R.string.releaseCreatedText));
|
||||
enableProcessButton();
|
||||
finish();
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
@@ -199,31 +180,27 @@ public class CreateReleaseActivity extends BaseActivity {
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
|
||||
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.genericError));
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Releases> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -231,11 +208,10 @@ public class CreateReleaseActivity extends BaseActivity {
|
||||
|
||||
}
|
||||
|
||||
private void getBranches(String instanceUrl, String instanceToken, final String repoOwner, final String repoName) {
|
||||
private void getBranches(String instanceToken, final String repoOwner, final String repoName) {
|
||||
|
||||
Call<List<Branches>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getApiInterface(ctx)
|
||||
.getBranches(instanceToken, repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Branches>>() {
|
||||
@@ -244,29 +220,27 @@ public class CreateReleaseActivity extends BaseActivity {
|
||||
public void onResponse(@NonNull Call<List<Branches>> call, @NonNull retrofit2.Response<List<Branches>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
List<Branches> branchesList_ = response.body();
|
||||
|
||||
assert branchesList_ != null;
|
||||
if(branchesList_.size() > 0) {
|
||||
for (int i = 0; i < branchesList_.size(); i++) {
|
||||
|
||||
Branches data = new Branches(
|
||||
branchesList_.get(i).getName()
|
||||
);
|
||||
branchesList.add(data);
|
||||
|
||||
}
|
||||
branchesList.addAll(branchesList_);
|
||||
}
|
||||
|
||||
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateReleaseActivity.this,
|
||||
R.layout.spinner_item, branchesList);
|
||||
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateReleaseActivity.this,
|
||||
R.layout.list_spinner_items, branchesList);
|
||||
|
||||
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
releaseBranch.setAdapter(adapter);
|
||||
enableProcessButton();
|
||||
|
||||
releaseBranch.setOnItemClickListener ((parent, view, position, id) ->
|
||||
|
||||
selectedBranch = branchesList.get(position).getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
@@ -275,13 +249,13 @@ public class CreateReleaseActivity extends BaseActivity {
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
@@ -289,32 +263,18 @@ public class CreateReleaseActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
createNewRelease.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createNewRelease.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
createNewRelease.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
createNewRelease.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.gitnex.tea4j.models.OrgOwner;
|
||||
import org.gitnex.tea4j.models.OrganizationRepository;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateRepoBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.OrgOwner;
|
||||
import org.mian.gitnex.models.OrganizationRepository;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -39,42 +39,42 @@ public class CreateRepoActivity extends BaseActivity {
|
||||
|
||||
public ImageView closeActivity;
|
||||
private View.OnClickListener onClickListener;
|
||||
private Spinner spinner;
|
||||
private AutoCompleteTextView spinner;
|
||||
private Button createRepo;
|
||||
private EditText repoName;
|
||||
private EditText repoDesc;
|
||||
private CheckBox repoAccess;
|
||||
final Context ctx = this;
|
||||
|
||||
List<OrgOwner> organizationsList = new ArrayList<>();
|
||||
private String loginUid;
|
||||
private String userLogin;
|
||||
|
||||
private String selectedOwner;
|
||||
|
||||
List<OrgOwner> organizationsList = new ArrayList<>();
|
||||
|
||||
//https://github.com/go-gitea/gitea/blob/52cfd2743c0e85b36081cf80a850e6a5901f1865/models/repo.go#L964-L967
|
||||
final List<String> reservedRepoNames = Arrays.asList(".", "..");
|
||||
final Pattern reservedRepoPatterns = Pattern.compile("\\.(git|wiki)$");
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_new_repo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
ActivityCreateRepoBinding activityCreateRepoBinding = ActivityCreateRepoBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCreateRepoBinding.getRoot());
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String userLogin = tinyDb.getString("userLogin");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(ctx);
|
||||
|
||||
loginUid = tinyDB.getString("loginUid");
|
||||
userLogin = tinyDB.getString("userLogin");
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
closeActivity = findViewById(R.id.close);
|
||||
repoName = findViewById(R.id.newRepoName);
|
||||
repoDesc = findViewById(R.id.newRepoDescription);
|
||||
repoAccess = findViewById(R.id.newRepoPrivate);
|
||||
closeActivity = activityCreateRepoBinding.close;
|
||||
repoName = activityCreateRepoBinding.newRepoName;
|
||||
repoDesc = activityCreateRepoBinding.newRepoDescription;
|
||||
repoAccess = activityCreateRepoBinding.newRepoPrivate;
|
||||
|
||||
repoName.requestFocus();
|
||||
assert imm != null;
|
||||
@@ -83,120 +83,90 @@ public class CreateRepoActivity extends BaseActivity {
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
spinner = findViewById(R.id.ownerSpinner);
|
||||
spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
|
||||
getOrganizations(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), userLogin);
|
||||
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
OrgOwner user = (OrgOwner) parent.getSelectedItem();
|
||||
}
|
||||
spinner = activityCreateRepoBinding.ownerSpinner;
|
||||
getOrganizations(Authorization.get(ctx), userLogin);
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
createRepo = findViewById(R.id.createNewRepoButton);
|
||||
createRepo = activityCreateRepoBinding.createNewRepoButton;
|
||||
disableProcessButton();
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
createRepo.setOnClickListener(createRepoListener);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private View.OnClickListener createRepoListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processNewRepo();
|
||||
}
|
||||
};
|
||||
private final View.OnClickListener createRepoListener = v -> processNewRepo();
|
||||
|
||||
private void processNewRepo() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
AppUtil appUtil = new AppUtil();
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
String newRepoName = repoName.getText().toString();
|
||||
String newRepoDesc = repoDesc.getText().toString();
|
||||
String repoOwner = spinner.getSelectedItem().toString();
|
||||
boolean newRepoAccess = repoAccess.isChecked();
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!newRepoDesc.equals("")) {
|
||||
if (appUtil.charactersLength(newRepoDesc) > 255) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.repoDescError));
|
||||
if (newRepoDesc.length() > 255) {
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.repoDescError));
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(newRepoName.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorEmpty));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.repoNameErrorEmpty));
|
||||
}
|
||||
else if(!appUtil.checkStrings(newRepoName)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorInvalid));
|
||||
else if(!AppUtil.checkStrings(newRepoName)) {
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.repoNameErrorInvalid));
|
||||
}
|
||||
else if (reservedRepoNames.contains(newRepoName)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorReservedName));
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.repoNameErrorReservedName));
|
||||
}
|
||||
else if (reservedRepoPatterns.matcher(newRepoName).find()) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorReservedPatterns));
|
||||
Toasty.warning(ctx, getString(R.string.repoNameErrorReservedPatterns));
|
||||
}
|
||||
else if(selectedOwner == null) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.repoOwnerError));
|
||||
}
|
||||
else {
|
||||
|
||||
disableProcessButton();
|
||||
createNewRepository(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess);
|
||||
|
||||
createNewRepository(Authorization.get(ctx), loginUid, newRepoName, newRepoDesc, selectedOwner, newRepoAccess);
|
||||
}
|
||||
}
|
||||
|
||||
private void createNewRepository(final String instanceUrl, final String token, String loginUid, String repoName, String repoDesc, String repoOwner, boolean isPrivate) {
|
||||
private void createNewRepository(final String token, String loginUid, String repoName, String repoDesc, String selectedOwner, boolean isPrivate) {
|
||||
|
||||
OrganizationRepository createRepository = new OrganizationRepository(true, repoDesc, null, null, repoName, isPrivate, "Default");
|
||||
|
||||
Call<OrganizationRepository> call;
|
||||
if(repoOwner.equals(loginUid)) {
|
||||
if(selectedOwner.equals(loginUid)) {
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getApiInterface(ctx)
|
||||
.createNewUserRepository(token, createRepository);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.createNewUserOrgRepository(token, repoOwner, createRepository);
|
||||
|
||||
.getApiInterface(ctx)
|
||||
.createNewUserOrgRepository(token, selectedOwner, createRepository);
|
||||
}
|
||||
|
||||
call.enqueue(new Callback<OrganizationRepository>() {
|
||||
@@ -206,9 +176,9 @@ public class CreateRepoActivity extends BaseActivity {
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
tinyDb.putBoolean("repoCreated", true);
|
||||
Toasty.info(getApplicationContext(), getString(R.string.repoCreated));
|
||||
Toasty.success(ctx, getString(R.string.repoCreated));
|
||||
enableProcessButton();
|
||||
finish();
|
||||
}
|
||||
@@ -219,99 +189,96 @@ public class CreateRepoActivity extends BaseActivity {
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else if(response.code() == 409) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.repoExistsError));
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.repoExistsError));
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.repoCreatedError));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.repoCreatedError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<OrganizationRepository> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getOrganizations(String instanceUrl, String instanceToken, final String userLogin) {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
private void getOrganizations(String instanceToken, final String userLogin) {
|
||||
|
||||
Call<List<OrgOwner>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getOrgOwners(instanceToken);
|
||||
.getApiInterface(ctx)
|
||||
.getOrgOwners(instanceToken, 1, 50);
|
||||
|
||||
call.enqueue(new Callback<List<OrgOwner>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<OrgOwner>> call, @NonNull retrofit2.Response<List<OrgOwner>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 200) {
|
||||
if(response.code() == 200) {
|
||||
|
||||
int organizationId = 0;
|
||||
int organizationId = 0;
|
||||
|
||||
List<OrgOwner> organizationsList_ = response.body();
|
||||
List<OrgOwner> organizationsList_ = response.body();
|
||||
|
||||
organizationsList.add(new OrgOwner(userLogin));
|
||||
assert organizationsList_ != null;
|
||||
if(organizationsList_.size() > 0) {
|
||||
for (int i = 0; i < organizationsList_.size(); i++) {
|
||||
organizationsList.add(new OrgOwner(userLogin));
|
||||
assert organizationsList_ != null;
|
||||
|
||||
if(!tinyDb.getString("organizationId").isEmpty()) {
|
||||
if (Integer.parseInt(tinyDb.getString("organizationId")) == organizationsList_.get(i).getId()) {
|
||||
organizationId = i + 1;
|
||||
}
|
||||
}
|
||||
OrgOwner data = new OrgOwner(
|
||||
organizationsList_.get(i).getUsername()
|
||||
);
|
||||
organizationsList.add(data);
|
||||
if(organizationsList_.size() > 0) {
|
||||
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < organizationsList_.size(); i++) {
|
||||
|
||||
ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(CreateRepoActivity.this,
|
||||
R.layout.spinner_item, organizationsList);
|
||||
if(!tinyDB.getString("organizationId").isEmpty()) {
|
||||
|
||||
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
spinner.setAdapter(adapter);
|
||||
if(Integer.parseInt(tinyDB.getString("organizationId")) == organizationsList_.get(i).getId()) {
|
||||
organizationId = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (tinyDb.getBoolean("organizationAction") & organizationId != 0) {
|
||||
spinner.setSelection(organizationId);
|
||||
tinyDb.putBoolean("organizationAction", false);
|
||||
}
|
||||
OrgOwner data = new OrgOwner(organizationsList_.get(i).getUsername());
|
||||
organizationsList.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
enableProcessButton();
|
||||
ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(CreateRepoActivity.this, R.layout.list_spinner_items, organizationsList);
|
||||
|
||||
}
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
spinner.setAdapter(adapter);
|
||||
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
spinner.setOnItemClickListener ((parent, view, position, id) -> selectedOwner = organizationsList.get(position).getUsername());
|
||||
|
||||
}
|
||||
if(tinyDB.getBoolean("organizationAction") & organizationId != 0) {
|
||||
|
||||
int selectOwnerById = organizationId;
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
spinner.setText(organizationsList.get(selectOwnerById).getUsername(), false);
|
||||
selectedOwner = organizationsList.get(selectOwnerById).getUsername();
|
||||
}, 500);
|
||||
|
||||
tinyDB.putBoolean("organizationAction", false);
|
||||
}
|
||||
|
||||
enableProcessButton();
|
||||
}
|
||||
|
||||
else if(response.code() == 401) {
|
||||
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<OrgOwner>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -319,32 +286,18 @@ public class CreateRepoActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
createRepo.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
createRepo.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
createRepo.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
createRepo.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import org.gitnex.tea4j.models.Teams;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityCreateTeamByOrgBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Teams;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import android.util.Log;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -32,7 +33,6 @@ import android.util.Log;
|
||||
|
||||
public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClickListener {
|
||||
|
||||
final Context ctx = CreateTeamByOrgActivity.this;
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView teamName;
|
||||
private TextView teamDesc;
|
||||
@@ -41,15 +41,10 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
private TextView teamAccessControls;
|
||||
private TextView teamAccessControlsArray;
|
||||
private Button createTeamButton;
|
||||
private String[] permissionList = {"Read", "Write", "Admin"};
|
||||
private final String[] permissionList = {"Read", "Write", "Admin"};
|
||||
public int permissionSelectedChoice = -1;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_create_team_by_org;
|
||||
}
|
||||
|
||||
private String[] accessControlsList = new String[] {
|
||||
private final String[] accessControlsList = new String[] {
|
||||
"Code",
|
||||
"Issues",
|
||||
"Pull Request",
|
||||
@@ -61,7 +56,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
|
||||
private List<String> pushAccessList;
|
||||
|
||||
private boolean[] selectedAccessControlsTrueFalse = new boolean[]{
|
||||
private final boolean[] selectedAccessControlsTrueFalse = new boolean[]{
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -73,20 +68,24 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
ActivityCreateTeamByOrgBinding activityCreateTeamByOrgBinding = ActivityCreateTeamByOrgBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityCreateTeamByOrgBinding.getRoot());
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
teamName = findViewById(R.id.teamName);
|
||||
teamDesc = findViewById(R.id.teamDesc);
|
||||
teamPermission = findViewById(R.id.teamPermission);
|
||||
teamPermissionDetail = findViewById(R.id.teamPermissionDetail);
|
||||
teamAccessControls = findViewById(R.id.teamAccessControls);
|
||||
teamAccessControlsArray = findViewById(R.id.teamAccessControlsArray);
|
||||
createTeamButton = findViewById(R.id.createTeamButton);
|
||||
ImageView closeActivity = activityCreateTeamByOrgBinding.close;
|
||||
teamName = activityCreateTeamByOrgBinding.teamName;
|
||||
teamDesc = activityCreateTeamByOrgBinding.teamDesc;
|
||||
teamPermission = activityCreateTeamByOrgBinding.teamPermission;
|
||||
teamPermissionDetail = activityCreateTeamByOrgBinding.teamPermissionDetail;
|
||||
teamAccessControls = activityCreateTeamByOrgBinding.teamAccessControls;
|
||||
teamAccessControlsArray = activityCreateTeamByOrgBinding.teamAccessControlsArray;
|
||||
createTeamButton = activityCreateTeamByOrgBinding.createTeamButton;
|
||||
|
||||
teamName.requestFocus();
|
||||
assert imm != null;
|
||||
@@ -95,134 +94,115 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
teamPermission.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
teamPermission.setOnClickListener(view -> {
|
||||
|
||||
AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx);
|
||||
AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx);
|
||||
|
||||
pBuilder.setTitle(R.string.newTeamPermission);
|
||||
if(permissionSelectedChoice != -1) {
|
||||
pBuilder.setCancelable(true);
|
||||
}
|
||||
else {
|
||||
pBuilder.setCancelable(false);
|
||||
}
|
||||
pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
pBuilder.setTitle(R.string.newTeamPermission);
|
||||
pBuilder.setCancelable(permissionSelectedChoice != -1);
|
||||
|
||||
permissionSelectedChoice = i;
|
||||
teamPermission.setText(permissionList[i]);
|
||||
pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, (dialogInterface, i) -> {
|
||||
|
||||
if(permissionList[i].equals("Read")) {
|
||||
teamPermissionDetail.setVisibility(View.VISIBLE);
|
||||
teamPermissionDetail.setText(R.string.newTeamPermissionRead);
|
||||
permissionSelectedChoice = i;
|
||||
teamPermission.setText(permissionList[i]);
|
||||
|
||||
switch(permissionList[i]) {
|
||||
case "Read":
|
||||
|
||||
teamPermissionDetail.setVisibility(View.VISIBLE);
|
||||
teamPermissionDetail.setText(R.string.newTeamPermissionRead);
|
||||
break;
|
||||
case "Write":
|
||||
|
||||
teamPermissionDetail.setVisibility(View.VISIBLE);
|
||||
teamPermissionDetail.setText(R.string.newTeamPermissionWrite);
|
||||
break;
|
||||
case "Admin":
|
||||
|
||||
teamPermissionDetail.setVisibility(View.VISIBLE);
|
||||
teamPermissionDetail.setText(R.string.newTeamPermissionAdmin);
|
||||
break;
|
||||
default:
|
||||
|
||||
teamPermissionDetail.setVisibility(View.GONE);
|
||||
break;
|
||||
}
|
||||
|
||||
dialogInterface.dismiss();
|
||||
});
|
||||
|
||||
AlertDialog pDialog = pBuilder.create();
|
||||
pDialog.show();
|
||||
});
|
||||
|
||||
teamAccessControls.setOnClickListener(v -> {
|
||||
|
||||
teamAccessControls.setText("");
|
||||
teamAccessControlsArray.setText("");
|
||||
pushAccessList = Arrays.asList(accessControlsList);
|
||||
|
||||
AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(ctx);
|
||||
|
||||
aDialogBuilder.setMultiChoiceItems(accessControlsList, selectedAccessControlsTrueFalse, (dialog, which, isChecked) -> {
|
||||
|
||||
})
|
||||
.setCancelable(false)
|
||||
.setTitle(R.string.newTeamAccessControls)
|
||||
.setPositiveButton(R.string.okButton, (dialog, which) -> {
|
||||
|
||||
int selectedVal = 0;
|
||||
while(selectedVal < selectedAccessControlsTrueFalse.length)
|
||||
{
|
||||
boolean value = selectedAccessControlsTrueFalse[selectedVal];
|
||||
|
||||
String repoCode = "";
|
||||
if(selectedVal == 0) {
|
||||
repoCode = "repo.code";
|
||||
}
|
||||
else if(permissionList[i].equals("Write")) {
|
||||
teamPermissionDetail.setVisibility(View.VISIBLE);
|
||||
teamPermissionDetail.setText(R.string.newTeamPermissionWrite);
|
||||
if(selectedVal == 1) {
|
||||
repoCode = "repo.issues";
|
||||
}
|
||||
else if(permissionList[i].equals("Admin")) {
|
||||
teamPermissionDetail.setVisibility(View.VISIBLE);
|
||||
teamPermissionDetail.setText(R.string.newTeamPermissionAdmin);
|
||||
if(selectedVal == 2) {
|
||||
repoCode = "repo.pulls";
|
||||
}
|
||||
else {
|
||||
teamPermissionDetail.setVisibility(View.GONE);
|
||||
if(selectedVal == 3) {
|
||||
repoCode = "repo.releases";
|
||||
}
|
||||
if(selectedVal == 4) {
|
||||
repoCode = "repo.wiki";
|
||||
}
|
||||
if(selectedVal == 5) {
|
||||
repoCode = "repo.ext_wiki";
|
||||
}
|
||||
if(selectedVal == 6) {
|
||||
repoCode = "repo.ext_issues";
|
||||
}
|
||||
|
||||
dialogInterface.dismiss();
|
||||
if(value){
|
||||
|
||||
teamAccessControls.setText(getString(R.string.newTeamPermissionValues, teamAccessControls.getText(), pushAccessList.get(selectedVal)));
|
||||
teamAccessControlsArray.setText(getString(R.string.newTeamPermissionValuesFinal, teamAccessControlsArray.getText(), repoCode));
|
||||
}
|
||||
|
||||
selectedVal++;
|
||||
}
|
||||
|
||||
String data = String.valueOf(teamAccessControls.getText());
|
||||
if(!data.equals("")) {
|
||||
|
||||
teamAccessControls.setText(data.substring(0, data.length() - 2));
|
||||
}
|
||||
|
||||
String dataArray = String.valueOf(teamAccessControlsArray.getText());
|
||||
|
||||
if(!dataArray.equals("")) {
|
||||
|
||||
teamAccessControlsArray.setText(dataArray.substring(0, dataArray.length() - 2));
|
||||
}
|
||||
});
|
||||
|
||||
AlertDialog pDialog = pBuilder.create();
|
||||
pDialog.show();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
teamAccessControls.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
teamAccessControls.setText("");
|
||||
teamAccessControlsArray.setText("");
|
||||
pushAccessList = Arrays.asList(accessControlsList);
|
||||
|
||||
AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(ctx);
|
||||
|
||||
aDialogBuilder.setMultiChoiceItems(accessControlsList, selectedAccessControlsTrueFalse, new DialogInterface.OnMultiChoiceClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
.setCancelable(false)
|
||||
.setTitle(R.string.newTeamAccessControls)
|
||||
.setPositiveButton(R.string.okButton, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
|
||||
int selectedVal = 0;
|
||||
while(selectedVal < selectedAccessControlsTrueFalse.length)
|
||||
{
|
||||
boolean value = selectedAccessControlsTrueFalse[selectedVal];
|
||||
|
||||
String repoCode = "";
|
||||
if(selectedVal == 0) {
|
||||
repoCode = "repo.code";
|
||||
}
|
||||
if(selectedVal == 1) {
|
||||
repoCode = "repo.issues";
|
||||
}
|
||||
if(selectedVal == 2) {
|
||||
repoCode = "repo.pulls";
|
||||
}
|
||||
if(selectedVal == 3) {
|
||||
repoCode = "repo.releases";
|
||||
}
|
||||
if(selectedVal == 4) {
|
||||
repoCode = "repo.wiki";
|
||||
}
|
||||
if(selectedVal == 5) {
|
||||
repoCode = "repo.ext_wiki";
|
||||
}
|
||||
if(selectedVal == 6) {
|
||||
repoCode = "repo.ext_issues";
|
||||
}
|
||||
|
||||
if(value){
|
||||
teamAccessControls.setText(getString(R.string.newTeamPermissionValues, teamAccessControls.getText(), pushAccessList.get(selectedVal)));
|
||||
teamAccessControlsArray.setText(getString(R.string.newTeamPermissionValuesFinal, teamAccessControlsArray.getText(), repoCode));
|
||||
}
|
||||
|
||||
selectedVal++;
|
||||
}
|
||||
|
||||
String data = String.valueOf(teamAccessControls.getText());
|
||||
if(!data.equals("")) {
|
||||
teamAccessControls.setText(data.substring(0, data.length() - 2));
|
||||
}
|
||||
|
||||
String dataArray = String.valueOf(teamAccessControlsArray.getText());
|
||||
if(!dataArray.equals("")) {
|
||||
teamAccessControlsArray.setText(dataArray.substring(0, dataArray.length() - 2));
|
||||
}
|
||||
//Log.i("orgName", String.valueOf(teamAccessControlsArray.getText()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
AlertDialog aDialog = aDialogBuilder.create();
|
||||
aDialog.show();
|
||||
}
|
||||
AlertDialog aDialog = aDialogBuilder.create();
|
||||
aDialog.show();
|
||||
});
|
||||
|
||||
createTeamButton.setEnabled(false);
|
||||
@@ -230,30 +210,26 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
if(!connToInternet) {
|
||||
|
||||
createTeamButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius(8);
|
||||
shape.setColor(ResourcesCompat.getColor(getResources(), R.color.hintColor, null));
|
||||
createTeamButton.setBackground(shape);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
createTeamButton.setEnabled(true);
|
||||
createTeamButton.setOnClickListener(this);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void processCreateTeam() {
|
||||
|
||||
AppUtil appUtil = new AppUtil();
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
final String orgName = tinyDb.getString("orgName");;
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
String newTeamName = teamName.getText().toString();
|
||||
String newTeamDesc = teamDesc.getText().toString();
|
||||
String newTeamPermission = teamPermission.getText().toString().toLowerCase();
|
||||
@@ -261,66 +237,62 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (newTeamName.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.teamNameEmpty));
|
||||
Toasty.error(ctx, getString(R.string.teamNameEmpty));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
|
||||
if(!AppUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.teamNameError));
|
||||
Toasty.warning(ctx, getString(R.string.teamNameError));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!newTeamDesc.equals("")) {
|
||||
|
||||
if(!appUtil.checkStrings(newTeamDesc)) {
|
||||
Toasty.info(getApplicationContext(), getString(R.string.teamDescError));
|
||||
if(!AppUtil.checkStrings(newTeamDesc)) {
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.teamDescError));
|
||||
return;
|
||||
}
|
||||
|
||||
if(newTeamDesc.length() > 100) {
|
||||
Toasty.info(getApplicationContext(), getString(R.string.teamDescLimit));
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.teamDescLimit));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (newTeamPermission.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.teamPermissionEmpty));
|
||||
Toasty.error(ctx, getString(R.string.teamPermissionEmpty));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
List<String> newTeamAccessControls_ = new ArrayList<>(Arrays.asList(newTeamAccessControls.split(",")));
|
||||
|
||||
for (int i = 0; i < newTeamAccessControls_.size(); i++) {
|
||||
|
||||
newTeamAccessControls_.set(i, newTeamAccessControls_.get(i).trim());
|
||||
}
|
||||
|
||||
createNewTeamCall(instanceUrl, instanceToken, orgName, newTeamName, newTeamDesc, newTeamPermission, newTeamAccessControls_, loginUid);
|
||||
|
||||
createNewTeamCall(instanceToken, orgName, newTeamName, newTeamDesc, newTeamPermission, newTeamAccessControls_, loginUid);
|
||||
}
|
||||
|
||||
private void createNewTeamCall(final String instanceUrl, final String instanceToken, String orgName, String newTeamName, String newTeamDesc, String newTeamPermission, List<String> newTeamAccessControls, String loginUid) {
|
||||
private void createNewTeamCall(final String instanceToken, String orgName, String newTeamName, String newTeamDesc, String newTeamPermission, List<String> newTeamAccessControls, String loginUid) {
|
||||
|
||||
Teams createNewTeamJson = new Teams(newTeamName, newTeamDesc, newTeamPermission, newTeamAccessControls);
|
||||
|
||||
Call<Teams> call3;
|
||||
|
||||
call3 = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.createTeamsByOrg(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), orgName, createNewTeamJson);
|
||||
.getApiInterface(ctx)
|
||||
.createTeamsByOrg(Authorization.get(ctx), orgName, createNewTeamJson);
|
||||
|
||||
call3.enqueue(new Callback<Teams>() {
|
||||
|
||||
@@ -328,21 +300,19 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
public void onResponse(@NonNull Call<Teams> call, @NonNull retrofit2.Response<Teams> response2) {
|
||||
|
||||
if(response2.isSuccessful()) {
|
||||
|
||||
if(response2.code() == 201) {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
tinyDb.putBoolean("resumeTeams", true);
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.teamCreated));
|
||||
Toasty.success(ctx, getString(R.string.teamCreated));
|
||||
finish();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if(response2.code() == 404) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
|
||||
|
||||
Toasty.warning(ctx, getString(R.string.apiNotFound));
|
||||
}
|
||||
else if(response2.code() == 401) {
|
||||
|
||||
@@ -350,14 +320,11 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.teamCreatedError));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.teamCreatedError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -370,19 +337,16 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
if(v == createTeamButton) {
|
||||
|
||||
processCreateTeam();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.CreditsAdapter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class CreditsActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_credits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
Resources res = getResources();
|
||||
CharSequence[] creditsInfo = res.getTextArray(R.array.creditsInfo);
|
||||
|
||||
List<CharSequence> creditsList = new ArrayList<>(Arrays.asList(creditsInfo));
|
||||
|
||||
RecyclerView mRecyclerView = findViewById(R.id.recyclerView);
|
||||
|
||||
mRecyclerView.setHasFixedSize(true);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
CreditsAdapter adapter = new CreditsAdapter(creditsList);
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,698 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.gitnex.tea4j.models.Files;
|
||||
import org.gitnex.tea4j.models.Organization;
|
||||
import org.gitnex.tea4j.models.PullRequests;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.gitnex.tea4j.models.UserRepositories;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.database.api.UserAccountsApi;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.database.models.UserAccount;
|
||||
import org.mian.gitnex.databinding.ActivityDeeplinksBinding;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.UrlHelper;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import io.mikael.urlbuilder.UrlBuilder;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class DeepLinksActivity extends BaseActivity {
|
||||
|
||||
private ActivityDeeplinksBinding viewBinding;
|
||||
private String currentInstance;
|
||||
private String instanceToken;
|
||||
private boolean accountFound = false;
|
||||
|
||||
private Intent mainIntent;
|
||||
private Intent issueIntent;
|
||||
private Intent repoIntent;
|
||||
private Intent orgIntent;
|
||||
private Intent userIntent;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
viewBinding = ActivityDeeplinksBinding.inflate(getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
|
||||
mainIntent = new Intent(ctx, MainActivity.class);
|
||||
issueIntent = new Intent(ctx, IssueDetailActivity.class);
|
||||
repoIntent = new Intent(ctx, RepoDetailActivity.class);
|
||||
orgIntent = new Intent(ctx, OrganizationDetailActivity.class);
|
||||
userIntent = new Intent(ctx, ProfileActivity.class);
|
||||
|
||||
Intent intent = getIntent();
|
||||
Uri data = intent.getData();
|
||||
assert data != null;
|
||||
|
||||
// check for login
|
||||
if(!tinyDB.getBoolean("loggedInMode")) {
|
||||
Intent loginIntent = new Intent(ctx, LoginActivity.class);
|
||||
loginIntent.putExtra("instanceUrl", data.getHost());
|
||||
ctx.startActivity(loginIntent);
|
||||
finish();
|
||||
}
|
||||
|
||||
// check for the links(URI) to be in the db
|
||||
UserAccountsApi userAccountsApi = BaseApi.getInstance(ctx, UserAccountsApi.class);
|
||||
List<UserAccount> userAccounts = userAccountsApi.usersAccounts();
|
||||
|
||||
for(UserAccount userAccount : userAccounts) {
|
||||
|
||||
String hostUri = userAccount.getInstanceUrl();
|
||||
|
||||
currentInstance = userAccount.getInstanceUrl();
|
||||
instanceToken = userAccount.getToken();
|
||||
|
||||
if(hostUri.toLowerCase().contains(Objects.requireNonNull(data.getHost().toLowerCase()))) {
|
||||
|
||||
accountFound = true;
|
||||
|
||||
AppUtil.switchToAccount(ctx, userAccount);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(accountFound) {
|
||||
|
||||
// redirect to proper fragment/activity, if no action is there, show options where user to want to go like repos, profile, notifications etc
|
||||
if(data.getPathSegments().size() == 1) {
|
||||
if(data.getLastPathSegment().equals("notifications")) { // notifications
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(data.getLastPathSegment().equals("explore")) { // explore
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(data.getLastPathSegment().equals(tinyDB.getString("userLogin"))) { // your user profile
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "profile");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(data.getLastPathSegment().equals("admin")) {
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "admin");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
getUserOrOrg(currentInstance, instanceToken, data.getLastPathSegment()), 500);
|
||||
}
|
||||
}
|
||||
else if(data.getPathSegments().size() == 2) {
|
||||
if(data.getPathSegments().get(0).equals("explore")) { // specific explore tab
|
||||
if(data.getPathSegments().get(1).equals("organizations")) { // orgs
|
||||
mainIntent.putExtra("exploreOrgs", true);
|
||||
}
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(data.getPathSegments().get(0).equals("user") && data.getPathSegments().get(1).equals("login")) { // open login
|
||||
Intent loginIntent = new Intent(ctx, AddNewAccountActivity.class);
|
||||
loginIntent.putExtra("instanceUrl", data.getHost());
|
||||
loginIntent.putExtra("instanceProtocol", data.getScheme());
|
||||
ctx.startActivity(loginIntent);
|
||||
finish();
|
||||
}
|
||||
else if(data.getPathSegments().get(0).equals("admin")) {
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "admin");
|
||||
mainIntent.putExtra("giteaAdminAction", data.getLastPathSegment());
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(!data.getPathSegments().get(0).equals("") & !data.getLastPathSegment().equals("")) { // go to repo
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getLastPathSegment(), "repo"), 500);
|
||||
}
|
||||
else { // no action, show options
|
||||
showNoActionButtons();
|
||||
}
|
||||
}
|
||||
else if(data.getPathSegments().size() >= 3) {
|
||||
if(data.getPathSegments().get(2).equals("issues")) { // issue
|
||||
|
||||
if(!Objects.requireNonNull(data.getLastPathSegment()).contains("issues") & StringUtils.isNumeric(data.getLastPathSegment())) {
|
||||
|
||||
issueIntent.putExtra("issueNumber", data.getLastPathSegment());
|
||||
issueIntent.putExtra("openedFromLink", "true");
|
||||
|
||||
String[] urlSplitted = data.toString().split("#");
|
||||
if (urlSplitted.length == 2) {
|
||||
issueIntent.putExtra("issueComment", urlSplitted[1]);
|
||||
}
|
||||
|
||||
tinyDB.putString("issueNumber", data.getLastPathSegment());
|
||||
tinyDB.putString("issueType", "Issue");
|
||||
|
||||
tinyDB.putString("repoFullName", data.getPathSegments().get(0) + "/" + data.getPathSegments().get(1));
|
||||
|
||||
final String repoOwner = data.getPathSegments().get(0);
|
||||
final String repoName = data.getPathSegments().get(1);
|
||||
|
||||
int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
|
||||
RepositoriesApi repositoryData = BaseApi.getInstance(ctx, RepositoriesApi.class);
|
||||
|
||||
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
|
||||
if(count == 0) {
|
||||
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDB.putLong("repositoryId", id);
|
||||
}
|
||||
else {
|
||||
|
||||
Repository dataRepo = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDB.putLong("repositoryId", dataRepo.getRepositoryId());
|
||||
}
|
||||
|
||||
ctx.startActivity(issueIntent);
|
||||
finish();
|
||||
}
|
||||
else if(Objects.requireNonNull(data.getLastPathSegment()).contains("issues")) {
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "issue"), 500);
|
||||
}
|
||||
else if(data.getLastPathSegment().equals("new")) {
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "issueNew"), 500);
|
||||
}
|
||||
else {
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("pulls")) { // pr
|
||||
|
||||
if(!Objects.requireNonNull(data.getLastPathSegment()).contains("pulls") & StringUtils.isNumeric(data.getLastPathSegment())) {
|
||||
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
String[] urlSplitted = data.toString().split("#");
|
||||
if (urlSplitted.length == 2) {
|
||||
issueIntent.putExtra("issueComment", urlSplitted[1]);
|
||||
}
|
||||
|
||||
getPullRequest(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), Integer.parseInt(data.getLastPathSegment()));
|
||||
}, 500);
|
||||
|
||||
}
|
||||
else if(Objects.requireNonNull(data.getLastPathSegment()).contains("pulls")) {
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "pull"), 500);
|
||||
}
|
||||
else if(data.getLastPathSegment().equals("files")) { // pr diff
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
issueIntent.putExtra("openPrDiff", "true");
|
||||
getPullRequest(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), Integer.parseInt(data.getPathSegments().get(3)));
|
||||
}, 500);
|
||||
}
|
||||
else {
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
else if(data.getPathSegments().get(2).equals("compare")) { // new pull request
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "pullNew"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("commit")) { // commits (no API yet to properly implement)
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "pull"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("commits")) { // commits list
|
||||
String branch = data.getLastPathSegment();
|
||||
repoIntent.putExtra("branchName", branch);
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "commitsList"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("milestones") && data.getLastPathSegment().equals("new")) { // new milestone
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "milestonesNew"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("milestones")) { // milestones
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "milestones"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("milestone")) { // milestone
|
||||
repoIntent.putExtra("milestoneId", data.getLastPathSegment());
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "milestones"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("releases") && data.getLastPathSegment().equals("new")) { // new release
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "newRelease"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("releases")) { // releases
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "releases"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("releases") && data.getPathSegments().get(3).equals("tag") && data.getPathSegments().size() == 5) { // release
|
||||
repoIntent.putExtra("releaseTagName", data.getLastPathSegment());
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "releases"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("labels")) { // labels
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "labels"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("settings")) { // repo settings
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "settings"), 500);
|
||||
}
|
||||
else if(data.getLastPathSegment().equals("branches")) { // branches list
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "branchesList"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().size() == 5 && data.getPathSegments().get(2).equals("src") && data.getPathSegments().get(3).equals("branch")) { // branch
|
||||
repoIntent.putExtra("selectedBranch", data.getLastPathSegment());
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getPathSegments().get(1), "branch"), 500);
|
||||
}
|
||||
else if(data.getPathSegments().get(2).equals("src") && data.getPathSegments().get(3).equals("branch")) { // file/dir
|
||||
StringBuilder filePath = new StringBuilder();
|
||||
ArrayList<String> segments = new ArrayList<>(data.getPathSegments());
|
||||
segments.subList(0, 5).clear();
|
||||
for (String item : segments) {
|
||||
filePath.append(item);
|
||||
filePath.append("/");
|
||||
}
|
||||
filePath.deleteCharAt(filePath.toString().length() - 1);
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() ->
|
||||
getFile(currentInstance, instanceToken, data.getPathSegments().get(0),
|
||||
data.getPathSegments().get(1), filePath.toString(), data.getPathSegments().get(4)), 500);
|
||||
}
|
||||
else { // no action, show options
|
||||
showNoActionButtons();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
viewBinding.progressBar.setVisibility(View.GONE);
|
||||
viewBinding.addNewAccountFrame.setVisibility(View.VISIBLE);
|
||||
viewBinding.noActionFrame.setVisibility(View.GONE);
|
||||
viewBinding.addAccountText.setText(String.format(getResources().getString(R.string.accountDoesNotExist), data.getHost()));
|
||||
|
||||
viewBinding.addNewAccount.setOnClickListener(addNewAccount -> {
|
||||
|
||||
Intent accountIntent = new Intent(ctx, AddNewAccountActivity.class);
|
||||
accountIntent.putExtra("instanceUrl", data.getHost());
|
||||
startActivity(accountIntent);
|
||||
finish();
|
||||
});
|
||||
|
||||
viewBinding.openInBrowser.setOnClickListener(addNewAccount -> {
|
||||
|
||||
Integer port = data.getPort() >= 0 ? data.getPort() : null;
|
||||
|
||||
URI host = UrlBuilder.fromString(UrlHelper.fixScheme(data.getHost(), "https"))
|
||||
.withPort(port)
|
||||
.toUri();
|
||||
|
||||
Intent intentBrowser = new Intent();
|
||||
|
||||
intentBrowser.setAction(Intent.ACTION_VIEW);
|
||||
intentBrowser.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
intentBrowser.setData(Uri.parse(String.valueOf(host)));
|
||||
|
||||
startActivity(intentBrowser);
|
||||
finish();
|
||||
|
||||
});
|
||||
|
||||
viewBinding.launchApp.setOnClickListener(launchApp -> {
|
||||
|
||||
startActivity(mainIntent);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void getPullRequest(String url, String token, String repoOwner, String repoName, int index) {
|
||||
|
||||
Call<PullRequests> call = RetrofitClient
|
||||
.getApiInterface(ctx, url)
|
||||
.getPullRequestByIndex(token, repoOwner, repoName, index);
|
||||
|
||||
call.enqueue(new Callback<PullRequests>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<PullRequests> call, @NonNull retrofit2.Response<PullRequests> response) {
|
||||
|
||||
PullRequests prInfo = response.body();
|
||||
|
||||
if (response.code() == 200) {
|
||||
|
||||
assert prInfo != null;
|
||||
|
||||
issueIntent.putExtra("issueNumber", index);
|
||||
issueIntent.putExtra("prMergeable", prInfo.isMergeable());
|
||||
issueIntent.putExtra("openedFromLink", "true");
|
||||
|
||||
if(prInfo.getHead() != null) {
|
||||
|
||||
issueIntent.putExtra("prHeadBranch", prInfo.getHead().getRef());
|
||||
tinyDB.putString("prHeadBranch", prInfo.getHead().getRef());
|
||||
|
||||
if(prInfo.getHead().getRepo() != null) {
|
||||
|
||||
tinyDB.putString("prIsFork", String.valueOf(prInfo.getHead().getRepo().isFork()));
|
||||
tinyDB.putString("prForkFullName", prInfo.getHead().getRepo().getFull_name());
|
||||
}
|
||||
else {
|
||||
|
||||
// pull was done from a deleted fork
|
||||
tinyDB.putString("prIsFork", "true");
|
||||
tinyDB.putString("prForkFullName", ctx.getString(R.string.prDeletedFork));
|
||||
}
|
||||
}
|
||||
|
||||
tinyDB.putString("issueNumber", String.valueOf(index));
|
||||
tinyDB.putString("prMergeable", String.valueOf(prInfo.isMergeable()));
|
||||
tinyDB.putString("issueType", "Pull");
|
||||
|
||||
tinyDB.putString("repoFullName", repoOwner + "/" + repoName);
|
||||
|
||||
int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
|
||||
RepositoriesApi repositoryData = BaseApi.getInstance(ctx, RepositoriesApi.class);
|
||||
|
||||
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
|
||||
if(count == 0) {
|
||||
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDB.putLong("repositoryId", id);
|
||||
}
|
||||
else {
|
||||
|
||||
Repository dataRepo = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDB.putLong("repositoryId", dataRepo.getRepositoryId());
|
||||
}
|
||||
|
||||
ctx.startActivity(issueIntent);
|
||||
finish();
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
ctx.startActivity(issueIntent);
|
||||
finish();
|
||||
Log.e("onFailure-links-pr", String.valueOf(response.code()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<PullRequests> call, @NonNull Throwable t) {
|
||||
|
||||
ctx.startActivity(issueIntent);
|
||||
finish();
|
||||
Log.e("onFailure-links-pr", t.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void goToRepoSection(String url, String token, String repoOwner, String repoName, String type) {
|
||||
|
||||
Call<UserRepositories> call = RetrofitClient
|
||||
.getApiInterface(ctx, url)
|
||||
.getUserRepository(token, repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<UserRepositories>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
|
||||
|
||||
UserRepositories repoInfo = response.body();
|
||||
|
||||
if (response.code() == 200) {
|
||||
|
||||
assert repoInfo != null;
|
||||
|
||||
repoIntent.putExtra("repoFullName", repoInfo.getFullName());
|
||||
repoIntent.putExtra("goToSection", "yes");
|
||||
repoIntent.putExtra("goToSectionType", type);
|
||||
|
||||
tinyDB.putString("repoFullName", repoInfo.getFullName());
|
||||
if(repoInfo.getPrivateFlag()) {
|
||||
|
||||
tinyDB.putString("repoType", getResources().getString(R.string.strPrivate));
|
||||
}
|
||||
else {
|
||||
|
||||
tinyDB.putString("repoType", getResources().getString(R.string.strPublic));
|
||||
}
|
||||
tinyDB.putBoolean("isRepoAdmin", repoInfo.getPermissions().isAdmin());
|
||||
tinyDB.putString("repoBranch", repoInfo.getDefault_branch());
|
||||
|
||||
int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
|
||||
RepositoriesApi repositoryData = BaseApi.getInstance(ctx, RepositoriesApi.class);
|
||||
|
||||
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
|
||||
if(count == 0) {
|
||||
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDB.putLong("repositoryId", id);
|
||||
}
|
||||
else {
|
||||
|
||||
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDB.putLong("repositoryId", data.getRepositoryId());
|
||||
}
|
||||
|
||||
ctx.startActivity(repoIntent);
|
||||
finish();
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
Log.e("onFailure-goToRepo", String.valueOf(response.code()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
|
||||
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
Log.e("onFailure-goToRepo", t.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getUserOrOrg(String url, String instanceToken, String userOrgName) {
|
||||
Call<Organization> call = RetrofitClient.getApiInterface(ctx, url).getOrganization(instanceToken, userOrgName);
|
||||
|
||||
call.enqueue(new Callback<Organization>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NotNull Call<Organization> call, @NotNull Response<Organization> response) {
|
||||
if(response.code() == 404) { // org doesn't exist or it's a user user
|
||||
Log.d("getUserOrOrg-404", String.valueOf(response.code()));
|
||||
getUser(url, instanceToken, userOrgName);
|
||||
}
|
||||
else if(response.code() == 200) { // org
|
||||
assert response.body() != null;
|
||||
orgIntent.putExtra("orgName", response.body().getUsername());
|
||||
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(ctx);
|
||||
tinyDb.putString("orgName", response.body().getUsername());
|
||||
tinyDb.putString("organizationId", String.valueOf(response.body().getId()));
|
||||
tinyDb.putBoolean("organizationAction", true);
|
||||
ctx.startActivity(orgIntent);
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
Log.e("getUserOrOrg-code", String.valueOf(response.code()));
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Call<Organization> call, @NotNull Throwable t) {
|
||||
Log.e("onFailure-getUserOrOrg", t.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getUser(String url, String instanceToken, String userName) {
|
||||
Call<UserInfo> call = RetrofitClient.getApiInterface(ctx, url).getUserProfile(instanceToken, userName);
|
||||
|
||||
call.enqueue(new Callback<UserInfo>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NotNull Call<UserInfo> call, @NotNull Response<UserInfo> response) {
|
||||
if(response.code() == 200) {
|
||||
assert response.body() != null;
|
||||
userIntent.putExtra("username", response.body().getLogin());
|
||||
ctx.startActivity(userIntent);
|
||||
}
|
||||
else {
|
||||
Log.e("getUser-code", String.valueOf(response.code()));
|
||||
ctx.startActivity(mainIntent);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Call<UserInfo> call, @NotNull Throwable t) {
|
||||
Log.e("onFailure-getUser", t.toString());
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getFile(String url, String instanceToken, String owner, String repo, String filePath, String branch) {
|
||||
Call<Files> call = RetrofitClient.getApiInterface(ctx, url).getSingleFileContents(instanceToken, owner, repo, filePath, branch);
|
||||
|
||||
call.enqueue(new Callback<Files>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NotNull Call<Files> call, @NotNull Response<Files> response) {
|
||||
if(response.code() == 200) {
|
||||
// check if file and open file/dir
|
||||
Files file = response.body();
|
||||
assert file != null;
|
||||
if(file.getType().equals("file")) {
|
||||
repoIntent.putExtra("file", file);
|
||||
repoIntent.putExtra("branch", branch);
|
||||
goToRepoSection(url, instanceToken, owner, repo, "file");
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log.e("getFile-onFailure", String.valueOf(response.code()));
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Call<Files> call, @NotNull Throwable t) {
|
||||
Log.e("getFile-onFailure", t.toString());
|
||||
// maybe it's a directory
|
||||
getDir(url, instanceToken, owner, repo, filePath, branch);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getDir(String url, String instanceToken, String owner, String repo, String filePath, String branch) {
|
||||
repoIntent.putExtra("branch", branch);
|
||||
repoIntent.putExtra("dir", filePath);
|
||||
goToRepoSection(url, instanceToken, owner, repo, "dir");
|
||||
}
|
||||
|
||||
private void showNoActionButtons() {
|
||||
viewBinding.progressBar.setVisibility(View.GONE);
|
||||
|
||||
if(tinyDB.getInt("defaultScreenId") == 1) { // repos
|
||||
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(tinyDB.getInt("defaultScreenId") == 2) { // org
|
||||
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(tinyDB.getInt("defaultScreenId") == 3) { // notifications
|
||||
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(tinyDB.getInt("defaultScreenId") == 4) { // explore
|
||||
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
}
|
||||
else if(tinyDB.getInt("defaultScreenId") == 0) { // show options
|
||||
|
||||
viewBinding.noActionFrame.setVisibility(View.VISIBLE);
|
||||
viewBinding.addNewAccountFrame.setVisibility(View.GONE);
|
||||
|
||||
viewBinding.repository.setOnClickListener(repository -> {
|
||||
|
||||
tinyDB.putInt("defaultScreenId", 1);
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
});
|
||||
|
||||
viewBinding.organization.setOnClickListener(organization -> {
|
||||
|
||||
tinyDB.putInt("defaultScreenId", 2);
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
});
|
||||
|
||||
viewBinding.notification.setOnClickListener(notification -> {
|
||||
|
||||
tinyDB.putInt("defaultScreenId", 3);
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
});
|
||||
|
||||
viewBinding.explore.setOnClickListener(explore -> {
|
||||
|
||||
tinyDB.putInt("defaultScreenId", 4);
|
||||
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
});
|
||||
|
||||
viewBinding.launchApp2.setOnClickListener(launchApp2 -> {
|
||||
|
||||
tinyDB.putInt("defaultScreenId", 0);
|
||||
ctx.startActivity(mainIntent);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,42 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.Button;
|
||||
import android.widget.DatePicker;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.hendraanggrian.appcompat.socialview.Mention;
|
||||
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
|
||||
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
|
||||
import org.gitnex.tea4j.models.CreateIssue;
|
||||
import org.gitnex.tea4j.models.Issues;
|
||||
import org.gitnex.tea4j.models.Milestones;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityEditIssueBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Collaborators;
|
||||
import org.mian.gitnex.models.CreateIssue;
|
||||
import org.mian.gitnex.models.Issues;
|
||||
import org.mian.gitnex.models.Milestones;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -47,61 +44,74 @@ import java.util.List;
|
||||
|
||||
public class EditIssueActivity extends BaseActivity implements View.OnClickListener {
|
||||
|
||||
final Context ctx = this;
|
||||
private View.OnClickListener onClickListener;
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
|
||||
private EditText editIssueTitle;
|
||||
private SocialAutoCompleteTextView editIssueDescription;
|
||||
private EditText editIssueDescription;
|
||||
private TextView editIssueDueDate;
|
||||
private Button editIssueButton;
|
||||
private Spinner editIssueMilestoneSpinner;
|
||||
private AutoCompleteTextView editIssueMilestoneSpinner;
|
||||
|
||||
private String msState = "open";
|
||||
private int milestoneId;
|
||||
|
||||
List<Milestones> milestonesList = new ArrayList<>();
|
||||
private ArrayAdapter<Mention> defaultMentionAdapter;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_edit_issue;
|
||||
}
|
||||
private String loginUid;
|
||||
private String instanceToken;
|
||||
private String repoOwner;
|
||||
private String repoName;
|
||||
private int issueIndex;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityEditIssueBinding activityEditIssueBinding = ActivityEditIssueBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityEditIssueBinding.getRoot());
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
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");
|
||||
loginUid = tinyDB.getString("loginUid");
|
||||
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];
|
||||
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
|
||||
repoOwner = parts[0];
|
||||
repoName = parts[1];
|
||||
issueIndex = Integer.parseInt(tinyDB.getString("issueNumber"));
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
editIssueButton = findViewById(R.id.editIssueButton);
|
||||
TextView toolbar_title = findViewById(R.id.toolbar_title);
|
||||
editIssueTitle = findViewById(R.id.editIssueTitle);
|
||||
editIssueDescription = findViewById(R.id.editIssueDescription);
|
||||
editIssueDueDate = findViewById(R.id.editIssueDueDate);
|
||||
ImageView closeActivity = activityEditIssueBinding.close;
|
||||
editIssueButton = activityEditIssueBinding.editIssueButton;
|
||||
TextView toolbar_title = activityEditIssueBinding.toolbarTitle;
|
||||
editIssueTitle = activityEditIssueBinding.editIssueTitle;
|
||||
editIssueDescription = activityEditIssueBinding.editIssueDescription;
|
||||
editIssueDueDate = activityEditIssueBinding.editIssueDueDate;
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
editIssueTitle.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
defaultMentionAdapter = new MentionArrayAdapter<>(this);
|
||||
loadCollaboratorsList();
|
||||
editIssueDescription.setOnTouchListener((touchView, motionEvent) -> {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) {
|
||||
|
||||
touchView.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
editIssueMilestoneSpinner = findViewById(R.id.editIssueMilestoneSpinner);
|
||||
editIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
|
||||
|
||||
editIssueDescription.setMentionAdapter(defaultMentionAdapter);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
@@ -109,97 +119,30 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
editIssueDueDate.setOnClickListener(this);
|
||||
editIssueButton.setOnClickListener(this);
|
||||
|
||||
if(!tinyDb.getString("issueNumber").isEmpty()) {
|
||||
if(!tinyDB.getString("issueNumber").isEmpty()) {
|
||||
|
||||
if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) {
|
||||
|
||||
if(tinyDb.getString("issueType").equals("pr")) {
|
||||
toolbar_title.setText(getString(R.string.editPrNavHeader, String.valueOf(issueIndex)));
|
||||
}
|
||||
else {
|
||||
|
||||
toolbar_title.setText(getString(R.string.editIssueNavHeader, String.valueOf(issueIndex)));
|
||||
}
|
||||
}
|
||||
|
||||
disableProcessButton();
|
||||
getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void loadCollaboratorsList() {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
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<List<Collaborators>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Collaborators>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
String fullName = "";
|
||||
for (int i = 0; i < response.body().size(); i++) {
|
||||
if(!response.body().get(i).getFull_name().equals("")) {
|
||||
fullName = response.body().get(i).getFull_name();
|
||||
}
|
||||
defaultMentionAdapter.add(
|
||||
new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
Log.i("onResponse", String.valueOf(response.code()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
|
||||
Log.i("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
getIssue(instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit);
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void processEditIssue() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
|
||||
|
||||
Milestones mModel = (Milestones) editIssueMilestoneSpinner.getSelectedItem();
|
||||
|
||||
int editIssueMilestoneId = mModel.getId();
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
String editIssueTitleForm = editIssueTitle.getText().toString();
|
||||
String editIssueDescriptionForm = editIssueDescription.getText().toString();
|
||||
@@ -207,47 +150,36 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (editIssueTitleForm.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty));
|
||||
Toasty.error(ctx, getString(R.string.issueTitleEmpty));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*if (editIssueDescriptionForm.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty));
|
||||
return;
|
||||
|
||||
}*/
|
||||
|
||||
if (editIssueDueDateForm.equals("")) {
|
||||
|
||||
editIssueDueDateForm = null;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
editIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(editIssueDueDateForm)));
|
||||
}
|
||||
|
||||
//Log.i("editIssueDueDateForm", String.valueOf(editIssueDueDateForm));
|
||||
disableProcessButton();
|
||||
editIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid, editIssueTitleForm, editIssueDescriptionForm, editIssueDueDateForm, editIssueMilestoneId);
|
||||
|
||||
editIssue(instanceToken, repoOwner, repoName, issueIndex, loginUid, editIssueTitleForm, editIssueDescriptionForm, editIssueDueDateForm, milestoneId);
|
||||
}
|
||||
|
||||
private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int editIssueMilestoneId) {
|
||||
private void editIssue(String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int milestoneId) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
CreateIssue issueData = new CreateIssue(title, description, dueDate, editIssueMilestoneId);
|
||||
CreateIssue issueData = new CreateIssue(title, description, dueDate, milestoneId);
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.patchIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData);
|
||||
.getApiInterface(ctx)
|
||||
.patchIssue(Authorization.get(ctx), repoOwner, repoName, issueIndex, issueData);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@@ -256,17 +188,18 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
if(tinyDb.getString("issueType").equals("pr")) {
|
||||
Toasty.info(getApplicationContext(), getString(R.string.editPrSuccessMessage));
|
||||
if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) {
|
||||
|
||||
Toasty.success(ctx, getString(R.string.editPrSuccessMessage));
|
||||
}
|
||||
else {
|
||||
Toasty.info(getApplicationContext(), getString(R.string.editIssueSuccessMessage));
|
||||
|
||||
Toasty.success(ctx, getString(R.string.editIssueSuccessMessage));
|
||||
}
|
||||
|
||||
tinyDb.putBoolean("issueEdited", true);
|
||||
tinyDb.putBoolean("resumeIssues", true);
|
||||
tinyDB.putBoolean("issueEdited", true);
|
||||
tinyDB.putBoolean("resumeIssues", true);
|
||||
finish();
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
@@ -275,19 +208,17 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.genericError));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -295,7 +226,6 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
@@ -307,31 +237,21 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
final int mDay = c.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
|
||||
new DatePickerDialog.OnDateSetListener() {
|
||||
|
||||
@Override
|
||||
public void onDateSet(DatePicker view, int year,
|
||||
int monthOfYear, int dayOfMonth) {
|
||||
|
||||
editIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth));
|
||||
|
||||
}
|
||||
}, mYear, mMonth, mDay);
|
||||
(view, year, monthOfYear, dayOfMonth) -> editIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay);
|
||||
datePickerDialog.show();
|
||||
|
||||
}
|
||||
else if(v == editIssueButton) {
|
||||
|
||||
processEditIssue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex) {
|
||||
private void getIssue(final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex, int resultLimit) {
|
||||
|
||||
Call<Issues> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
|
||||
.getApiInterface(ctx)
|
||||
.getIssueByIndex(Authorization.get(ctx), repoOwner, repoName, issueIndex);
|
||||
|
||||
call.enqueue(new Callback<Issues>() {
|
||||
|
||||
@@ -344,27 +264,27 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
editIssueTitle.setText(response.body().getTitle());
|
||||
editIssueDescription.setText(response.body().getBody());
|
||||
|
||||
int msId = 0;
|
||||
int currentMilestoneId = 0;
|
||||
if(response.body().getMilestone() != null) {
|
||||
msId = response.body().getMilestone().getId();
|
||||
|
||||
currentMilestoneId = response.body().getMilestone().getId();
|
||||
}
|
||||
|
||||
// get milestones list
|
||||
if(response.body().getId() > 0) {
|
||||
|
||||
Call<List<Milestones>> call_ = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState);
|
||||
.getApiInterface(ctx)
|
||||
.getMilestones(Authorization.get(ctx), repoOwner, repoName, 1, resultLimit, msState);
|
||||
|
||||
final int finalMsId = msId;
|
||||
int checkMilestoneId = currentMilestoneId;
|
||||
|
||||
call_.enqueue(new Callback<List<Milestones>>() {
|
||||
call_.enqueue(new Callback<List<Milestones>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull retrofit2.Response<List<Milestones>> response_) {
|
||||
|
||||
int finalMsId1 = 0;
|
||||
int getSelectedMilestoneId = 0;
|
||||
|
||||
if (response_.code() == 200) {
|
||||
|
||||
@@ -372,39 +292,40 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
|
||||
milestonesList.add(new Milestones(0, "No milestone"));
|
||||
assert milestonesList_ != null;
|
||||
|
||||
if (milestonesList_.size() > 0) {
|
||||
|
||||
milestonesList.addAll(milestonesList_);
|
||||
|
||||
for (int i = 0; i < milestonesList_.size(); i++) {
|
||||
|
||||
Milestones data = new Milestones(
|
||||
milestonesList_.get(i).getId(),
|
||||
milestonesList_.get(i).getTitle()
|
||||
);
|
||||
milestonesList.add(data);
|
||||
|
||||
if(finalMsId == milestonesList_.get(i).getId()) {
|
||||
finalMsId1 = i + 1;
|
||||
if(checkMilestoneId == milestonesList_.get(i).getId()) {
|
||||
getSelectedMilestoneId = i + 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(EditIssueActivity.this,
|
||||
R.layout.spinner_item, milestonesList);
|
||||
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(EditIssueActivity.this,
|
||||
R.layout.list_spinner_items, milestonesList);
|
||||
|
||||
adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
editIssueMilestoneSpinner.setAdapter(adapter_);
|
||||
editIssueMilestoneSpinner.setAdapter(adapter);
|
||||
|
||||
editIssueMilestoneSpinner.setOnItemClickListener ((parent, view, position, id) -> milestoneId = milestonesList.get(position).getId());
|
||||
|
||||
int finalMsId = getSelectedMilestoneId;
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
editIssueMilestoneSpinner.setText(milestonesList.get(finalMsId).getTitle(),false);
|
||||
milestoneId = milestonesList.get(finalMsId).getId();
|
||||
}, 500);
|
||||
|
||||
if(milestonesList_.size() > 0) {
|
||||
editIssueMilestoneSpinner.setSelection(finalMsId1);
|
||||
}
|
||||
enableProcessButton();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
@@ -417,7 +338,6 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
@SuppressLint("SimpleDateFormat") DateFormat formatter = new SimpleDateFormat("yyyy-M-dd");
|
||||
String dueDate = formatter.format(response.body().getDue_date());
|
||||
editIssueDueDate.setText(dueDate);
|
||||
|
||||
}
|
||||
//enableProcessButton();
|
||||
|
||||
@@ -428,18 +348,16 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.genericError));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
}
|
||||
});
|
||||
@@ -449,21 +367,11 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
|
||||
private void disableProcessButton() {
|
||||
|
||||
editIssueButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
editIssueButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
editIssueButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
editIssueButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.FilesDiffAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityFileDiffBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.ParseDiff;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.FileDiffView;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -32,188 +30,117 @@ import retrofit2.Callback;
|
||||
|
||||
public class FileDiffActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView toolbar_title;
|
||||
private RecyclerView mRecyclerView;
|
||||
private ProgressBar mProgressBar;
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView toolbarTitle;
|
||||
private ListView mListView;
|
||||
private ProgressBar mProgressBar;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_file_diff;
|
||||
}
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActivityFileDiffBinding activityFileDiffBinding = ActivityFileDiffBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityFileDiffBinding.getRoot());
|
||||
|
||||
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");
|
||||
Toolbar toolbar = activityFileDiffBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
toolbar_title = findViewById(R.id.toolbar_title);
|
||||
mRecyclerView = findViewById(R.id.recyclerView);
|
||||
mProgressBar = findViewById(R.id.progress_bar);
|
||||
final TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
mRecyclerView.setHasFixedSize(true);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
|
||||
ImageView closeActivity = activityFileDiffBinding.close;
|
||||
toolbarTitle = activityFileDiffBinding.toolbarTitle;
|
||||
mListView = activityFileDiffBinding.listView;
|
||||
mProgressBar = activityFileDiffBinding.progressBar;
|
||||
|
||||
toolbar_title.setText(R.string.processingText);
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
mListView.setDivider(null);
|
||||
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
toolbarTitle.setText(R.string.processingText);
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
String pullIndex = tinyDb.getString("issueNumber");
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
getPullDiffContent(tinyDb.getString("instanceUrlWithProtocol"), repoOwner, repoName, pullIndex);
|
||||
String pullIndex = tinyDb.getString("issueNumber");
|
||||
|
||||
}
|
||||
boolean apiCall = !new Version(tinyDb.getString("giteaVersion")).less("1.13.0");
|
||||
getPullDiffContent(repoOwner, repoName, pullIndex, apiCall);
|
||||
|
||||
private void getPullDiffContent(String instanceUrl, String owner, String repo, String filename) {
|
||||
}
|
||||
|
||||
Call<ResponseBody> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getWebInterface()
|
||||
.getPullDiffContent(owner, repo, filename);
|
||||
private void getPullDiffContent(String owner, String repo, String pullIndex, boolean apiCall) {
|
||||
|
||||
call.enqueue(new Callback<ResponseBody>() {
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
|
||||
Call<ResponseBody> call = apiCall ?
|
||||
RetrofitClient.getApiInterface(ctx).getPullDiffContent(Authorization.get(ctx), owner, repo, pullIndex) :
|
||||
RetrofitClient.getWebInterface(ctx).getPullDiffContent(Authorization.getWeb(ctx), owner, repo, pullIndex);
|
||||
|
||||
if (response.code() == 200) {
|
||||
try {
|
||||
|
||||
try {
|
||||
assert response.body() != null;
|
||||
Response<ResponseBody> response = call.execute();
|
||||
assert response.body() != null;
|
||||
|
||||
AppUtil appUtil = new AppUtil();
|
||||
List<FileDiffView> fileContentsArray = new ArrayList<>();
|
||||
switch(response.code()) {
|
||||
|
||||
String[] lines = response.body().string().split("diff");
|
||||
case 200:
|
||||
List<FileDiffView> fileDiffViews = ParseDiff.getFileDiffViewArray(response.body().string());
|
||||
|
||||
if(lines.length > 0) {
|
||||
int filesCount = fileDiffViews.size();
|
||||
|
||||
for (int i = 1; i < lines.length; i++) {
|
||||
String toolbarTitleText = (filesCount > 1) ?
|
||||
getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount)) :
|
||||
getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount));
|
||||
|
||||
if(lines[i].contains("@@ -")) {
|
||||
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, getSupportFragmentManager(), fileDiffViews);
|
||||
|
||||
String[] level2nd = lines[i].split("@@ -"); // main content part of single diff view
|
||||
runOnUiThread(() -> {
|
||||
toolbarTitle.setText(toolbarTitleText);
|
||||
mListView.setAdapter(adapter);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
});
|
||||
break;
|
||||
|
||||
String[] fileName_ = level2nd[0].split("\\+\\+\\+ b/"); // filename part
|
||||
String fileNameFinal = fileName_[1];
|
||||
case 401:
|
||||
runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(ctx,
|
||||
getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getString(R.string.alertDialogTokenRevokedCopyPositiveButton)));
|
||||
break;
|
||||
|
||||
String[] fileContents_ = level2nd[1].split("@@"); // file info / content part
|
||||
String fileInfoFinal = fileContents_[0];
|
||||
String fileContentsFinal = (fileContents_[1]);
|
||||
case 403:
|
||||
runOnUiThread(() -> Toasty.error(ctx, ctx.getString(R.string.authorizeError)));
|
||||
break;
|
||||
|
||||
if(level2nd.length > 2) {
|
||||
for (int j = 2; j < level2nd.length; j++) {
|
||||
fileContentsFinal += (level2nd[j]);
|
||||
}
|
||||
}
|
||||
case 404:
|
||||
runOnUiThread(() -> Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)));
|
||||
break;
|
||||
|
||||
String fileExtension = FileUtils.getExtension(fileNameFinal);
|
||||
default:
|
||||
runOnUiThread(() -> Toasty.error(ctx, getString(R.string.labelGeneralError)));
|
||||
|
||||
String fileContentsFinalWithBlankLines = fileContentsFinal.replaceAll( ".*@@.*", "" );
|
||||
String fileContentsFinalWithoutBlankLines = fileContentsFinal.replaceAll( ".*@@.*(\r?\n|\r)?", "" );
|
||||
fileContentsFinalWithoutBlankLines = fileContentsFinalWithoutBlankLines.replaceAll( ".*\\ No newline at end of file.*(\r?\n|\r)?", "" );
|
||||
}
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
fileContentsArray.add(new FileDiffView(fileNameFinal, appUtil.imageExtension(fileExtension), fileInfoFinal, fileContentsFinalWithoutBlankLines));
|
||||
}
|
||||
else {
|
||||
});
|
||||
|
||||
String[] getFileName = lines[i].split("--git a/");
|
||||
thread.start();
|
||||
|
||||
String[] getFileName_ = getFileName[1].split("b/");
|
||||
String getFileNameFinal = getFileName_[0].trim();
|
||||
}
|
||||
|
||||
String[] binaryFile = getFileName_[1].split("GIT binary patch");
|
||||
String binaryFileRaw = binaryFile[1].substring(binaryFile[1].indexOf('\n')+1);
|
||||
String binaryFileFinal = binaryFile[1].substring(binaryFileRaw.indexOf('\n')+1);
|
||||
private void initCloseListener() {
|
||||
|
||||
String fileExtension = FileUtils.getExtension(getFileNameFinal);
|
||||
onClickListener = view -> {
|
||||
|
||||
if(appUtil.imageExtension(FileUtils.getExtension(getFileNameFinal))) {
|
||||
|
||||
fileContentsArray.add(new FileDiffView(getFileNameFinal, appUtil.imageExtension(fileExtension), "", binaryFileFinal));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int filesCount = fileContentsArray.size();
|
||||
if(filesCount > 1) {
|
||||
toolbar_title.setText(getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount)));
|
||||
}
|
||||
else {
|
||||
toolbar_title.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount)));
|
||||
}
|
||||
|
||||
FilesDiffAdapter adapter = new FilesDiffAdapter(fileContentsArray, getApplicationContext());
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
AlertDialogs.authorizationTokenRevokedDialog(getApplicationContext(), 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(getApplicationContext(), getApplicationContext().getString(R.string.authorizeError));
|
||||
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getApplicationContext().getString(R.string.apiNotFound));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<ResponseBody> 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();
|
||||
}
|
||||
};
|
||||
}
|
||||
getIntent().removeExtra("singleFileName");
|
||||
finish();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,54 +1,41 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.github.barteksc.pdfviewer.PDFView;
|
||||
import com.github.barteksc.pdfviewer.util.FitPolicy;
|
||||
import com.github.chrisbanes.photoview.PhotoView;
|
||||
import com.pddstudio.highlightjs.HighlightJsView;
|
||||
import com.pddstudio.highlightjs.models.Theme;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.gitnex.tea4j.models.Files;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityFileViewBinding;
|
||||
import org.mian.gitnex.fragments.BottomSheetFileViewerFragment;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Images;
|
||||
import org.mian.gitnex.helpers.Markdown;
|
||||
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 java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import org.mian.gitnex.notifications.Notifications;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Objects;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -56,246 +43,180 @@ import retrofit2.Callback;
|
||||
|
||||
public class FileViewActivity extends BaseActivity implements BottomSheetFileViewerFragment.BottomSheetListener {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView singleFileContents;
|
||||
private LinearLayout singleFileContentsFrame;
|
||||
private LinearLayout highlightJs;
|
||||
//private HighlightJsView singleCodeContents;
|
||||
private PhotoView imageView;
|
||||
final Context ctx = this;
|
||||
private ProgressBar mProgressBar;
|
||||
private byte[] imageData;
|
||||
private PDFView pdfView;
|
||||
private LinearLayout pdfViewFrame;
|
||||
private byte[] decodedPdf;
|
||||
private Boolean pdfNightMode;
|
||||
private static final int PERMISSION_REQUEST_CODE = 1;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId() {
|
||||
|
||||
return R.layout.activity_file_view;
|
||||
}
|
||||
private ActivityFileViewBinding binding;
|
||||
private Files file;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
binding = ActivityFileViewBinding.inflate(getLayoutInflater());
|
||||
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
|
||||
tinyDB.putBoolean("enableMarkdownInFileView", false);
|
||||
|
||||
file = (Files) getIntent().getSerializableExtra("file");
|
||||
|
||||
binding.close.setOnClickListener(view -> finish());
|
||||
|
||||
binding.toolbarTitle.setMovementMethod(new ScrollingMovementMethod());
|
||||
binding.toolbarTitle.setText(file.getPath());
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String repoBranch = tinyDB.getString("repoBranch");
|
||||
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");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
singleFileContents = findViewById(R.id.singleFileContents);
|
||||
highlightJs = findViewById(R.id.highlightJs);
|
||||
//singleCodeContents = findViewById(R.id.singleCodeContents);
|
||||
imageView = findViewById(R.id.imageView);
|
||||
mProgressBar = findViewById(R.id.progress_bar);
|
||||
pdfView = findViewById(R.id.pdfView);
|
||||
pdfViewFrame = findViewById(R.id.pdfViewFrame);
|
||||
singleFileContentsFrame = findViewById(R.id.singleFileContentsFrame);
|
||||
|
||||
String singleFileName = getIntent().getStringExtra("singleFileName");
|
||||
|
||||
TextView toolbar_title = findViewById(R.id.toolbar_title);
|
||||
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
tinyDb.putString("downloadFileContents", "");
|
||||
|
||||
try {
|
||||
|
||||
singleFileName = URLDecoder.decode(singleFileName, "UTF-8");
|
||||
singleFileName = singleFileName.replaceAll("//", "/");
|
||||
singleFileName = singleFileName.startsWith("/") ? singleFileName.substring(1) : singleFileName;
|
||||
|
||||
}
|
||||
catch(UnsupportedEncodingException e) {
|
||||
|
||||
assert singleFileName != null;
|
||||
Log.i("singleFileName", singleFileName);
|
||||
|
||||
}
|
||||
|
||||
toolbar_title.setText(singleFileName);
|
||||
|
||||
getSingleFileContents(instanceUrl, instanceToken, repoOwner, repoName, singleFileName);
|
||||
getSingleFileContents(repoOwner, repoName, file.getPath(), repoBranch);
|
||||
|
||||
}
|
||||
|
||||
private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) {
|
||||
@Override
|
||||
public void onResume() {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
super.onResume();
|
||||
|
||||
Call<Files> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getSingleFileContents(token, owner, repo, filename);
|
||||
if(tinyDB.getBoolean("fileModified")) {
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String repoBranch = tinyDB.getString("repoBranch");
|
||||
String[] parts = repoFullName.split("/");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
call.enqueue(new Callback<Files>() {
|
||||
getSingleFileContents(repoOwner, repoName, file.getPath(), repoBranch);
|
||||
tinyDB.putBoolean("fileModified", false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Files> call, @NonNull retrofit2.Response<Files> response) {
|
||||
private void getSingleFileContents(final String owner, String repo, final String filename, String ref) {
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
Call<ResponseBody> call = RetrofitClient
|
||||
.getWebInterface(ctx)
|
||||
.getFileContents(Authorization.getWeb(ctx), owner, repo, ref, filename);
|
||||
|
||||
try {
|
||||
|
||||
Response<ResponseBody> response = call.execute();
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
AppUtil appUtil = new AppUtil();
|
||||
assert response.body() != null;
|
||||
ResponseBody responseBody = response.body();
|
||||
|
||||
if(!response.body().getContent().equals("")) {
|
||||
if(responseBody != null) {
|
||||
|
||||
runOnUiThread(() -> binding.progressBar.setVisibility(View.GONE));
|
||||
String fileExtension = FileUtils.getExtension(filename);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
|
||||
// download file meta
|
||||
tinyDb.putString("downloadFileName", filename);
|
||||
tinyDb.putString("downloadFileContents", response.body().getContent());
|
||||
boolean processable = false;
|
||||
|
||||
if(appUtil.imageExtension(fileExtension)) { // file is image
|
||||
switch(AppUtil.getFileType(fileExtension)) {
|
||||
|
||||
singleFileContentsFrame.setVisibility(View.GONE);
|
||||
highlightJs.setVisibility(View.GONE);
|
||||
//singleCodeContents.setVisibility(View.GONE);
|
||||
pdfViewFrame.setVisibility(View.GONE);
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
case IMAGE:
|
||||
|
||||
imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT);
|
||||
Drawable imageDrawable = new BitmapDrawable(getResources(), BitmapFactory.decodeByteArray(imageData, 0, imageData.length));
|
||||
imageView.setImageDrawable(imageDrawable);
|
||||
// See https://developer.android.com/guide/topics/media/media-formats#core
|
||||
if(Arrays.asList("bmp", "gif", "jpg", "jpeg", "png", "webp", "heic", "heif").contains(fileExtension.toLowerCase())) {
|
||||
|
||||
}
|
||||
else if(appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode
|
||||
processable = true;
|
||||
|
||||
pdfViewFrame.setVisibility(View.GONE);
|
||||
imageView.setVisibility(View.GONE);
|
||||
byte[] pictureBytes = responseBody.bytes();
|
||||
|
||||
if(Build.VERSION.SDK_INT > 23) {
|
||||
runOnUiThread(() -> {
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
|
||||
highlightJs.setVisibility(View.VISIBLE);
|
||||
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
assert inflater != null;
|
||||
@SuppressLint("InflateParams") View mView = inflater.inflate(R.layout.custom_highlightjs, null);
|
||||
HighlightJsView singleCodeContents = mView.findViewById(R.id.singleCodeContents);
|
||||
highlightJs.addView(mView);
|
||||
binding.photoView.setVisibility(View.VISIBLE);
|
||||
binding.photoView.setImageBitmap(Images.scaleImage(pictureBytes, 1920));
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
singleFileContentsFrame.setVisibility(View.GONE);
|
||||
singleCodeContents.setVisibility(View.VISIBLE);
|
||||
case UNKNOWN:
|
||||
case TEXT:
|
||||
|
||||
switch(tinyDb.getInt("fileviewerSourceCodeThemeId")) {
|
||||
case 1:
|
||||
singleCodeContents.setTheme(Theme.ARDUINO_LIGHT);
|
||||
break;
|
||||
case 2:
|
||||
singleCodeContents.setTheme(Theme.GITHUB);
|
||||
break;
|
||||
case 3:
|
||||
singleCodeContents.setTheme(Theme.FAR);
|
||||
break;
|
||||
case 4:
|
||||
singleCodeContents.setTheme(Theme.IR_BLACK);
|
||||
break;
|
||||
case 5:
|
||||
singleCodeContents.setTheme(Theme.ANDROID_STUDIO);
|
||||
break;
|
||||
default:
|
||||
singleCodeContents.setTheme(Theme.MONOKAI_SUBLIME);
|
||||
if(file.getSize() > Constants.maximumFileViewerSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
singleCodeContents.setShowLineNumbers(true);
|
||||
singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent()));
|
||||
processable = true;
|
||||
String text = responseBody.string();
|
||||
|
||||
}
|
||||
else {
|
||||
runOnUiThread(() -> {
|
||||
binding.photoView.setVisibility(View.GONE);
|
||||
|
||||
singleFileContents.setVisibility(View.VISIBLE);
|
||||
singleFileContents.setText(appUtil.decodeBase64(response.body().getContent()));
|
||||
binding.contents.setContent(text, fileExtension);
|
||||
|
||||
}
|
||||
if(tinyDB.getBoolean("enableMarkdownInFileView")) {
|
||||
Markdown.render(ctx, EmojiParser.parseToUnicode(text), binding.markdown);
|
||||
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
}
|
||||
else if(appUtil.pdfExtension(fileExtension)) { // file is pdf
|
||||
|
||||
imageView.setVisibility(View.GONE);
|
||||
singleFileContentsFrame.setVisibility(View.GONE);
|
||||
highlightJs.setVisibility(View.GONE);
|
||||
//singleCodeContents.setVisibility(View.GONE);
|
||||
pdfViewFrame.setVisibility(View.VISIBLE);
|
||||
if(!processable) { // While the file could still be non-binary,
|
||||
// it's better we don't show it (to prevent any crashes and/or unwanted behavior) and let the user download it instead.
|
||||
responseBody.close();
|
||||
|
||||
pdfNightMode = tinyDb.getBoolean("enablePdfMode");
|
||||
|
||||
decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT);
|
||||
pdfView.fromBytes(decodedPdf).enableSwipe(true).swipeHorizontal(false).enableDoubletap(true).defaultPage(0).enableAnnotationRendering(false).password(null).scrollHandle(null).enableAntialiasing(true).spacing(0).autoSpacing(true).pageFitPolicy(FitPolicy.WIDTH).fitEachPage(true).pageSnap(false).pageFling(true).nightMode(pdfNightMode).load();
|
||||
runOnUiThread(() -> {
|
||||
binding.photoView.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
|
||||
binding.markdownFrame.setVisibility(View.VISIBLE);
|
||||
binding.markdown.setText(getString(R.string.excludeFilesInFileViewer));
|
||||
binding.markdown.setGravity(Gravity.CENTER);
|
||||
binding.markdown.setTypeface(null, Typeface.BOLD);
|
||||
});
|
||||
}
|
||||
else if(appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded
|
||||
} else {
|
||||
|
||||
imageView.setVisibility(View.GONE);
|
||||
highlightJs.setVisibility(View.GONE);
|
||||
//singleCodeContents.setVisibility(View.GONE);
|
||||
pdfViewFrame.setVisibility(View.GONE);
|
||||
singleFileContentsFrame.setVisibility(View.VISIBLE);
|
||||
runOnUiThread(() -> {
|
||||
binding.markdown.setText("");
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
||||
singleFileContents.setText(getResources().getString(R.string.excludeFilesInFileviewer));
|
||||
singleFileContents.setGravity(Gravity.CENTER);
|
||||
singleFileContents.setTypeface(null, Typeface.BOLD);
|
||||
switch(response.code()) {
|
||||
|
||||
}
|
||||
else { // file type not known - plain text view
|
||||
case 401:
|
||||
runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(ctx,
|
||||
getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)));
|
||||
break;
|
||||
|
||||
imageView.setVisibility(View.GONE);
|
||||
highlightJs.setVisibility(View.GONE);
|
||||
//singleCodeContents.setVisibility(View.GONE);
|
||||
pdfViewFrame.setVisibility(View.GONE);
|
||||
singleFileContentsFrame.setVisibility(View.VISIBLE);
|
||||
case 403:
|
||||
runOnUiThread(() -> Toasty.error(ctx, ctx.getString(R.string.authorizeError)));
|
||||
break;
|
||||
|
||||
singleFileContents.setText(appUtil.decodeBase64(response.body().getContent()));
|
||||
case 404:
|
||||
runOnUiThread(() -> Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)));
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
runOnUiThread(() -> Toasty.error(ctx, getString(R.string.labelGeneralError)));
|
||||
|
||||
}
|
||||
else {
|
||||
singleFileContents.setText("");
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
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());
|
||||
}
|
||||
});
|
||||
|
||||
thread.start();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -303,6 +224,15 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
|
||||
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
|
||||
inflater.inflate(R.menu.files_view_menu, menu);
|
||||
|
||||
if(!FileUtils.getExtension(file.getName())
|
||||
.equalsIgnoreCase("md")) {
|
||||
|
||||
menu.getItem(0)
|
||||
.setVisible(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -311,112 +241,158 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
switch(id) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
case R.id.genericMenu:
|
||||
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet");
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
if(id == android.R.id.home) {
|
||||
|
||||
finish();
|
||||
return true;
|
||||
|
||||
} else if(id == R.id.genericMenu) {
|
||||
|
||||
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet");
|
||||
return true;
|
||||
|
||||
} else if(id == R.id.markdown) {
|
||||
|
||||
if(!tinyDB.getBoolean("enableMarkdownInFileView")) {
|
||||
Markdown.render(ctx, EmojiParser.parseToUnicode(binding.contents.getContent()), binding.markdown);
|
||||
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.VISIBLE);
|
||||
|
||||
tinyDB.putBoolean("enableMarkdownInFileView", true);
|
||||
} else {
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.VISIBLE);
|
||||
|
||||
tinyDB.putBoolean("enableMarkdownInFileView", false);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClicked(String text) {
|
||||
|
||||
switch(text) {
|
||||
case "downloadFile":
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 23) {
|
||||
if(checkPermission()) {
|
||||
requestFileDownload();
|
||||
}
|
||||
else {
|
||||
requestPermission();
|
||||
}
|
||||
}
|
||||
else {
|
||||
requestFileDownload();
|
||||
}
|
||||
break;
|
||||
|
||||
if("downloadFile".equals(text)) {
|
||||
requestFileDownload();
|
||||
}
|
||||
|
||||
if("deleteFile".equals(text)) {
|
||||
Intent intent = new Intent(ctx, CreateFileActivity.class);
|
||||
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_DELETE);
|
||||
intent.putExtra("filePath", file.getPath());
|
||||
intent.putExtra("fileSha", file.getSha());
|
||||
|
||||
ctx.startActivity(intent);
|
||||
}
|
||||
|
||||
if("editFile".equals(text)) {
|
||||
|
||||
if(binding.contents.getContent() != null &&
|
||||
!binding.contents.getContent().isEmpty()) {
|
||||
|
||||
Intent intent = new Intent(ctx, CreateFileActivity.class);
|
||||
|
||||
intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_EDIT);
|
||||
intent.putExtra("filePath", file.getPath());
|
||||
intent.putExtra("fileSha", file.getSha());
|
||||
intent.putExtra("fileContents", binding.contents.getContent());
|
||||
|
||||
ctx.startActivity(intent);
|
||||
|
||||
} else {
|
||||
Toasty.error(ctx, getString(R.string.fileTypeCannotBeEdited));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void requestFileDownload() {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
|
||||
if(!tinyDb.getString("downloadFileContents").isEmpty()) {
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.putExtra(Intent.EXTRA_TITLE, file.getName());
|
||||
intent.setType("*/*");
|
||||
|
||||
File outputFileName = new File(tinyDb.getString("downloadFileName"));
|
||||
final File downloadFilePath = new File(Environment.getExternalStorageDirectory().getPath() + "/Download/" + outputFileName.getName());
|
||||
activityResultLauncher.launch(intent);
|
||||
|
||||
byte[] pdfAsBytes = Base64.decode(tinyDb.getString("downloadFileContents"), 0);
|
||||
FileOutputStream fileOutputStream = null;
|
||||
}
|
||||
|
||||
ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
||||
|
||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||
|
||||
assert result.getData() != null;
|
||||
|
||||
try {
|
||||
|
||||
fileOutputStream = new FileOutputStream(downloadFilePath, false);
|
||||
Objects.requireNonNull(fileOutputStream).write(pdfAsBytes);
|
||||
fileOutputStream.flush();
|
||||
fileOutputStream.close();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.downloadFileSaved));
|
||||
OutputStream outputStream = getContentResolver().openOutputStream(result.getData().getData());
|
||||
|
||||
}
|
||||
catch(IOException e) {
|
||||
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
|
||||
}
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, ctx.getPackageName())
|
||||
.setContentTitle(getString(R.string.fileViewerNotificationTitleStarted))
|
||||
.setContentText(getString(R.string.fileViewerNotificationDescriptionStarted, file.getName()))
|
||||
.setSmallIcon(R.drawable.gitnex_transparent)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setChannelId(Constants.downloadNotificationChannelId)
|
||||
.setProgress(100, 0, false)
|
||||
.setOngoing(true);
|
||||
|
||||
}
|
||||
else {
|
||||
Toasty.error(getApplicationContext(), getString(R.string.waitLoadingDownloadFile));
|
||||
int notificationId = Notifications.uniqueNotificationId(ctx);
|
||||
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);;
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String repoBranch = tinyDB.getString("repoBranch");
|
||||
String[] parts = repoFullName.split("/");
|
||||
String repoOwner = parts[0];
|
||||
String repoName = parts[1];
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
try {
|
||||
|
||||
Call<ResponseBody> call = RetrofitClient
|
||||
.getWebInterface(ctx)
|
||||
.getFileContents(Authorization.getWeb(ctx), repoOwner, repoName, repoBranch, file.getPath());
|
||||
|
||||
Response<ResponseBody> response = call.execute();
|
||||
|
||||
assert response.body() != null;
|
||||
|
||||
AppUtil.copyProgress(response.body().byteStream(), outputStream, file.getSize(), progress -> {
|
||||
builder.setProgress(100, progress, false);
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
});
|
||||
|
||||
builder.setContentTitle(getString(R.string.fileViewerNotificationTitleFinished))
|
||||
.setContentText(getString(R.string.fileViewerNotificationDescriptionFinished, file.getName()));
|
||||
|
||||
} catch(IOException ignored) {
|
||||
|
||||
builder.setContentTitle(getString(R.string.fileViewerNotificationTitleFailed))
|
||||
.setContentText(getString(R.string.fileViewerNotificationDescriptionFailed, file.getName()));
|
||||
|
||||
} finally {
|
||||
|
||||
builder.setProgress(0,0,false)
|
||||
.setOngoing(false);
|
||||
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
thread.start();
|
||||
|
||||
} catch(IOException ignored) {}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
private boolean checkPermission() {
|
||||
|
||||
int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
return result == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
private void requestPermission() {
|
||||
|
||||
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
|
||||
switch(requestCode) {
|
||||
case PERMISSION_REQUEST_CODE:
|
||||
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.i("PermissionsCheck", "Permission Granted");
|
||||
}
|
||||
else {
|
||||
Log.e("PermissionsCheck", "Permission Denied");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
getIntent().removeExtra("singleFileName");
|
||||
finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,39 +2,28 @@ package org.mian.gitnex.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.hendraanggrian.appcompat.socialview.Mention;
|
||||
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
|
||||
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.gitnex.tea4j.models.MergePullRequest;
|
||||
import org.gitnex.tea4j.models.MergePullRequestSpinner;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.PullRequestActions;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityMergePullRequestBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.VersionCheck;
|
||||
import org.mian.gitnex.models.Collaborators;
|
||||
import org.mian.gitnex.models.MergePullRequest;
|
||||
import org.mian.gitnex.models.MergePullRequestSpinner;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import okhttp3.ResponseBody;
|
||||
import java.util.Objects;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -42,159 +31,107 @@ import retrofit2.Response;
|
||||
|
||||
public class MergePullRequestActivity extends BaseActivity {
|
||||
|
||||
public ImageView closeActivity;
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
final Context ctx = this;
|
||||
private String repoOwner;
|
||||
private String repoName;
|
||||
private int prIndex;
|
||||
|
||||
private ActivityMergePullRequestBinding viewBinding;
|
||||
|
||||
private SocialAutoCompleteTextView mergeDescription;
|
||||
private EditText mergeTitle;
|
||||
private Spinner mergeModeSpinner;
|
||||
private ArrayAdapter<Mention> defaultMentionAdapter;
|
||||
private Button mergeButton;
|
||||
private String Do;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId() {
|
||||
|
||||
return R.layout.activity_merge_pull_request;
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
viewBinding = ActivityMergePullRequestBinding.inflate(getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
repoOwner = parts[0];
|
||||
repoName = parts[1];
|
||||
prIndex = Integer.parseInt(tinyDB.getString("issueNumber"));
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
mergeModeSpinner = findViewById(R.id.mergeSpinner);
|
||||
mergeDescription = findViewById(R.id.mergeDescription);
|
||||
mergeTitle = findViewById(R.id.mergeTitle);
|
||||
|
||||
mergeTitle.requestFocus();
|
||||
viewBinding.mergeTitle.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(mergeTitle, InputMethodManager.SHOW_IMPLICIT);
|
||||
imm.showSoftInput(viewBinding.mergeTitle, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
setMergeAdapter();
|
||||
|
||||
mergeModeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
if(!tinyDB.getString("issueTitle").isEmpty()) {
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
|
||||
MergePullRequestSpinner mergeId = (MergePullRequestSpinner) parent.getSelectedItem();
|
||||
Do = mergeId.getId();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
defaultMentionAdapter = new MentionArrayAdapter<>(this);
|
||||
loadCollaboratorsList();
|
||||
|
||||
mergeDescription.setMentionAdapter(defaultMentionAdapter);
|
||||
|
||||
closeActivity = findViewById(R.id.close);
|
||||
TextView toolbar_title = findViewById(R.id.toolbar_title);
|
||||
|
||||
if(!tinyDb.getString("issueTitle").isEmpty()) {
|
||||
toolbar_title.setText(tinyDb.getString("issueTitle"));
|
||||
mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber")+ ")");
|
||||
viewBinding.toolbarTitle.setText(tinyDB.getString("issueTitle"));
|
||||
viewBinding.mergeTitle.setText(tinyDB.getString("issueTitle") + " (#" + tinyDB.getString("issueNumber") + ")");
|
||||
}
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
viewBinding.close.setOnClickListener(onClickListener);
|
||||
|
||||
mergeButton = findViewById(R.id.mergeButton);
|
||||
// if gitea version is greater/equal(1.12.0) than user installed version (installed.higherOrEqual(compareVer))
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
|
||||
viewBinding.deleteBranch.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if(tinyDB.getString("prMergeable").equals("false")) {
|
||||
|
||||
disableProcessButton();
|
||||
viewBinding.mergeInfoDisabledMessage.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
|
||||
viewBinding.mergeInfoDisabledMessage.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(tinyDB.getString("prIsFork").equals("true")) {
|
||||
|
||||
viewBinding.deleteBranchForkInfo.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
|
||||
viewBinding.deleteBranchForkInfo.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
mergeButton.setOnClickListener(mergePullRequest);
|
||||
|
||||
viewBinding.mergeButton.setOnClickListener(mergePullRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setMergeAdapter() {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
ArrayList<MergePullRequestSpinner> mergeList = new ArrayList<>();
|
||||
|
||||
mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge)));
|
||||
mergeList.add(new MergePullRequestSpinner("rebase", getResources().getString(R.string.mergeOptionRebase)));
|
||||
mergeList.add(new MergePullRequestSpinner("rebase-merge", getResources().getString(R.string.mergeOptionRebaseCommit)));
|
||||
//squash merge works only on gitea v1.11.5 and higher due to a bug
|
||||
if(VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) {
|
||||
// squash merge works only on gitea > v1.11.4 due to a bug
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higher("1.11.4")) {
|
||||
|
||||
mergeList.add(new MergePullRequestSpinner("squash", getResources().getString(R.string.mergeOptionSquash)));
|
||||
}
|
||||
|
||||
ArrayAdapter<MergePullRequestSpinner> adapter = new ArrayAdapter<>(MergePullRequestActivity.this, R.layout.spinner_item, mergeList);
|
||||
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
mergeModeSpinner.setAdapter(adapter);
|
||||
ArrayAdapter<MergePullRequestSpinner> adapter = new ArrayAdapter<>(MergePullRequestActivity.this, R.layout.list_spinner_items, mergeList);
|
||||
viewBinding.mergeSpinner.setAdapter(adapter);
|
||||
|
||||
}
|
||||
|
||||
public void loadCollaboratorsList() {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
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<List<Collaborators>> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Collaborators>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
String fullName = "";
|
||||
for(int i = 0; i < response.body().size(); i++) {
|
||||
if(!response.body().get(i).getFull_name().equals("")) {
|
||||
fullName = response.body().get(i).getFull_name();
|
||||
}
|
||||
defaultMentionAdapter.add(new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Log.i("onResponse", String.valueOf(response.code()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.i("onFailure", t.toString());
|
||||
}
|
||||
viewBinding.mergeSpinner.setOnItemClickListener ((parent, view, position, id) -> {
|
||||
|
||||
Do = mergeList.get(position).getId();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
@@ -202,80 +139,112 @@ public class MergePullRequestActivity extends BaseActivity {
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private View.OnClickListener mergePullRequest = v -> processMergePullRequest();
|
||||
private final View.OnClickListener mergePullRequest = v -> processMergePullRequest();
|
||||
|
||||
private void processMergePullRequest() {
|
||||
|
||||
String mergePRDesc = mergeDescription.getText().toString();
|
||||
String mergePRTitle = mergeTitle.getText().toString();
|
||||
String mergePRDesc = Objects.requireNonNull(viewBinding.mergeDescription.getText()).toString();
|
||||
String mergePRTitle = Objects.requireNonNull(viewBinding.mergeTitle.getText()).toString();
|
||||
boolean deleteBranch = viewBinding.deleteBranch.isChecked();
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
disableProcessButton();
|
||||
mergeFunction(Do, mergePRDesc, mergePRTitle);
|
||||
if(Do == null) {
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.selectMergeStrategy));
|
||||
}
|
||||
else {
|
||||
|
||||
disableProcessButton();
|
||||
mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch);
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeFunction(String Do, String mergePRDT, String mergeTitle) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
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];
|
||||
final int prIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
|
||||
private void mergeFunction(String Do, String mergePRDT, String mergeTitle, boolean deleteBranch) {
|
||||
|
||||
MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle);
|
||||
|
||||
Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().mergePullRequest(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR);
|
||||
Call<Void> call = RetrofitClient.getApiInterface(ctx).mergePullRequest(Authorization.get(ctx), repoOwner, repoName, prIndex, mergePR);
|
||||
|
||||
call.enqueue(new Callback<ResponseBody>() {
|
||||
call.enqueue(new Callback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
|
||||
|
||||
if(response.code() == 200) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.mergePRSuccessMsg));
|
||||
tinyDb.putBoolean("prMerged", true);
|
||||
tinyDb.putBoolean("resumePullRequests", true);
|
||||
finish();
|
||||
if(deleteBranch) {
|
||||
|
||||
if(tinyDB.getString("prIsFork").equals("true")) {
|
||||
|
||||
String repoFullName = tinyDB.getString("prForkFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
PullRequestActions.deleteHeadBranch(ctx, repoOwner, repoName, tinyDB.getString("prHeadBranch"), false);
|
||||
|
||||
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg));
|
||||
tinyDB.putBoolean("prMerged", true);
|
||||
tinyDB.putBoolean("resumePullRequests", true);
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
PullRequestActions.deleteHeadBranch(ctx, repoOwner, repoName, tinyDB.getString("prHeadBranch"), false);
|
||||
|
||||
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg));
|
||||
tinyDB.putBoolean("prMerged", true);
|
||||
tinyDB.putBoolean("resumePullRequests", true);
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg));
|
||||
tinyDB.putBoolean("prMerged", true);
|
||||
tinyDB.putBoolean("resumePullRequests", true);
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
enableProcessButton();
|
||||
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() == 404) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.mergePR404ErrorMsg));
|
||||
Toasty.warning(ctx, getString(R.string.mergePR404ErrorMsg));
|
||||
}
|
||||
else if(response.code() == 405) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.warning(ctx, getString(R.string.mergeNotAllowed));;
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.genericError));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
@@ -287,22 +256,12 @@ public class MergePullRequestActivity extends BaseActivity {
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
mergeButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius(8);
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
mergeButton.setBackground(shape);
|
||||
|
||||
viewBinding.mergeButton.setEnabled(false);
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
mergeButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius(8);
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
mergeButton.setBackground(shape);
|
||||
|
||||
viewBinding.mergeButton.setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
@@ -13,46 +9,48 @@ import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.gitnex.tea4j.models.AddEmail;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityProfileEmailBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.AddEmail;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class ProfileEmailActivity extends BaseActivity {
|
||||
public class MyProfileEmailActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private EditText userEmail;
|
||||
final Context ctx = this;
|
||||
private Button addEmailButton;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_profile_email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
ActivityProfileEmailBinding activityProfileEmailBinding = ActivityProfileEmailBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityProfileEmailBinding.getRoot());
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
userEmail = findViewById(R.id.userEmail);
|
||||
addEmailButton = findViewById(R.id.addEmailButton);
|
||||
ImageView closeActivity = activityProfileEmailBinding.close;
|
||||
userEmail = activityProfileEmailBinding.userEmail;
|
||||
addEmailButton = activityProfileEmailBinding.addEmailButton;
|
||||
|
||||
userEmail.requestFocus();
|
||||
assert imm != null;
|
||||
@@ -64,68 +62,53 @@ public class ProfileEmailActivity extends BaseActivity {
|
||||
if(!connToInternet) {
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
} else {
|
||||
|
||||
addEmailButton.setOnClickListener(addEmailListener);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private View.OnClickListener addEmailListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processAddNewEmail();
|
||||
}
|
||||
};
|
||||
private final View.OnClickListener addEmailListener = v -> processAddNewEmail();
|
||||
|
||||
private void processAddNewEmail() {
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
String newUserEmail = userEmail.getText().toString().trim();
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(newUserEmail.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.emailErrorEmpty));
|
||||
Toasty.error(ctx, getString(R.string.emailErrorEmpty));
|
||||
return;
|
||||
|
||||
}
|
||||
else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.emailErrorInvalid));
|
||||
Toasty.warning(ctx, getString(R.string.emailErrorInvalid));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
List<String> newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(",")));
|
||||
|
||||
disableProcessButton();
|
||||
addNewEmail(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newEmailList);
|
||||
|
||||
addNewEmail(Authorization.get(ctx), newEmailList);
|
||||
}
|
||||
|
||||
private void addNewEmail(final String instanceUrl, final String token, List<String> newUserEmail) {
|
||||
private void addNewEmail(final String token, List<String> newUserEmail) {
|
||||
|
||||
AddEmail addEmailFunc = new AddEmail(newUserEmail);
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
|
||||
Call<JsonElement> call;
|
||||
|
||||
call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getApiInterface(appCtx)
|
||||
.addNewEmail(token, addEmailFunc);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
@@ -135,11 +118,10 @@ public class ProfileEmailActivity extends BaseActivity {
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.emailAddedText));
|
||||
Toasty.success(ctx, getString(R.string.emailAddedText));
|
||||
tinyDb.putBoolean("emailsRefresh", true);
|
||||
enableProcessButton();
|
||||
finish();
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
@@ -148,37 +130,32 @@ public class ProfileEmailActivity extends BaseActivity {
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else if(response.code() == 403) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
|
||||
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
}
|
||||
else if(response.code() == 422) {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(ctx, ctx.getString(R.string.emailErrorInUse));
|
||||
|
||||
Toasty.warning(ctx, ctx.getString(R.string.emailErrorInUse));
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
|
||||
|
||||
Toasty.error(ctx, getString(R.string.labelGeneralError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
@@ -187,32 +164,18 @@ public class ProfileEmailActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
addEmailButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
addEmailButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
addEmailButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
addEmailButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.helpers.PathsHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import io.mikael.urlbuilder.UrlBuilder;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -12,24 +19,37 @@ import org.mian.gitnex.util.TinyDB;
|
||||
|
||||
public class OpenRepoInBrowserActivity extends AppCompatActivity {
|
||||
|
||||
private Context appCtx;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw");
|
||||
if (!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) {
|
||||
instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol");
|
||||
}
|
||||
appCtx = getApplicationContext();
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
|
||||
String repoFullNameBrowser = getIntent().getStringExtra("repoFullNameBrowser");
|
||||
Uri url = Uri.parse(instanceUrlWithProtocol + "/" + repoFullNameBrowser);
|
||||
Intent i = new Intent(Intent.ACTION_VIEW, url);
|
||||
startActivity(i);
|
||||
finish();
|
||||
try {
|
||||
|
||||
URI instanceUrl = new URI(UrlBuilder.fromString(tinyDb.getString("instanceUrl"))
|
||||
.withPath("/")
|
||||
.toString());
|
||||
|
||||
String browserPath = PathsHelper.join(instanceUrl.getPath(), getIntent().getStringExtra("repoFullNameBrowser"));
|
||||
|
||||
String browserUrl = UrlBuilder.fromUri(instanceUrl)
|
||||
.withPath(browserPath)
|
||||
.toString();
|
||||
|
||||
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(browserUrl));
|
||||
startActivity(i);
|
||||
finish();
|
||||
|
||||
}
|
||||
catch(URISyntaxException e) {
|
||||
|
||||
Toasty.error(appCtx, getString(R.string.genericError));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
@@ -16,14 +12,23 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.fragments.MembersByOrgFragment;
|
||||
import org.mian.gitnex.fragments.BottomSheetOrganizationFragment;
|
||||
import org.mian.gitnex.fragments.MembersByOrgFragment;
|
||||
import org.mian.gitnex.fragments.OrganizationInfoFragment;
|
||||
import org.mian.gitnex.fragments.OrganizationLabelsFragment;
|
||||
import org.mian.gitnex.fragments.RepositoriesByOrgFragment;
|
||||
import org.mian.gitnex.fragments.TeamsByOrgFragment;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.Objects;
|
||||
import io.mikael.urlbuilder.UrlBuilder;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -31,20 +36,17 @@ import java.util.Objects;
|
||||
|
||||
public class OrganizationDetailActivity extends BaseActivity implements BottomSheetOrganizationFragment.BottomSheetListener {
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_org_detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
String orgName = tinyDb.getString("orgName");
|
||||
setContentView(R.layout.activity_org_detail);
|
||||
|
||||
String orgName = tinyDB.getString("orgName");
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
|
||||
TextView toolbarTitle = findViewById(R.id.toolbar_title);
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
Objects.requireNonNull(getSupportActionBar()).setTitle(orgName);
|
||||
@@ -59,20 +61,20 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
|
||||
|
||||
Typeface myTypeface;
|
||||
|
||||
switch(tinyDb.getInt("customFontId", -1)) {
|
||||
switch(tinyDB.getInt("customFontId", -1)) {
|
||||
|
||||
case 0:
|
||||
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/roboto.ttf");
|
||||
break;
|
||||
|
||||
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
|
||||
break;
|
||||
case 2:
|
||||
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/sourcecodeproregular.ttf");
|
||||
break;
|
||||
|
||||
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
|
||||
break;
|
||||
default:
|
||||
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/manroperegular.ttf");
|
||||
break;
|
||||
|
||||
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf");
|
||||
break;
|
||||
}
|
||||
|
||||
toolbarTitle.setTypeface(myTypeface);
|
||||
@@ -80,12 +82,18 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
|
||||
|
||||
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
|
||||
int tabsCount = vg.getChildCount();
|
||||
|
||||
for (int j = 0; j < tabsCount; j++) {
|
||||
|
||||
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
|
||||
int tabChildCount = vgTab.getChildCount();
|
||||
|
||||
for (int i = 0; i < tabChildCount; i++) {
|
||||
|
||||
View tabViewChild = vgTab.getChildAt(i);
|
||||
|
||||
if (tabViewChild instanceof TextView) {
|
||||
|
||||
((TextView) tabViewChild).setTypeface(myTypeface);
|
||||
}
|
||||
}
|
||||
@@ -93,12 +101,12 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
|
||||
|
||||
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
|
||||
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.repo_dotted_menu, menu);
|
||||
return true;
|
||||
@@ -109,36 +117,55 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
case R.id.repoMenu:
|
||||
BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet");
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
if(id == android.R.id.home) {
|
||||
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.repoMenu) {
|
||||
|
||||
BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClicked(String text) {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
switch (text) {
|
||||
case "repository":
|
||||
tinyDb.putBoolean("organizationAction", true);
|
||||
|
||||
tinyDB.putBoolean("organizationAction", true);
|
||||
startActivity(new Intent(OrganizationDetailActivity.this, CreateRepoActivity.class));
|
||||
break;
|
||||
case "label":
|
||||
|
||||
Intent intent = new Intent(ctx, CreateLabelActivity.class);
|
||||
intent.putExtra("orgName", getIntent().getStringExtra("orgName"));
|
||||
intent.putExtra("type", "org");
|
||||
ctx.startActivity(intent);
|
||||
break;
|
||||
case "team":
|
||||
|
||||
startActivity(new Intent(OrganizationDetailActivity.this, CreateTeamByOrgActivity.class));
|
||||
break;
|
||||
}
|
||||
//Log.i("clicked", text);
|
||||
case "copyOrgUrl":
|
||||
|
||||
String url = UrlBuilder.fromString(tinyDB.getString("instanceUrl"))
|
||||
.withPath("/")
|
||||
.toString();
|
||||
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("orgUrl", url + tinyDB.getString("orgName"));
|
||||
assert clipboard != null;
|
||||
clipboard.setPrimaryClip(clip);
|
||||
Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public class SectionsPagerAdapter extends FragmentPagerAdapter {
|
||||
@@ -151,33 +178,41 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
String orgName;
|
||||
if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) {
|
||||
|
||||
orgName = getIntent().getStringExtra("orgName");
|
||||
}
|
||||
else {
|
||||
orgName = tinyDb.getString("orgName");
|
||||
|
||||
orgName = tinyDB.getString("orgName");
|
||||
}
|
||||
|
||||
Fragment fragment = null;
|
||||
switch (position) {
|
||||
|
||||
case 0: // info
|
||||
|
||||
return OrganizationInfoFragment.newInstance(orgName);
|
||||
case 1: // repos
|
||||
return RepositoriesByOrgFragment.newInstance(orgName);
|
||||
case 2: // teams
|
||||
|
||||
return RepositoriesByOrgFragment.newInstance(orgName);
|
||||
case 2: // labels
|
||||
|
||||
return OrganizationLabelsFragment.newInstance(orgName);
|
||||
case 3: // teams
|
||||
|
||||
return TeamsByOrgFragment.newInstance(orgName);
|
||||
case 3: // members
|
||||
case 4: // members
|
||||
|
||||
return MembersByOrgFragment.newInstance(orgName);
|
||||
}
|
||||
return fragment;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,106 +1,161 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.TeamMembersByOrgAdapter;
|
||||
import org.mian.gitnex.databinding.ActivityOrgTeamMembersBinding;
|
||||
import org.mian.gitnex.fragments.BottomSheetOrganizationTeamsFragment;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.models.UserInfo;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.viewmodels.TeamMembersByOrgViewModel;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class OrganizationTeamMembersActivity extends BaseActivity {
|
||||
public class OrganizationTeamMembersActivity extends BaseActivity implements BottomSheetOrganizationTeamsFragment.BottomSheetListener {
|
||||
|
||||
private TextView noDataMembers;
|
||||
private View.OnClickListener onClickListener;
|
||||
private TeamMembersByOrgAdapter adapter;
|
||||
private GridView mGridView;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_org_team_members;
|
||||
}
|
||||
private String teamId;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
ActivityOrgTeamMembersBinding activityOrgTeamMembersBinding = ActivityOrgTeamMembersBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityOrgTeamMembersBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
TextView toolbarTitle = findViewById(R.id.toolbar_title);
|
||||
noDataMembers = findViewById(R.id.noDataMembers);
|
||||
mGridView = findViewById(R.id.gridView);
|
||||
Toolbar toolbar = activityOrgTeamMembersBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ImageView closeActivity = activityOrgTeamMembersBinding.close;
|
||||
TextView toolbarTitle = activityOrgTeamMembersBinding.toolbarTitle;
|
||||
noDataMembers = activityOrgTeamMembersBinding.noDataMembers;
|
||||
mGridView = activityOrgTeamMembersBinding.gridView;
|
||||
progressBar = activityOrgTeamMembersBinding.progressBar;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
if(getIntent().getStringExtra("teamTitle") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamTitle")).equals("")) {
|
||||
toolbarTitle.setText(getIntent().getStringExtra("teamTitle"));
|
||||
|
||||
toolbarTitle.setText(getIntent().getStringExtra("teamTitle"));
|
||||
}
|
||||
else {
|
||||
toolbarTitle.setText(R.string.orgTeamMembers);
|
||||
|
||||
toolbarTitle.setText(R.string.orgTeamMembers);
|
||||
}
|
||||
|
||||
String teamId;
|
||||
if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")){
|
||||
teamId = getIntent().getStringExtra("teamId");
|
||||
|
||||
teamId = getIntent().getStringExtra("teamId");
|
||||
}
|
||||
else {
|
||||
teamId = "0";
|
||||
}
|
||||
|
||||
getIntent().getStringExtra("teamId");
|
||||
//Log.i("teamId", getIntent().getStringExtra("teamId"));
|
||||
teamId = "0";
|
||||
}
|
||||
|
||||
assert teamId != null;
|
||||
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), Integer.valueOf(teamId));
|
||||
|
||||
fetchDataAsync(Authorization.get(ctx), Integer.parseInt(teamId));
|
||||
}
|
||||
|
||||
private void fetchDataAsync(String instanceUrl, String instanceToken, int teamId) {
|
||||
@Override
|
||||
public void onResume() {
|
||||
|
||||
super.onResume();
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
|
||||
if(tinyDb.getBoolean("teamActionFlag")) {
|
||||
|
||||
fetchDataAsync(Authorization.get(ctx), Integer.parseInt(teamId));
|
||||
tinyDb.putBoolean("teamActionFlag", false);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchDataAsync(String instanceToken, int teamId) {
|
||||
|
||||
TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class);
|
||||
|
||||
teamMembersModel.getMembersByOrgList(instanceUrl, instanceToken, teamId, getApplicationContext()).observe(this, new Observer<List<UserInfo>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable List<UserInfo> teamMembersListMain) {
|
||||
adapter = new TeamMembersByOrgAdapter(getApplicationContext(), teamMembersListMain);
|
||||
if(adapter.getCount() > 0) {
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataMembers.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
adapter.notifyDataSetChanged();
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataMembers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
teamMembersModel.getMembersByOrgList(instanceToken, teamId, ctx).observe(this, teamMembersListMain -> {
|
||||
|
||||
adapter = new TeamMembersByOrgAdapter(ctx, teamMembersListMain);
|
||||
|
||||
if(adapter.getCount() > 0) {
|
||||
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataMembers.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataMembers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
if(id == android.R.id.home) {
|
||||
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.genericMenu) {
|
||||
|
||||
BottomSheetOrganizationTeamsFragment bottomSheet = new BottomSheetOrganizationTeamsFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "orgTeamsBottomSheet");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClicked(String text) {
|
||||
|
||||
if("newMember".equals(text)) {
|
||||
|
||||
Intent intent = new Intent(OrganizationTeamMembersActivity.this, AddNewTeamMemberActivity.class);
|
||||
intent.putExtra("teamId", teamId);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.fragments.profile.DetailFragment;
|
||||
import org.mian.gitnex.fragments.profile.FollowersFragment;
|
||||
import org.mian.gitnex.fragments.profile.FollowingFragment;
|
||||
import org.mian.gitnex.fragments.profile.OrganizationsFragment;
|
||||
import org.mian.gitnex.fragments.profile.RepositoriesFragment;
|
||||
import org.mian.gitnex.fragments.profile.StarredRepositoriesFragment;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class ProfileActivity extends BaseActivity {
|
||||
|
||||
private String username;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_profile);
|
||||
Intent profileIntent = getIntent();
|
||||
Typeface myTypeface;
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
TextView toolbarTitle = findViewById(R.id.toolbarTitle);
|
||||
|
||||
if(profileIntent.getStringExtra("username") != null && !Objects.equals(profileIntent.getStringExtra("username"), "")) {
|
||||
username = profileIntent.getStringExtra("username");
|
||||
}
|
||||
else {
|
||||
Toasty.warning(ctx, ctx.getResources().getString(R.string.userInvalidUserName));
|
||||
finish();
|
||||
}
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
Objects.requireNonNull(getSupportActionBar()).setTitle(username);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
ViewPager2 viewPager = findViewById(R.id.profileContainer);
|
||||
viewPager.setOffscreenPageLimit(1);
|
||||
TabLayout tabLayout = findViewById(R.id.tabs);
|
||||
|
||||
switch(tinyDB.getInt("customFontId", -1)) {
|
||||
case 0:
|
||||
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
|
||||
break;
|
||||
case 2:
|
||||
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
|
||||
break;
|
||||
default:
|
||||
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf");
|
||||
break;
|
||||
}
|
||||
|
||||
toolbarTitle.setTypeface(myTypeface);
|
||||
toolbarTitle.setText(username);
|
||||
|
||||
viewPager.setAdapter(new ViewPagerAdapter(this));
|
||||
|
||||
String[] tabTitles = {ctx.getResources().getString(R.string.tabTextInfo), ctx.getResources().getString(R.string.navRepos), ctx.getResources().getString(R.string.navStarredRepos), ctx.getResources().getString(R.string.navOrg), ctx.getResources().getString(R.string.profileTabFollowers), ctx.getResources().getString(R.string.profileTabFollowing)};
|
||||
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText(tabTitles[position])).attach();
|
||||
|
||||
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
|
||||
int tabsCount = vg.getChildCount();
|
||||
|
||||
for (int j = 0; j < tabsCount; j++) {
|
||||
|
||||
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
|
||||
int tabChildCount = vgTab.getChildCount();
|
||||
|
||||
for (int i = 0; i < tabChildCount; i++) {
|
||||
View tabViewChild = vgTab.getChildAt(i);
|
||||
if (tabViewChild instanceof TextView) {
|
||||
((TextView) tabViewChild).setTypeface(myTypeface);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewPagerAdapter extends FragmentStateAdapter {
|
||||
|
||||
public ViewPagerAdapter(@NonNull FragmentActivity fa) { super(fa); }
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
switch(position) {
|
||||
case 0: // detail
|
||||
return DetailFragment.newInstance(username);
|
||||
case 1: // repos
|
||||
return RepositoriesFragment.newInstance(username);
|
||||
case 2: // starred repos
|
||||
return StarredRepositoriesFragment.newInstance(username);
|
||||
case 3: // organizations
|
||||
return OrganizationsFragment.newInstance(username);
|
||||
case 4: // followers
|
||||
return FollowersFragment.newInstance(username);
|
||||
case 5: // following
|
||||
return FollowingFragment.newInstance(username);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
if(id == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import com.hendraanggrian.appcompat.socialview.Mention;
|
||||
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
|
||||
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.IssueActions;
|
||||
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.models.Collaborators;
|
||||
import org.mian.gitnex.models.Issues;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class ReplyToIssueActivity extends BaseActivity {
|
||||
|
||||
public ImageView closeActivity;
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
final Context ctx = this;
|
||||
|
||||
private SocialAutoCompleteTextView addComment;
|
||||
private ArrayAdapter<Mention> defaultMentionAdapter;
|
||||
private Button replyButton;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_reply_to_issue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
addComment = findViewById(R.id.addComment);
|
||||
addComment.setShowSoftInputOnFocus(true);
|
||||
|
||||
defaultMentionAdapter = new MentionArrayAdapter<>(this);
|
||||
loadCollaboratorsList();
|
||||
|
||||
addComment.setMentionAdapter(defaultMentionAdapter);
|
||||
|
||||
closeActivity = findViewById(R.id.close);
|
||||
TextView toolbar_title = findViewById(R.id.toolbar_title);
|
||||
|
||||
addComment.requestFocus();
|
||||
assert imm != null;
|
||||
imm.showSoftInput(addComment, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
if(!tinyDb.getString("issueTitle").isEmpty()) {
|
||||
toolbar_title.setText(tinyDb.getString("issueTitle"));
|
||||
}
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
replyButton = findViewById(R.id.replyButton);
|
||||
|
||||
if(getIntent().getStringExtra("commentAction") != null && getIntent().getStringExtra("commentAction").equals("edit")) {
|
||||
|
||||
addComment.setText(getIntent().getStringExtra("commentBody"));
|
||||
final String commentId = getIntent().getStringExtra("commentId");
|
||||
|
||||
toolbar_title.setText(getResources().getString(R.string.editCommentTitle));
|
||||
replyButton.setText(getResources().getString(R.string.editCommentButtonText));
|
||||
|
||||
replyButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
disableProcessButton();
|
||||
IssueActions.editIssueComment(ctx, Integer.valueOf(commentId), addComment.getText().toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
disableProcessButton();
|
||||
|
||||
} else {
|
||||
|
||||
replyButton.setOnClickListener(replyToIssue);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void loadCollaboratorsList() {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
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<List<Collaborators>> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<List<Collaborators>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
String fullName = "";
|
||||
for (int i = 0; i < response.body().size(); i++) {
|
||||
if(!response.body().get(i).getFull_name().equals("")) {
|
||||
fullName = response.body().get(i).getFull_name();
|
||||
}
|
||||
defaultMentionAdapter.add(
|
||||
new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
Log.i("onResponse", String.valueOf(response.code()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
|
||||
Log.i("onFailure", t.getMessage());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private View.OnClickListener replyToIssue = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
processNewCommentReply();
|
||||
}
|
||||
};
|
||||
|
||||
private void processNewCommentReply() {
|
||||
|
||||
String newReplyDT = addComment.getText().toString();
|
||||
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
|
||||
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(newReplyDT.equals("")) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.commentEmptyError));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
disableProcessButton();
|
||||
replyComment(newReplyDT);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void replyComment(String newReplyDT) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
|
||||
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];
|
||||
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
|
||||
|
||||
Issues issueComment = new Issues(newReplyDT);
|
||||
|
||||
Call<Issues> call = RetrofitClient
|
||||
.getInstance(instanceUrl, getApplicationContext())
|
||||
.getApiInterface()
|
||||
.replyCommentToIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment);
|
||||
|
||||
call.enqueue(new Callback<Issues>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
|
||||
|
||||
if(response.code() == 201) {
|
||||
|
||||
Toasty.info(getApplicationContext(), getString(R.string.commentSuccess));
|
||||
tinyDb.putBoolean("commentPosted", true);
|
||||
tinyDb.putBoolean("resumeIssues", true);
|
||||
tinyDb.putBoolean("resumePullRequests", true);
|
||||
finish();
|
||||
|
||||
}
|
||||
else if(response.code() == 401) {
|
||||
|
||||
enableProcessButton();
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
enableProcessButton();
|
||||
Toasty.info(getApplicationContext(), getString(R.string.commentError));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
|
||||
Log.e("onFailure", t.toString());
|
||||
enableProcessButton();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void disableProcessButton() {
|
||||
|
||||
replyButton.setEnabled(false);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.hintColor));
|
||||
replyButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
private void enableProcessButton() {
|
||||
|
||||
replyButton.setEnabled(true);
|
||||
GradientDrawable shape = new GradientDrawable();
|
||||
shape.setCornerRadius( 8 );
|
||||
shape.setColor(getResources().getColor(R.color.btnBackground));
|
||||
replyButton.setBackground(shape);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,278 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import org.gitnex.tea4j.models.UserRepositories;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.RepoForksAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityRepoForksBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class RepoForksActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView noData;
|
||||
private ProgressBar progressBar;
|
||||
private final String TAG = "RepositoryForks";
|
||||
private int resultLimit = Constants.resultLimitOldGiteaInstances;
|
||||
private int pageSize = 1;
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
private List<UserRepositories> forksList;
|
||||
private RepoForksAdapter adapter;
|
||||
private ProgressBar progressLoadMore;
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityRepoForksBinding activityRepoForksBinding = ActivityRepoForksBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityRepoForksBinding.getRoot());
|
||||
|
||||
Toolbar toolbar = activityRepoForksBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
|
||||
String repoFullNameForForks = getIntent().getStringExtra("repoFullNameForForks");
|
||||
assert repoFullNameForForks != null;
|
||||
String[] parts = repoFullNameForForks.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
TextView toolbar_title = activityRepoForksBinding.toolbarTitle;
|
||||
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
|
||||
toolbar_title.setText(String.format("%s : %s", ctx.getResources().getString(R.string.infoTabRepoForksCount), repoName));
|
||||
|
||||
ImageView closeActivity = activityRepoForksBinding.close;
|
||||
noData = activityRepoForksBinding.noData;
|
||||
progressLoadMore = activityRepoForksBinding.progressLoadMore;
|
||||
progressBar = activityRepoForksBinding.progressBar;
|
||||
SwipeRefreshLayout swipeRefresh = activityRepoForksBinding.pullToRefresh;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances)
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12")) {
|
||||
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
recyclerView = activityRepoForksBinding.recyclerView;
|
||||
forksList = new ArrayList<>();
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
swipeRefresh.setRefreshing(false);
|
||||
loadInitial(Authorization.get(ctx), repoOwner, repoName, pageSize, resultLimit);
|
||||
adapter.notifyDataChanged();
|
||||
|
||||
}, 200));
|
||||
|
||||
adapter = new RepoForksAdapter(ctx, forksList);
|
||||
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
|
||||
|
||||
if(forksList.size() == resultLimit || pageSize == resultLimit) {
|
||||
|
||||
int page = (forksList.size() + resultLimit) / resultLimit;
|
||||
loadMore(Authorization.get(ctx), repoOwner, repoName, page, resultLimit);
|
||||
}
|
||||
}));
|
||||
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
loadInitial(Authorization.get(ctx), repoOwner, repoName, pageSize, resultLimit);
|
||||
}
|
||||
|
||||
private void loadInitial(String instanceToken, String repoOwner, String repoName, int pageSize, int resultLimit) {
|
||||
|
||||
Call<List<UserRepositories>> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getRepositoryForks(instanceToken, repoOwner, repoName, pageSize, resultLimit);
|
||||
|
||||
call.enqueue(new Callback<List<UserRepositories>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<UserRepositories>> call, @NonNull Response<List<UserRepositories>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
|
||||
if(response.body().size() > 0) {
|
||||
|
||||
forksList.clear();
|
||||
forksList.addAll(response.body());
|
||||
adapter.notifyDataChanged();
|
||||
noData.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
forksList.clear();
|
||||
adapter.notifyDataChanged();
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<UserRepositories>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e(TAG, t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void loadMore(String instanceToken, String repoOwner, String repoName, int page, int resultLimit) {
|
||||
|
||||
progressLoadMore.setVisibility(View.VISIBLE);
|
||||
|
||||
Call<List<UserRepositories>> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getRepositoryForks(instanceToken, repoOwner, repoName, page, resultLimit);
|
||||
|
||||
call.enqueue(new Callback<List<UserRepositories>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<UserRepositories>> call, @NonNull Response<List<UserRepositories>> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
//remove loading view
|
||||
forksList.remove(forksList.size() - 1);
|
||||
|
||||
List<UserRepositories> result = response.body();
|
||||
assert result != null;
|
||||
|
||||
if(result.size() > 0) {
|
||||
|
||||
pageSize = result.size();
|
||||
forksList.addAll(result);
|
||||
}
|
||||
else {
|
||||
|
||||
adapter.setMoreDataAvailable(false);
|
||||
}
|
||||
|
||||
adapter.notifyDataChanged();
|
||||
progressLoadMore.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<UserRepositories>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e(TAG, t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.search_menu, menu);
|
||||
|
||||
MenuItem searchItem = menu.findItem(R.id.action_search);
|
||||
SearchView searchView = (SearchView) searchItem.getActionView();
|
||||
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
|
||||
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
|
||||
filter(newText);
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
private void filter(String text) {
|
||||
|
||||
List<UserRepositories> arr = new ArrayList<>();
|
||||
|
||||
for(UserRepositories d : forksList) {
|
||||
|
||||
if(d.getName().toLowerCase().contains(text) || d.getDescription().toLowerCase().contains(text)) {
|
||||
|
||||
arr.add(d);
|
||||
}
|
||||
}
|
||||
|
||||
adapter.updateList(arr);
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = view -> {
|
||||
|
||||
getIntent().removeExtra("repoFullNameForForks");
|
||||
finish();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +1,17 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import android.view.View;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.RepoStargazersAdapter;
|
||||
import org.mian.gitnex.databinding.ActivityRepoStargazersBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.models.UserInfo;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.viewmodels.RepoStargazersViewModel;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -29,25 +25,19 @@ public class RepoStargazersActivity extends BaseActivity {
|
||||
private GridView mGridView;
|
||||
private ProgressBar mProgressBar;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_repo_stargazers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
TextView toolbarTitle = findViewById(R.id.toolbar_title);
|
||||
noDataStargazers = findViewById(R.id.noDataStargazers);
|
||||
mGridView = findViewById(R.id.gridView);
|
||||
mProgressBar = findViewById(R.id.progress_bar);
|
||||
ActivityRepoStargazersBinding activityRepoStargazersBinding = ActivityRepoStargazersBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityRepoStargazersBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = activityRepoStargazersBinding.close;
|
||||
TextView toolbarTitle = activityRepoStargazersBinding.toolbarTitle;
|
||||
noDataStargazers = activityRepoStargazersBinding.noDataStargazers;
|
||||
mGridView = activityRepoStargazersBinding.gridView;
|
||||
mProgressBar = activityRepoStargazersBinding.progressBar;
|
||||
|
||||
String repoFullNameForStars = getIntent().getStringExtra("repoFullNameForStars");
|
||||
String[] parts = repoFullNameForStars.split("/");
|
||||
@@ -59,40 +49,37 @@ public class RepoStargazersActivity extends BaseActivity {
|
||||
|
||||
toolbarTitle.setText(R.string.repoStargazersInMenu);
|
||||
|
||||
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
fetchDataAsync(Authorization.get(ctx), repoOwner, repoName);
|
||||
}
|
||||
|
||||
private void fetchDataAsync(String instanceUrl, String instanceToken, String repoOwner, String repoName) {
|
||||
private void fetchDataAsync(String instanceToken, String repoOwner, String repoName) {
|
||||
|
||||
RepoStargazersViewModel repoStargazersModel = new ViewModelProvider(this).get(RepoStargazersViewModel.class);
|
||||
|
||||
repoStargazersModel.getRepoStargazers(instanceUrl, instanceToken, repoOwner, repoName, getApplicationContext()).observe(this, new Observer<List<UserInfo>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable List<UserInfo> stargazersListMain) {
|
||||
adapter = new RepoStargazersAdapter(getApplicationContext(), stargazersListMain);
|
||||
if(adapter.getCount() > 0) {
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataStargazers.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
adapter.notifyDataSetChanged();
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataStargazers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
repoStargazersModel.getRepoStargazers(instanceToken, repoOwner, repoName, ctx).observe(this, stargazersListMain -> {
|
||||
|
||||
adapter = new RepoStargazersAdapter(ctx, stargazersListMain);
|
||||
|
||||
if(adapter.getCount() > 0) {
|
||||
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataStargazers.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataStargazers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import android.view.View;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.RepoWatchersAdapter;
|
||||
import org.mian.gitnex.databinding.ActivityRepoWatchersBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.models.UserInfo;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.viewmodels.RepoWatchersViewModel;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -29,25 +25,19 @@ public class RepoWatchersActivity extends BaseActivity {
|
||||
private GridView mGridView;
|
||||
private ProgressBar mProgressBar;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_repo_watchers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
TinyDB tinyDb = new TinyDB(getApplicationContext());
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
ActivityRepoWatchersBinding activityRepoWatchersBinding = ActivityRepoWatchersBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityRepoWatchersBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
TextView toolbarTitle = findViewById(R.id.toolbar_title);
|
||||
noDataWatchers = findViewById(R.id.noDataWatchers);
|
||||
mGridView = findViewById(R.id.gridView);
|
||||
mProgressBar = findViewById(R.id.progress_bar);
|
||||
ImageView closeActivity = activityRepoWatchersBinding.close;
|
||||
TextView toolbarTitle = activityRepoWatchersBinding.toolbarTitle;
|
||||
noDataWatchers = activityRepoWatchersBinding.noDataWatchers;
|
||||
mGridView = activityRepoWatchersBinding.gridView;
|
||||
mProgressBar = activityRepoWatchersBinding.progressBar;
|
||||
|
||||
String repoFullNameForWatchers = getIntent().getStringExtra("repoFullNameForWatchers");
|
||||
String[] parts = repoFullNameForWatchers.split("/");
|
||||
@@ -59,40 +49,37 @@ public class RepoWatchersActivity extends BaseActivity {
|
||||
|
||||
toolbarTitle.setText(R.string.repoWatchersInMenu);
|
||||
|
||||
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
|
||||
|
||||
fetchDataAsync(Authorization.get(ctx), repoOwner, repoName);
|
||||
}
|
||||
|
||||
private void fetchDataAsync(String instanceUrl, String instanceToken, String repoOwner, String repoName) {
|
||||
private void fetchDataAsync(String instanceToken, String repoOwner, String repoName) {
|
||||
|
||||
RepoWatchersViewModel repoWatchersModel = new ViewModelProvider(this).get(RepoWatchersViewModel.class);
|
||||
|
||||
repoWatchersModel.getRepoWatchers(instanceUrl, instanceToken, repoOwner, repoName, getApplicationContext()).observe(this, new Observer<List<UserInfo>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable List<UserInfo> watchersListMain) {
|
||||
adapter = new RepoWatchersAdapter(getApplicationContext(), watchersListMain);
|
||||
if(adapter.getCount() > 0) {
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataWatchers.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
adapter.notifyDataSetChanged();
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataWatchers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
repoWatchersModel.getRepoWatchers(instanceToken, repoOwner, repoName, ctx).observe(this, watchersListMain -> {
|
||||
|
||||
adapter = new RepoWatchersAdapter(ctx, watchersListMain);
|
||||
|
||||
if(adapter.getCount() > 0) {
|
||||
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataWatchers.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataWatchers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.gitnex.tea4j.models.RepositoryTransfer;
|
||||
import org.gitnex.tea4j.models.UserRepositories;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.databinding.ActivityRepositorySettingsBinding;
|
||||
import org.mian.gitnex.databinding.CustomRepositoryDeleteDialogBinding;
|
||||
import org.mian.gitnex.databinding.CustomRepositoryEditPropertiesDialogBinding;
|
||||
import org.mian.gitnex.databinding.CustomRepositoryTransferDialogBinding;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class RepositorySettingsActivity extends BaseActivity {
|
||||
|
||||
private ActivityRepositorySettingsBinding viewBinding;
|
||||
private CustomRepositoryEditPropertiesDialogBinding propBinding;
|
||||
private CustomRepositoryDeleteDialogBinding deleteRepoBinding;
|
||||
private CustomRepositoryTransferDialogBinding transferRepoBinding;
|
||||
private Dialog dialogProp;
|
||||
private Dialog dialogDeleteRepository;
|
||||
private Dialog dialogTransferRepository;
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
private String loginUid;
|
||||
private String instanceToken;
|
||||
|
||||
private String repositoryOwner;
|
||||
private String repositoryName;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
viewBinding = ActivityRepositorySettingsBinding.inflate(getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
|
||||
loginUid = tinyDB.getString("loginUid");
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
repositoryOwner = parts[0];
|
||||
repositoryName = parts[1];
|
||||
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
// require gitea 1.12 or higher
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
|
||||
|
||||
viewBinding.transferOwnerFrame.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
viewBinding.editProperties.setOnClickListener(editProperties -> showRepositoryProperties());
|
||||
|
||||
viewBinding.deleteRepository.setOnClickListener(deleteRepository -> showDeleteRepository());
|
||||
|
||||
viewBinding.transferOwnerFrame.setOnClickListener(transferRepositoryOwnership -> showTransferRepository());
|
||||
}
|
||||
|
||||
private void showTransferRepository() {
|
||||
|
||||
dialogTransferRepository = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
|
||||
|
||||
if (dialogTransferRepository.getWindow() != null) {
|
||||
|
||||
dialogTransferRepository.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
transferRepoBinding = CustomRepositoryTransferDialogBinding.inflate(LayoutInflater.from(ctx));
|
||||
|
||||
View view = transferRepoBinding.getRoot();
|
||||
dialogTransferRepository.setContentView(view);
|
||||
|
||||
transferRepoBinding.cancel.setOnClickListener(editProperties -> dialogTransferRepository.dismiss());
|
||||
|
||||
transferRepoBinding.transfer.setOnClickListener(deleteRepo -> {
|
||||
|
||||
String newOwner = String.valueOf(transferRepoBinding.ownerNameForTransfer.getText());
|
||||
String repoName = String.valueOf(transferRepoBinding.repoNameForTransfer.getText());
|
||||
|
||||
if(!repositoryName.equals(repoName)) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.repoSettingsDeleteError));
|
||||
}
|
||||
else if(newOwner.matches("")) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.repoTransferOwnerError));
|
||||
}
|
||||
else {
|
||||
|
||||
transferRepository(newOwner);
|
||||
}
|
||||
});
|
||||
|
||||
dialogTransferRepository.setCancelable(false);
|
||||
dialogTransferRepository.show();
|
||||
}
|
||||
|
||||
private void transferRepository(String newOwner) {
|
||||
|
||||
RepositoryTransfer repositoryTransfer = new RepositoryTransfer(newOwner);
|
||||
|
||||
Call<JsonElement> transferCall = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.transferRepository(instanceToken, repositoryOwner, repositoryName, repositoryTransfer);
|
||||
|
||||
transferCall.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
transferRepoBinding.transfer.setVisibility(View.GONE);
|
||||
transferRepoBinding.processingRequest.setVisibility(View.VISIBLE);
|
||||
|
||||
if (response.code() == 202) {
|
||||
|
||||
dialogTransferRepository.dismiss();
|
||||
Toasty.success(ctx, getString(R.string.repoTransferSuccess));
|
||||
|
||||
finish();
|
||||
BaseApi.getInstance(ctx, RepositoriesApi.class).deleteRepository((int) tinyDB.getLong("repositoryId", 0));
|
||||
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
|
||||
RepositorySettingsActivity.this.startActivity(intent);
|
||||
}
|
||||
else if (response.code() == 404) {
|
||||
|
||||
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
|
||||
transferRepoBinding.processingRequest.setVisibility(View.GONE);
|
||||
Toasty.error(ctx, getString(R.string.repoTransferError));
|
||||
}
|
||||
else {
|
||||
|
||||
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
|
||||
transferRepoBinding.processingRequest.setVisibility(View.GONE);
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
|
||||
transferRepoBinding.processingRequest.setVisibility(View.GONE);
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showDeleteRepository() {
|
||||
|
||||
dialogDeleteRepository = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
|
||||
|
||||
if (dialogDeleteRepository.getWindow() != null) {
|
||||
|
||||
dialogDeleteRepository.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
deleteRepoBinding = CustomRepositoryDeleteDialogBinding.inflate(LayoutInflater.from(ctx));
|
||||
|
||||
View view = deleteRepoBinding.getRoot();
|
||||
dialogDeleteRepository.setContentView(view);
|
||||
|
||||
deleteRepoBinding.cancel.setOnClickListener(editProperties -> dialogDeleteRepository.dismiss());
|
||||
|
||||
deleteRepoBinding.delete.setOnClickListener(deleteRepo -> {
|
||||
|
||||
if(!repositoryName.equals(String.valueOf(deleteRepoBinding.repoNameForDeletion.getText()))) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.repoSettingsDeleteError));
|
||||
}
|
||||
else {
|
||||
|
||||
deleteRepository();
|
||||
}
|
||||
});
|
||||
|
||||
dialogDeleteRepository.setCancelable(false);
|
||||
dialogDeleteRepository.show();
|
||||
}
|
||||
|
||||
private void deleteRepository() {
|
||||
|
||||
Call<JsonElement> deleteCall = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.deleteRepository(instanceToken, repositoryOwner, repositoryName);
|
||||
|
||||
deleteCall.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
deleteRepoBinding.delete.setVisibility(View.GONE);
|
||||
deleteRepoBinding.processingRequest.setVisibility(View.VISIBLE);
|
||||
|
||||
if (response.code() == 204) {
|
||||
|
||||
dialogDeleteRepository.dismiss();
|
||||
Toasty.success(ctx, getString(R.string.repoDeletionSuccess));
|
||||
|
||||
finish();
|
||||
BaseApi.getInstance(ctx, RepositoriesApi.class).deleteRepository((int) tinyDB.getLong("repositoryId", 0));
|
||||
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
|
||||
RepositorySettingsActivity.this.startActivity(intent);
|
||||
}
|
||||
else {
|
||||
|
||||
deleteRepoBinding.delete.setVisibility(View.VISIBLE);
|
||||
deleteRepoBinding.processingRequest.setVisibility(View.GONE);
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
deleteRepoBinding.delete.setVisibility(View.VISIBLE);
|
||||
deleteRepoBinding.processingRequest.setVisibility(View.GONE);
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showRepositoryProperties() {
|
||||
|
||||
dialogProp = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
|
||||
|
||||
if (dialogProp.getWindow() != null) {
|
||||
|
||||
dialogProp.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
propBinding = CustomRepositoryEditPropertiesDialogBinding.inflate(LayoutInflater.from(ctx));
|
||||
|
||||
View view = propBinding.getRoot();
|
||||
dialogProp.setContentView(view);
|
||||
|
||||
propBinding.cancel.setOnClickListener(editProperties -> dialogProp.dismiss());
|
||||
|
||||
Call<UserRepositories> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getUserRepository(instanceToken, repositoryOwner, repositoryName);
|
||||
|
||||
call.enqueue(new Callback<UserRepositories>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
|
||||
|
||||
UserRepositories repoInfo = response.body();
|
||||
|
||||
propBinding.progressBar.setVisibility(View.GONE);
|
||||
propBinding.mainView.setVisibility(View.VISIBLE);
|
||||
|
||||
if (response.code() == 200) {
|
||||
|
||||
assert repoInfo != null;
|
||||
propBinding.repoName.setText(repoInfo.getName());
|
||||
propBinding.repoWebsite.setText(repoInfo.getWebsite());
|
||||
propBinding.repoDescription.setText(repoInfo.getDescription());
|
||||
propBinding.repoPrivate.setChecked(repoInfo.getPrivateFlag());
|
||||
propBinding.repoAsTemplate.setChecked(repoInfo.isTemplate());
|
||||
|
||||
propBinding.repoEnableIssues.setChecked(repoInfo.getHas_issues());
|
||||
|
||||
propBinding.repoEnableIssues.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
if (isChecked) {
|
||||
|
||||
propBinding.repoEnableTimer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
|
||||
propBinding.repoEnableTimer.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
if(repoInfo.getInternal_tracker() != null) {
|
||||
|
||||
propBinding.repoEnableTimer.setChecked(repoInfo.getInternal_tracker().isEnable_time_tracker());
|
||||
}
|
||||
else {
|
||||
|
||||
propBinding.repoEnableTimer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
propBinding.repoEnableWiki.setChecked(repoInfo.isHas_wiki());
|
||||
propBinding.repoEnablePr.setChecked(repoInfo.isHas_pull_requests());
|
||||
propBinding.repoEnableMerge.setChecked(repoInfo.isAllow_merge_commits());
|
||||
propBinding.repoEnableRebase.setChecked(repoInfo.isAllow_rebase());
|
||||
propBinding.repoEnableSquash.setChecked(repoInfo.isAllow_squash_merge());
|
||||
propBinding.repoEnableForceMerge.setChecked(repoInfo.isAllow_rebase_explicit());
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
|
||||
propBinding.save.setOnClickListener(saveProperties -> saveRepositoryProperties(String.valueOf(propBinding.repoName.getText()),
|
||||
String.valueOf(propBinding.repoWebsite.getText()),
|
||||
String.valueOf(propBinding.repoDescription.getText()),
|
||||
propBinding.repoPrivate.isChecked(), propBinding.repoAsTemplate.isChecked(),
|
||||
propBinding.repoEnableIssues.isChecked(), propBinding.repoEnableWiki.isChecked(),
|
||||
propBinding.repoEnablePr.isChecked(), propBinding.repoEnableTimer.isChecked(),
|
||||
propBinding.repoEnableMerge.isChecked(), propBinding.repoEnableRebase.isChecked(),
|
||||
propBinding.repoEnableSquash.isChecked(), propBinding.repoEnableForceMerge.isChecked()));
|
||||
|
||||
dialogProp.setCancelable(false);
|
||||
dialogProp.show();
|
||||
}
|
||||
|
||||
private void saveRepositoryProperties(String repoName, String repoWebsite, String repoDescription,
|
||||
boolean repoPrivate, boolean repoAsTemplate, boolean repoEnableIssues, boolean repoEnableWiki,
|
||||
boolean repoEnablePr, boolean repoEnableTimer, boolean repoEnableMerge, boolean repoEnableRebase,
|
||||
boolean repoEnableSquash, boolean repoEnableForceMerge) {
|
||||
|
||||
UserRepositories.internalTimeTrackerObject repoPropsTimeTracker = new UserRepositories.internalTimeTrackerObject(repoEnableTimer);
|
||||
|
||||
UserRepositories repoProps;
|
||||
|
||||
if(!repoEnableIssues) {
|
||||
|
||||
repoProps = new UserRepositories(repoName, repoWebsite, repoDescription, repoPrivate, repoAsTemplate, repoEnableIssues, repoEnableWiki, repoEnablePr, repoEnableMerge,
|
||||
repoEnableRebase, repoEnableSquash, repoEnableForceMerge);
|
||||
}
|
||||
else {
|
||||
|
||||
repoProps = new UserRepositories(repoName, repoWebsite, repoDescription, repoPrivate, repoAsTemplate, repoEnableIssues, repoEnableWiki, repoEnablePr, repoPropsTimeTracker, repoEnableMerge,
|
||||
repoEnableRebase, repoEnableSquash, repoEnableForceMerge);
|
||||
}
|
||||
|
||||
Call<UserRepositories> propsCall = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.updateRepositoryProperties(instanceToken, repositoryOwner, repositoryName, repoProps);
|
||||
|
||||
propsCall.enqueue(new Callback<UserRepositories>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
|
||||
|
||||
propBinding.save.setVisibility(View.GONE);
|
||||
propBinding.processingRequest.setVisibility(View.VISIBLE);
|
||||
|
||||
if (response.code() == 200) {
|
||||
|
||||
tinyDB.putBoolean("hasIssues", repoEnableIssues);
|
||||
tinyDB.putBoolean("hasPullRequests", repoEnablePr);
|
||||
|
||||
dialogProp.dismiss();
|
||||
Toasty.success(ctx, getString(R.string.repoPropertiesSaveSuccess));
|
||||
|
||||
if(!repositoryName.equals(repoName)) {
|
||||
|
||||
finish();
|
||||
BaseApi.getInstance(ctx, RepositoriesApi.class).updateRepositoryOwnerAndName(repositoryOwner, repoName, (int) tinyDB.getLong("repositoryId", 0));
|
||||
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
|
||||
RepositorySettingsActivity.this.startActivity(intent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
propBinding.save.setVisibility(View.VISIBLE);
|
||||
propBinding.processingRequest.setVisibility(View.GONE);
|
||||
Toasty.error(ctx, getString(R.string.genericError));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
|
||||
|
||||
propBinding.save.setVisibility(View.VISIBLE);
|
||||
propBinding.processingRequest.setVisibility(View.GONE);
|
||||
Toasty.error(ctx, getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.TimePickerDialog;
|
||||
import android.os.Bundle;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TimePicker;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsAppearanceBinding;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class SettingsAppearanceActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
private static String[] timeList;
|
||||
private static int timeSelectedChoice = 0;
|
||||
|
||||
private static String[] customFontList;
|
||||
private static int customFontSelectedChoice = 0;
|
||||
|
||||
private static String[] themeList;
|
||||
private static int themeSelectedChoice = 0;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivitySettingsAppearanceBinding activitySettingsAppearanceBinding = ActivitySettingsAppearanceBinding.inflate(getLayoutInflater());
|
||||
setContentView(activitySettingsAppearanceBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = activitySettingsAppearanceBinding.close;
|
||||
|
||||
LinearLayout timeFrame = activitySettingsAppearanceBinding.timeFrame;
|
||||
LinearLayout customFontFrame = activitySettingsAppearanceBinding.customFontFrame;
|
||||
LinearLayout themeFrame = activitySettingsAppearanceBinding.themeSelectionFrame;
|
||||
LinearLayout lightTimeFrame = activitySettingsAppearanceBinding.lightThemeTimeSelectionFrame;
|
||||
LinearLayout darkTimeFrame = activitySettingsAppearanceBinding.darkThemeTimeSelectionFrame;
|
||||
|
||||
SwitchMaterial counterBadgesSwitch = activitySettingsAppearanceBinding.switchCounterBadge;
|
||||
|
||||
timeList = getResources().getStringArray(R.array.timeFormats);
|
||||
customFontList = getResources().getStringArray(R.array.fonts);
|
||||
themeList = getResources().getStringArray(R.array.themes);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
String lightMinute = String.valueOf(tinyDB.getInt("lightThemeTimeMinute"));
|
||||
String lightHour = String.valueOf(tinyDB.getInt("lightThemeTimeHour"));
|
||||
if(lightMinute.length() == 1) lightMinute = "0" + lightMinute;
|
||||
if(lightHour.length() == 1) lightHour = "0" + lightHour;
|
||||
|
||||
String darkMinute = String.valueOf(tinyDB.getInt("darkThemeTimeMinute"));
|
||||
String darkHour = String.valueOf(tinyDB.getInt("darkThemeTimeHour"));
|
||||
if(darkMinute.length() == 1) darkMinute = "0" + darkMinute;
|
||||
if(darkHour.length() == 1) darkHour = "0" + darkHour;
|
||||
|
||||
activitySettingsAppearanceBinding.lightThemeSelectedTime.setText(ctx.getResources().getString(R.string.settingsThemeTimeSelectedHint, lightHour,
|
||||
lightMinute));
|
||||
activitySettingsAppearanceBinding.darkThemeSelectedTime.setText(ctx.getResources().getString(R.string.settingsThemeTimeSelectedHint, darkHour,
|
||||
darkMinute));
|
||||
activitySettingsAppearanceBinding.tvDateTimeSelected.setText(tinyDB.getString("timeStr"));
|
||||
activitySettingsAppearanceBinding.customFontSelected.setText(tinyDB.getString("customFontStr", "Manrope"));
|
||||
activitySettingsAppearanceBinding.themeSelected.setText(tinyDB.getString("themeStr", "Dark"));
|
||||
|
||||
if(tinyDB.getString("themeStr").startsWith("Auto")) {
|
||||
darkTimeFrame.setVisibility(View.VISIBLE);
|
||||
lightTimeFrame.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
darkTimeFrame.setVisibility(View.GONE);
|
||||
lightTimeFrame.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
timeSelectedChoice = tinyDB.getInt("timeId");
|
||||
customFontSelectedChoice = tinyDB.getInt("customFontId", 1);
|
||||
themeSelectedChoice = tinyDB.getInt("themeId");
|
||||
|
||||
counterBadgesSwitch.setChecked(tinyDB.getBoolean("enableCounterBadges"));
|
||||
|
||||
// counter badge switcher
|
||||
counterBadgesSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
tinyDB.putBoolean("enableCounterBadges", isChecked);
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
// theme selection dialog
|
||||
themeFrame.setOnClickListener(view -> {
|
||||
|
||||
AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
|
||||
|
||||
tsBuilder.setTitle(getResources().getString(R.string.themeSelectorDialogTitle));
|
||||
tsBuilder.setCancelable(themeSelectedChoice != -1);
|
||||
|
||||
tsBuilder.setSingleChoiceItems(themeList, themeSelectedChoice, (dialogInterfaceTheme, i) -> {
|
||||
|
||||
themeSelectedChoice = i;
|
||||
activitySettingsAppearanceBinding.themeSelected.setText(themeList[i]);
|
||||
tinyDB.putString("themeStr", themeList[i]);
|
||||
tinyDB.putInt("themeId", i);
|
||||
|
||||
tinyDB.putBoolean("refreshParent", true);
|
||||
this.recreate();
|
||||
this.overridePendingTransition(0, 0);
|
||||
dialogInterfaceTheme.dismiss();
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
AlertDialog cfDialog = tsBuilder.create();
|
||||
cfDialog.show();
|
||||
});
|
||||
|
||||
lightTimeFrame.setOnClickListener(view -> {
|
||||
LightTimePicker timePicker = new LightTimePicker();
|
||||
timePicker.show(getSupportFragmentManager(), "timePicker");
|
||||
});
|
||||
|
||||
darkTimeFrame.setOnClickListener(view -> {
|
||||
DarkTimePicker timePicker = new DarkTimePicker();
|
||||
timePicker.show(getSupportFragmentManager(), "timePicker");
|
||||
});
|
||||
|
||||
// custom font dialog
|
||||
customFontFrame.setOnClickListener(view -> {
|
||||
|
||||
AlertDialog.Builder cfBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
|
||||
|
||||
cfBuilder.setTitle(R.string.settingsCustomFontSelectorDialogTitle);
|
||||
cfBuilder.setCancelable(customFontSelectedChoice != -1);
|
||||
|
||||
cfBuilder.setSingleChoiceItems(customFontList, customFontSelectedChoice, (dialogInterfaceCustomFont, i) -> {
|
||||
|
||||
customFontSelectedChoice = i;
|
||||
activitySettingsAppearanceBinding.customFontSelected.setText(customFontList[i]);
|
||||
tinyDB.putString("customFontStr", customFontList[i]);
|
||||
tinyDB.putInt("customFontId", i);
|
||||
|
||||
tinyDB.putBoolean("refreshParent", true);
|
||||
this.recreate();
|
||||
this.overridePendingTransition(0, 0);
|
||||
dialogInterfaceCustomFont.dismiss();
|
||||
Toasty.success(appCtx, appCtx.getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
AlertDialog cfDialog = cfBuilder.create();
|
||||
cfDialog.show();
|
||||
});
|
||||
|
||||
// time and date dialog
|
||||
timeFrame.setOnClickListener(view -> {
|
||||
|
||||
AlertDialog.Builder tBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
|
||||
|
||||
tBuilder.setTitle(R.string.settingsTimeSelectorDialogTitle);
|
||||
tBuilder.setCancelable(timeSelectedChoice != -1);
|
||||
|
||||
tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, (dialogInterfaceTime, i) -> {
|
||||
|
||||
timeSelectedChoice = i;
|
||||
activitySettingsAppearanceBinding.tvDateTimeSelected.setText(timeList[i]);
|
||||
tinyDB.putString("timeStr", timeList[i]);
|
||||
tinyDB.putInt("timeId", i);
|
||||
|
||||
switch(i) {
|
||||
case 0:
|
||||
tinyDB.putString("dateFormat", "pretty");
|
||||
break;
|
||||
case 1:
|
||||
tinyDB.putString("dateFormat", "normal");
|
||||
break;
|
||||
}
|
||||
|
||||
dialogInterfaceTime.dismiss();
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
AlertDialog tDialog = tBuilder.create();
|
||||
tDialog.show();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
public static class LightTimePicker extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
|
||||
|
||||
TinyDB db = TinyDB.getInstance(getContext());
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
int hour = db.getInt("lightThemeTimeHour");
|
||||
int minute = db.getInt("lightThemeTimeMinute");
|
||||
|
||||
return new TimePickerDialog(getActivity(), this, hour, minute, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
|
||||
db.putInt("lightThemeTimeHour", hourOfDay);
|
||||
db.putInt("lightThemeTimeMinute", minute);
|
||||
db.putBoolean("refreshParent", true);
|
||||
requireActivity().overridePendingTransition(0, 0);
|
||||
this.dismiss();
|
||||
Toasty.success(requireActivity().getApplicationContext(), requireContext().getResources().getString(R.string.settingsSave));
|
||||
requireActivity().recreate();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DarkTimePicker extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
|
||||
|
||||
TinyDB db = TinyDB.getInstance(getContext());
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
int hour = db.getInt("darkThemeTimeHour");
|
||||
int minute = db.getInt("darkThemeTimeMinute");
|
||||
|
||||
return new TimePickerDialog(getActivity(), this, hour, minute, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
|
||||
db.putInt("darkThemeTimeHour", hourOfDay);
|
||||
db.putInt("darkThemeTimeMinute", minute);
|
||||
db.putBoolean("refreshParent", true);
|
||||
requireActivity().overridePendingTransition(0, 0);
|
||||
this.dismiss();
|
||||
Toasty.success(requireActivity().getApplicationContext(), requireContext().getResources().getString(R.string.settingsSave));
|
||||
requireActivity().recreate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsDraftsBinding;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class SettingsDraftsActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivitySettingsDraftsBinding activitySettingsDraftsBinding = ActivitySettingsDraftsBinding.inflate(getLayoutInflater());
|
||||
setContentView(activitySettingsDraftsBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = activitySettingsDraftsBinding.close;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
activitySettingsDraftsBinding.commentsDeletionSwitch.setChecked(tinyDB.getBoolean("draftsCommentsDeletionEnabled"));
|
||||
|
||||
// delete comments on submit switcher
|
||||
activitySettingsDraftsBinding.commentsDeletionSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
tinyDB.putBoolean("draftsCommentsDeletionEnabled", isChecked);
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() { onClickListener = view -> finish(); }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsGeneralBinding;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class SettingsGeneralActivity extends BaseActivity {
|
||||
|
||||
private ActivitySettingsGeneralBinding viewBinding;
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
private List<String> homeScreenList;
|
||||
private static int homeScreenSelectedChoice = 0;
|
||||
|
||||
private List<String> linkHandlerDefaultScreen;
|
||||
private static int defaultLinkHandlerScreenSelectedChoice = 0;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
viewBinding = ActivitySettingsGeneralBinding.inflate(getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
|
||||
initCloseListener();
|
||||
viewBinding.close.setOnClickListener(onClickListener);
|
||||
|
||||
// home screen
|
||||
String[] appHomeDefaultScreen = getResources().getStringArray(R.array.appDefaultHomeScreen);
|
||||
|
||||
String[] appHomeDefaultScreenNew = getResources().getStringArray(R.array.appDefaultHomeScreenNew);
|
||||
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.3")) {
|
||||
|
||||
appHomeDefaultScreen = appHomeDefaultScreenNew;
|
||||
}
|
||||
|
||||
homeScreenList = new ArrayList<>(Arrays.asList(appHomeDefaultScreen));
|
||||
String[] homeScreenArray = new String[homeScreenList.size()];
|
||||
homeScreenList.toArray(homeScreenArray);
|
||||
|
||||
if(homeScreenSelectedChoice == 0) {
|
||||
|
||||
homeScreenSelectedChoice = tinyDB.getInt("homeScreenId");
|
||||
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleMyRepos));
|
||||
}
|
||||
|
||||
if(homeScreenSelectedChoice == 1) {
|
||||
|
||||
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleStarredRepos));
|
||||
}
|
||||
else if(homeScreenSelectedChoice == 2) {
|
||||
|
||||
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleOrganizations));
|
||||
}
|
||||
else if(homeScreenSelectedChoice == 3) {
|
||||
|
||||
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleRepositories));
|
||||
}
|
||||
else if(homeScreenSelectedChoice == 4) {
|
||||
|
||||
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleProfile));
|
||||
}
|
||||
else if(homeScreenSelectedChoice == 5) {
|
||||
|
||||
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleExplore));
|
||||
}
|
||||
else if(homeScreenSelectedChoice == 6) {
|
||||
|
||||
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.titleDrafts));
|
||||
}
|
||||
else if(homeScreenSelectedChoice == 7) {
|
||||
|
||||
viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleNotifications));
|
||||
}
|
||||
|
||||
viewBinding.homeScreenFrame.setOnClickListener(setDefaultHomeScreen -> {
|
||||
|
||||
AlertDialog.Builder hsBuilder = new AlertDialog.Builder(SettingsGeneralActivity.this);
|
||||
|
||||
hsBuilder.setTitle(R.string.settingsHomeScreenSelectorDialogTitle);
|
||||
hsBuilder.setCancelable(homeScreenSelectedChoice != -1);
|
||||
|
||||
hsBuilder.setSingleChoiceItems(homeScreenArray, homeScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> {
|
||||
|
||||
homeScreenSelectedChoice = i;
|
||||
viewBinding.homeScreenSelected.setText(homeScreenArray[i]);
|
||||
tinyDB.putInt("homeScreenId", i);
|
||||
|
||||
dialogInterfaceHomeScreen.dismiss();
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
AlertDialog hsDialog = hsBuilder.create();
|
||||
hsDialog.show();
|
||||
});
|
||||
// home screen
|
||||
|
||||
// link handler
|
||||
String[] linkHandlerDefaultScreenList = getResources().getStringArray(R.array.linkHandlerDefaultScreen);
|
||||
linkHandlerDefaultScreen = new ArrayList<>(Arrays.asList(linkHandlerDefaultScreenList));
|
||||
|
||||
String[] linksArray = new String[linkHandlerDefaultScreen.size()];
|
||||
linkHandlerDefaultScreen.toArray(linksArray);
|
||||
|
||||
defaultLinkHandlerScreenSelectedChoice = tinyDB.getInt("defaultScreenId");
|
||||
viewBinding.generalDeepLinkSelected.setText(linksArray[defaultLinkHandlerScreenSelectedChoice]);
|
||||
|
||||
viewBinding.setDefaultLinkHandler.setOnClickListener(setDefaultLinkHandler -> {
|
||||
|
||||
AlertDialog.Builder dlBuilder = new AlertDialog.Builder(SettingsGeneralActivity.this);
|
||||
dlBuilder.setTitle(R.string.linkSelectorDialogTitle);
|
||||
|
||||
dlBuilder.setCancelable(defaultLinkHandlerScreenSelectedChoice != -1);
|
||||
|
||||
dlBuilder.setSingleChoiceItems(linksArray, defaultLinkHandlerScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> {
|
||||
|
||||
defaultLinkHandlerScreenSelectedChoice = i;
|
||||
viewBinding.generalDeepLinkSelected.setText(linksArray[i]);
|
||||
tinyDB.putInt("defaultScreenId", i);
|
||||
|
||||
dialogInterfaceHomeScreen.dismiss();
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
AlertDialog dlDialog = dlBuilder.create();
|
||||
dlDialog.show();
|
||||
});
|
||||
// link handler
|
||||
}
|
||||
|
||||
private void initCloseListener() { onClickListener = view -> finish(); }
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.NumberPicker;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import com.pes.androidmaterialcolorpickerdialog.ColorPicker;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.notifications.Notifications;
|
||||
|
||||
/**
|
||||
* Template Author M M Arif
|
||||
* Author opyale
|
||||
*/
|
||||
|
||||
public class SettingsNotificationsActivity extends BaseActivity {
|
||||
|
||||
private ActivitySettingsNotificationsBinding viewBinding;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
viewBinding = ActivitySettingsNotificationsBinding.inflate(getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
|
||||
View.OnClickListener onClickListener = viewClose -> finish();
|
||||
|
||||
viewBinding.close.setOnClickListener(onClickListener);
|
||||
|
||||
viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay)));
|
||||
viewBinding.chooseColorState.setCardBackgroundColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
|
||||
|
||||
viewBinding.enableNotificationsMode.setChecked(tinyDB.getBoolean("notificationsEnabled", true));
|
||||
viewBinding.enableLightsMode.setChecked(tinyDB.getBoolean("notificationsEnableLights", true));
|
||||
viewBinding.enableVibrationMode.setChecked(tinyDB.getBoolean("notificationsEnableVibration", true));
|
||||
|
||||
viewBinding.enableNotificationsMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
tinyDB.putBoolean("notificationsEnabled", isChecked);
|
||||
|
||||
if(isChecked) {
|
||||
Notifications.startWorker(ctx);
|
||||
} else {
|
||||
Notifications.stopWorker(ctx);
|
||||
}
|
||||
|
||||
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||
|
||||
});
|
||||
|
||||
// polling delay
|
||||
viewBinding.pollingDelayFrame.setOnClickListener(v -> {
|
||||
|
||||
NumberPicker numberPicker = new NumberPicker(ctx);
|
||||
numberPicker.setMinValue(Constants.minimumPollingDelay);
|
||||
numberPicker.setMaxValue(Constants.maximumPollingDelay);
|
||||
numberPicker.setValue(tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay));
|
||||
numberPicker.setWrapSelectorWheel(true);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||
builder.setTitle(getString(R.string.pollingDelayDialogHeaderText));
|
||||
builder.setMessage(getString(R.string.pollingDelayDialogDescriptionText));
|
||||
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(getString(R.string.okButton), (dialog, which) -> {
|
||||
|
||||
tinyDB.putInt("pollingDelayMinutes", numberPicker.getValue());
|
||||
|
||||
Notifications.stopWorker(ctx);
|
||||
Notifications.startWorker(ctx);
|
||||
|
||||
viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue()));
|
||||
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
|
||||
builder.setView(numberPicker);
|
||||
builder.create().show();
|
||||
|
||||
});
|
||||
|
||||
// lights switcher
|
||||
viewBinding.enableLightsMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
tinyDB.putBoolean("notificationsEnableLights", isChecked);
|
||||
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||
|
||||
});
|
||||
|
||||
// lights color chooser
|
||||
viewBinding.chooseColorFrame.setOnClickListener(v -> {
|
||||
|
||||
ColorPicker colorPicker = new ColorPicker(SettingsNotificationsActivity.this);
|
||||
colorPicker.setColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
|
||||
colorPicker.setCallback(color -> {
|
||||
|
||||
tinyDB.putInt("notificationsLightColor", color);
|
||||
viewBinding.chooseColorState.setCardBackgroundColor(color);
|
||||
colorPicker.dismiss();
|
||||
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
colorPicker.show();
|
||||
|
||||
});
|
||||
|
||||
// vibration switcher
|
||||
viewBinding.enableVibrationMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
tinyDB.putBoolean("notificationsEnableVibration", isChecked);
|
||||
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsReportsBinding;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class SettingsReportsActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivitySettingsReportsBinding activitySettingsReportsBinding = ActivitySettingsReportsBinding.inflate(getLayoutInflater());
|
||||
setContentView(activitySettingsReportsBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = activitySettingsReportsBinding.close;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
activitySettingsReportsBinding.crashReportsSwitch.setChecked(tinyDB.getBoolean("crashReportingEnabled"));
|
||||
|
||||
// crash reports switcher
|
||||
activitySettingsReportsBinding.crashReportsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
tinyDB.putBoolean("crashReportingEnabled", isChecked);
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.biometric.BiometricManager;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsSecurityBinding;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG;
|
||||
import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class SettingsSecurityActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
private static String[] cacheSizeDataList;
|
||||
private static int cacheSizeDataSelectedChoice = 0;
|
||||
|
||||
private static String[] cacheSizeImagesList;
|
||||
private static int cacheSizeImagesSelectedChoice = 0;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivitySettingsSecurityBinding activitySettingsSecurityBinding = ActivitySettingsSecurityBinding.inflate(getLayoutInflater());
|
||||
setContentView(activitySettingsSecurityBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = activitySettingsSecurityBinding.close;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
TextView cacheSizeDataSelected = activitySettingsSecurityBinding.cacheSizeDataSelected; // setter for data cache size
|
||||
TextView cacheSizeImagesSelected = activitySettingsSecurityBinding.cacheSizeImagesSelected; // setter for images cache size
|
||||
TextView clearCacheSelected = activitySettingsSecurityBinding.clearCacheSelected; // setter for clear cache
|
||||
|
||||
LinearLayout certsFrame = activitySettingsSecurityBinding.certsFrame;
|
||||
LinearLayout cacheSizeDataFrame = activitySettingsSecurityBinding.cacheSizeDataSelectionFrame;
|
||||
LinearLayout cacheSizeImagesFrame = activitySettingsSecurityBinding.cacheSizeImagesSelectionFrame;
|
||||
LinearLayout clearCacheFrame = activitySettingsSecurityBinding.clearCacheSelectionFrame;
|
||||
|
||||
SwitchMaterial switchBiometric = activitySettingsSecurityBinding.switchBiometric;
|
||||
|
||||
cacheSizeDataList = getResources().getStringArray(R.array.cacheSizeList);
|
||||
cacheSizeImagesList = getResources().getStringArray(R.array.cacheSizeList);
|
||||
|
||||
if(!tinyDB.getString("cacheSizeStr").isEmpty()) {
|
||||
|
||||
cacheSizeDataSelected.setText(tinyDB.getString("cacheSizeStr"));
|
||||
}
|
||||
|
||||
if(!tinyDB.getString("cacheSizeImagesStr").isEmpty()) {
|
||||
|
||||
cacheSizeImagesSelected.setText(tinyDB.getString("cacheSizeImagesStr"));
|
||||
}
|
||||
|
||||
if(cacheSizeDataSelectedChoice == 0) {
|
||||
|
||||
cacheSizeDataSelectedChoice = tinyDB.getInt("cacheSizeId");
|
||||
}
|
||||
|
||||
if(cacheSizeImagesSelectedChoice == 0) {
|
||||
|
||||
cacheSizeImagesSelectedChoice = tinyDB.getInt("cacheSizeImagesId");
|
||||
}
|
||||
|
||||
switchBiometric.setChecked(tinyDB.getBoolean("biometricStatus"));
|
||||
|
||||
// biometric switcher
|
||||
switchBiometric.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
|
||||
if(isChecked) {
|
||||
|
||||
BiometricManager biometricManager = BiometricManager.from(ctx);
|
||||
KeyguardManager keyguardManager = (KeyguardManager) ctx.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
|
||||
if (!keyguardManager.isDeviceSecure()) {
|
||||
|
||||
switch(biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)) {
|
||||
|
||||
case BiometricManager.BIOMETRIC_SUCCESS:
|
||||
|
||||
tinyDB.putBoolean("biometricStatus", true);
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
break;
|
||||
case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
|
||||
case BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED:
|
||||
case BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED:
|
||||
case BiometricManager.BIOMETRIC_STATUS_UNKNOWN:
|
||||
|
||||
tinyDB.putBoolean("biometricStatus", false);
|
||||
switchBiometric.setChecked(false);
|
||||
Toasty.error(appCtx, getResources().getString(R.string.biometricNotSupported));
|
||||
break;
|
||||
case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
|
||||
|
||||
tinyDB.putBoolean("biometricStatus", false);
|
||||
switchBiometric.setChecked(false);
|
||||
Toasty.error(appCtx, getResources().getString(R.string.biometricNotAvailable));
|
||||
break;
|
||||
case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
|
||||
|
||||
tinyDB.putBoolean("biometricStatus", false);
|
||||
switchBiometric.setChecked(false);
|
||||
Toasty.info(appCtx, getResources().getString(R.string.enrollBiometric));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
tinyDB.putBoolean("biometricStatus", true);
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
tinyDB.putBoolean("biometricStatus", false);
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
tinyDB.putBoolean("biometricStatus", false);
|
||||
Toasty.success(appCtx, getResources().getString(R.string.biometricNotSupported));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// clear cache setter
|
||||
File cacheDir = appCtx.getCacheDir();
|
||||
clearCacheSelected.setText(FileUtils.byteCountToDisplaySize((int) FileUtils.sizeOfDirectory(cacheDir)));
|
||||
|
||||
// clear cache
|
||||
clearCacheFrame.setOnClickListener(v1 -> {
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(SettingsSecurityActivity.this);
|
||||
|
||||
builder.setTitle(getResources().getString(R.string.clearCacheDialogHeader));
|
||||
builder.setMessage(getResources().getString(R.string.clearCacheDialogMessage));
|
||||
builder.setPositiveButton(R.string.menuDeleteText, (dialog, which) -> {
|
||||
|
||||
try {
|
||||
|
||||
FileUtils.deleteDirectory(cacheDir);
|
||||
FileUtils.mkdir(cacheDir.getAbsolutePath());
|
||||
this.recreate();
|
||||
this.overridePendingTransition(0, 0);
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
||||
Log.e("SettingsSecurity", e.toString());
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
|
||||
builder.create().show();
|
||||
|
||||
});
|
||||
|
||||
// cache size images selection dialog
|
||||
cacheSizeImagesFrame.setOnClickListener(view -> {
|
||||
|
||||
AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsSecurityActivity.this);
|
||||
|
||||
tsBuilder.setTitle(getResources().getString(R.string.cacheSizeImagesDialogHeader));
|
||||
tsBuilder.setCancelable(cacheSizeImagesSelectedChoice != -1);
|
||||
|
||||
tsBuilder.setSingleChoiceItems(cacheSizeImagesList, cacheSizeImagesSelectedChoice, (dialogInterfaceTheme, i) -> {
|
||||
|
||||
cacheSizeImagesSelectedChoice = i;
|
||||
cacheSizeImagesSelected.setText(cacheSizeImagesList[i]);
|
||||
tinyDB.putString("cacheSizeImagesStr", cacheSizeImagesList[i]);
|
||||
tinyDB.putInt("cacheSizeImagesId", i);
|
||||
|
||||
dialogInterfaceTheme.dismiss();
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
AlertDialog cfDialog = tsBuilder.create();
|
||||
cfDialog.show();
|
||||
});
|
||||
|
||||
// cache size data selection dialog
|
||||
cacheSizeDataFrame.setOnClickListener(view -> {
|
||||
|
||||
AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsSecurityActivity.this);
|
||||
|
||||
tsBuilder.setTitle(getResources().getString(R.string.cacheSizeDataDialogHeader));
|
||||
tsBuilder.setCancelable(cacheSizeDataSelectedChoice != -1);
|
||||
|
||||
tsBuilder.setSingleChoiceItems(cacheSizeDataList, cacheSizeDataSelectedChoice, (dialogInterfaceTheme, i) -> {
|
||||
|
||||
cacheSizeDataSelectedChoice = i;
|
||||
cacheSizeDataSelected.setText(cacheSizeDataList[i]);
|
||||
tinyDB.putString("cacheSizeStr", cacheSizeDataList[i]);
|
||||
tinyDB.putInt("cacheSizeId", i);
|
||||
|
||||
dialogInterfaceTheme.dismiss();
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
});
|
||||
|
||||
AlertDialog cfDialog = tsBuilder.create();
|
||||
cfDialog.show();
|
||||
});
|
||||
|
||||
// certs deletion
|
||||
certsFrame.setOnClickListener(v1 -> {
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(SettingsSecurityActivity.this);
|
||||
|
||||
builder.setTitle(getResources().getString(R.string.settingsCertsPopupTitle));
|
||||
builder.setMessage(getResources().getString(R.string.settingsCertsPopupMessage));
|
||||
builder.setPositiveButton(R.string.menuDeleteText, (dialog, which) -> {
|
||||
|
||||
appCtx.getSharedPreferences(MemorizingTrustManager.KEYSTORE_NAME, Context.MODE_PRIVATE).edit().remove(MemorizingTrustManager.KEYSTORE_KEY).apply();
|
||||
|
||||
tinyDB.putBoolean("loggedInMode", false);
|
||||
tinyDB.remove("basicAuthPassword");
|
||||
tinyDB.putBoolean("basicAuthFlag", false);
|
||||
|
||||
Intent loginActivityIntent = new Intent().setClass(appCtx, LoginActivity.class);
|
||||
loginActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
appCtx.startActivity(loginActivityIntent);
|
||||
});
|
||||
|
||||
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
|
||||
builder.create().show();
|
||||
});
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivitySettingsTranslationBinding;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class SettingsTranslationActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
private static int langSelectedChoice = 0;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
LinkedHashMap<String, String> langs = new LinkedHashMap<>();
|
||||
langs.put("", getString(R.string.settingsLanguageSystem));
|
||||
for(String langCode : getResources().getStringArray(R.array.languages)) {
|
||||
langs.put(langCode, getLanguageDisplayName(langCode));
|
||||
}
|
||||
|
||||
ActivitySettingsTranslationBinding activitySettingsTranslationBinding = ActivitySettingsTranslationBinding.inflate(getLayoutInflater());
|
||||
setContentView(activitySettingsTranslationBinding.getRoot());
|
||||
|
||||
ImageView closeActivity = activitySettingsTranslationBinding.close;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
final TextView tvLanguageSelected = activitySettingsTranslationBinding.tvLanguageSelected; // setter for en, fr
|
||||
TextView helpTranslate = activitySettingsTranslationBinding.helpTranslate;
|
||||
|
||||
LinearLayout langFrame = activitySettingsTranslationBinding.langFrame;
|
||||
|
||||
helpTranslate.setOnClickListener(v12 -> {
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
intent.setData(Uri.parse(getResources().getString(R.string.crowdInLink)));
|
||||
startActivity(intent);
|
||||
|
||||
});
|
||||
|
||||
tvLanguageSelected.setText(tinyDB.getString("localeStr"));
|
||||
|
||||
langSelectedChoice = tinyDB.getInt("langId");
|
||||
|
||||
// language dialog
|
||||
langFrame.setOnClickListener(view -> {
|
||||
|
||||
AlertDialog.Builder lBuilder = new AlertDialog.Builder(SettingsTranslationActivity.this);
|
||||
|
||||
lBuilder.setTitle(R.string.settingsLanguageSelectorDialogTitle);
|
||||
lBuilder.setCancelable(langSelectedChoice != -1);
|
||||
|
||||
lBuilder.setSingleChoiceItems(langs.values().toArray(new String[0]), langSelectedChoice, (dialogInterface, i) -> {
|
||||
|
||||
String selectedLanguage = langs.keySet().toArray(new String[0])[i];
|
||||
tinyDB.putString("localeStr", langs.get(selectedLanguage));
|
||||
tinyDB.putInt("langId", i);
|
||||
tinyDB.putString("locale", selectedLanguage);
|
||||
|
||||
tinyDB.putBoolean("refreshParent", true);
|
||||
this.overridePendingTransition(0, 0);
|
||||
dialogInterface.dismiss();
|
||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
||||
this.recreate();
|
||||
});
|
||||
|
||||
lBuilder.setNeutralButton(getString(R.string.cancelButton), null);
|
||||
|
||||
AlertDialog lDialog = lBuilder.create();
|
||||
lDialog.show();
|
||||
});
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
|
||||
private static String getLanguageDisplayName(String langCode) {
|
||||
Locale english = new Locale("en");
|
||||
Locale translated = new Locale(langCode);
|
||||
return String.format("%s (%s)", translated.getDisplayName(translated), translated.getDisplayName(english));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package org.mian.gitnex.activities;
|
||||
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.SponsorsAdapter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class SponsorsActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResourceId(){
|
||||
return R.layout.activity_sponsors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ImageView closeActivity = findViewById(R.id.close);
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
Resources res = getResources();
|
||||
CharSequence[] sponsorsInfo = res.getTextArray(R.array.sponsorsInfo);
|
||||
|
||||
List<CharSequence> sponsorsList = new ArrayList<>(Arrays.asList(sponsorsInfo));
|
||||
|
||||
RecyclerView mRecyclerView = findViewById(R.id.recyclerView);
|
||||
|
||||
mRecyclerView.setHasFixedSize(true);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
SponsorsAdapter adapter = new SponsorsAdapter(sponsorsList);
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.gitnex.tea4j.models.CronTasks;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class AdminCronTasksAdapter extends RecyclerView.Adapter<AdminCronTasksAdapter.CronTasksViewHolder> {
|
||||
|
||||
private final List<CronTasks> tasksList;
|
||||
private static TinyDB tinyDb;
|
||||
|
||||
static class CronTasksViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private CronTasks cronTasks;
|
||||
|
||||
private final TextView taskName;
|
||||
|
||||
private CronTasksViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
Context ctx = itemView.getContext();
|
||||
|
||||
final Locale locale = ctx.getResources().getConfiguration().locale;
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
ImageView runTask = itemView.findViewById(R.id.runTask);
|
||||
taskName = itemView.findViewById(R.id.taskName);
|
||||
LinearLayout cronTasksInfo = itemView.findViewById(R.id.cronTasksInfo);
|
||||
LinearLayout cronTasksRun = itemView.findViewById(R.id.cronTasksRun);
|
||||
|
||||
cronTasksInfo.setOnClickListener(taskInfo -> {
|
||||
|
||||
String nextRun = "";
|
||||
String lastRun = "";
|
||||
|
||||
if(cronTasks.getNext() != null) {
|
||||
nextRun = TimeHelper.formatTime(cronTasks.getNext(), locale, timeFormat, ctx);
|
||||
}
|
||||
if(cronTasks.getPrev() != null) {
|
||||
lastRun = TimeHelper.formatTime(cronTasks.getPrev(), locale, timeFormat, ctx);
|
||||
}
|
||||
|
||||
View view = LayoutInflater.from(ctx).inflate(R.layout.layout_cron_task_info, null);
|
||||
|
||||
TextView taskScheduleContent = view.findViewById(R.id.taskScheduleContent);
|
||||
TextView nextRunContent = view.findViewById(R.id.nextRunContent);
|
||||
TextView lastRunContent = view.findViewById(R.id.lastRunContent);
|
||||
TextView execTimeContent = view.findViewById(R.id.execTimeContent);
|
||||
|
||||
taskScheduleContent.setText(cronTasks.getSchedule());
|
||||
nextRunContent.setText(nextRun);
|
||||
lastRunContent.setText(lastRun);
|
||||
execTimeContent.setText(String.valueOf(cronTasks.getExec_times()));
|
||||
|
||||
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx);
|
||||
|
||||
alertDialog.setTitle(StringUtils.capitalize(cronTasks.getName().replace("_", " ")));
|
||||
alertDialog.setView(view);
|
||||
alertDialog.setPositiveButton(ctx.getString(R.string.close), null);
|
||||
alertDialog.create().show();
|
||||
|
||||
});
|
||||
|
||||
cronTasksRun.setOnClickListener(taskInfo -> {
|
||||
|
||||
runCronTask(ctx, cronTasks.getName());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public AdminCronTasksAdapter(Context ctx, List<CronTasks> tasksListMain) {
|
||||
|
||||
tinyDb = TinyDB.getInstance(ctx);
|
||||
this.tasksList = tasksListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AdminCronTasksAdapter.CronTasksViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_admin_cron_tasks, parent, false);
|
||||
return new AdminCronTasksAdapter.CronTasksViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull AdminCronTasksAdapter.CronTasksViewHolder holder, int position) {
|
||||
|
||||
CronTasks currentItem = tasksList.get(position);
|
||||
|
||||
holder.cronTasks = currentItem;
|
||||
holder.taskName.setText(StringUtils.capitalize(currentItem.getName().replace("_", " ")));
|
||||
}
|
||||
|
||||
private static void runCronTask(final Context ctx, final String taskName) {
|
||||
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.adminRunCronTask(instanceToken, taskName);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 204:
|
||||
Toasty.success(ctx, ctx.getString(R.string.adminCronTaskSuccessMsg, taskName));
|
||||
break;
|
||||
|
||||
case 401:
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getString(R.string.alertDialogTokenRevokedTitle),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
case 403:
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
break;
|
||||
|
||||
case 404:
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
break;
|
||||
|
||||
default:
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return tasksList.size();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -9,12 +11,15 @@ import android.widget.Filterable;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.ProfileActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.models.UserInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -24,19 +29,22 @@ import java.util.List;
|
||||
|
||||
public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdapter.UsersViewHolder> implements Filterable {
|
||||
|
||||
private List<UserInfo> usersList;
|
||||
private Context mCtx;
|
||||
private List<UserInfo> usersListFull;
|
||||
private final List<UserInfo> usersList;
|
||||
private final Context context;
|
||||
private final List<UserInfo> usersListFull;
|
||||
|
||||
static class UsersViewHolder extends RecyclerView.ViewHolder {
|
||||
class UsersViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private ImageView userAvatar;
|
||||
private TextView userFullName;
|
||||
private TextView userEmail;
|
||||
private ImageView userRole;
|
||||
private TextView userName;
|
||||
private String userLoginId;
|
||||
|
||||
private final ImageView userAvatar;
|
||||
private final TextView userFullName;
|
||||
private final TextView userEmail;
|
||||
private final ImageView userRole;
|
||||
private final TextView userName;
|
||||
|
||||
private UsersViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
userAvatar = itemView.findViewById(R.id.userAvatar);
|
||||
@@ -45,11 +53,22 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
|
||||
userEmail = itemView.findViewById(R.id.userEmail);
|
||||
userRole = itemView.findViewById(R.id.userRole);
|
||||
|
||||
itemView.setOnClickListener(loginId -> {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.putExtra("username", userLoginId);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
userAvatar.setOnLongClickListener(loginId -> {
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public AdminGetUsersAdapter(Context mCtx, List<UserInfo> usersListMain) {
|
||||
this.mCtx = mCtx;
|
||||
public AdminGetUsersAdapter(Context ctx, List<UserInfo> usersListMain) {
|
||||
|
||||
this.context = ctx;
|
||||
this.usersList = usersListMain;
|
||||
usersListFull = new ArrayList<>(usersList);
|
||||
}
|
||||
@@ -57,6 +76,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
|
||||
@NonNull
|
||||
@Override
|
||||
public AdminGetUsersAdapter.UsersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_admin_users, parent, false);
|
||||
return new AdminGetUsersAdapter.UsersViewHolder(v);
|
||||
}
|
||||
@@ -65,40 +85,49 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
|
||||
public void onBindViewHolder(@NonNull AdminGetUsersAdapter.UsersViewHolder holder, int position) {
|
||||
|
||||
UserInfo currentItem = usersList.get(position);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
holder.userLoginId = currentItem.getLogin();
|
||||
|
||||
if(!currentItem.getFullname().equals("")) {
|
||||
holder.userFullName.setText(currentItem.getFullname());
|
||||
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
|
||||
|
||||
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
|
||||
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
|
||||
}
|
||||
else {
|
||||
holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
|
||||
|
||||
holder.userFullName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
|
||||
holder.userName.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!currentItem.getEmail().equals("")) {
|
||||
|
||||
holder.userEmail.setText(currentItem.getEmail());
|
||||
}
|
||||
else {
|
||||
|
||||
holder.userEmail.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(currentItem.getIs_admin()) {
|
||||
|
||||
holder.userRole.setVisibility(View.VISIBLE);
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.textColor(mCtx.getResources().getColor(R.color.white))
|
||||
.textColor(ResourcesCompat.getColor(context.getResources(), R.color.colorWhite, null))
|
||||
.fontSize(44)
|
||||
.width(180)
|
||||
.height(60)
|
||||
.endConfig()
|
||||
.buildRoundRect(mCtx.getResources().getString(R.string.userRoleAdmin).toLowerCase(), mCtx.getResources().getColor(R.color.releasePre), 8);
|
||||
.buildRoundRect(context.getResources().getString(R.string.userRoleAdmin).toLowerCase(), ResourcesCompat.getColor(context.getResources(), R.color.releasePre, null), 8);
|
||||
holder.userRole.setImageDrawable(drawable);
|
||||
}
|
||||
else {
|
||||
|
||||
holder.userRole.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
|
||||
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,14 +140,15 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
|
||||
return usersFilter;
|
||||
}
|
||||
|
||||
private Filter usersFilter = new Filter() {
|
||||
private final Filter usersFilter = new Filter() {
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
List<UserInfo> filteredList = new ArrayList<>();
|
||||
|
||||
if (constraint == null || constraint.length() == 0) {
|
||||
filteredList.addAll(usersListFull);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
String filterPattern = constraint.toString().toLowerCase().trim();
|
||||
|
||||
for (UserInfo item : usersListFull) {
|
||||
@@ -136,6 +166,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
|
||||
usersList.clear();
|
||||
usersList.addAll((List) results.values);
|
||||
notifyDataSetChanged();
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.Collaborators;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class AssigneesListAdapter extends RecyclerView.Adapter<AssigneesListAdapter.AssigneesViewHolder> {
|
||||
|
||||
private final Context context;
|
||||
private final List<Collaborators> assigneesList;
|
||||
private List<String> assigneesStrings = new ArrayList<>();
|
||||
private List<String> currentAssignees;
|
||||
|
||||
private final AssigneesListAdapterListener assigneesListener;
|
||||
|
||||
public interface AssigneesListAdapterListener {
|
||||
|
||||
void assigneesInterface(List<String> data);
|
||||
}
|
||||
|
||||
public AssigneesListAdapter(Context ctx, List<Collaborators> dataMain, AssigneesListAdapterListener assigneesListener, List<String> currentAssignees) {
|
||||
|
||||
this.context = ctx;
|
||||
this.assigneesList = dataMain;
|
||||
this.assigneesListener = assigneesListener;
|
||||
this.currentAssignees = currentAssignees;
|
||||
}
|
||||
|
||||
static class AssigneesViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final CheckBox assigneesSelection;
|
||||
private final TextView assigneesName;
|
||||
private final ImageView assigneesAvatar;
|
||||
|
||||
private AssigneesViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
this.setIsRecyclable(false);
|
||||
|
||||
assigneesSelection = itemView.findViewById(R.id.assigneesSelection);
|
||||
assigneesName = itemView.findViewById(R.id.assigneesName);
|
||||
assigneesAvatar = itemView.findViewById(R.id.assigneesAvatar);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AssigneesListAdapter.AssigneesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_assignees_list, parent, false);
|
||||
return new AssigneesListAdapter.AssigneesViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull AssigneesListAdapter.AssigneesViewHolder holder, int position) {
|
||||
|
||||
Collaborators currentItem = assigneesList.get(position);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
if(currentItem.getFull_name().equals("")) {
|
||||
|
||||
holder.assigneesName.setText(currentItem.getLogin());
|
||||
}
|
||||
else {
|
||||
|
||||
holder.assigneesName.setText(Html.fromHtml(currentItem.getFull_name()));
|
||||
}
|
||||
PicassoService
|
||||
.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(holder.assigneesAvatar);
|
||||
|
||||
for(int i = 0; i < assigneesList.size(); i++) {
|
||||
|
||||
if(assigneesStrings.contains(currentItem.getLogin())) {
|
||||
|
||||
holder.assigneesSelection.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
currentAssignees = new ArrayList<>(new LinkedHashSet<>(currentAssignees));
|
||||
|
||||
for(int i = 0; i < currentAssignees.size(); i++) {
|
||||
|
||||
if(currentAssignees.contains(currentItem.getLogin())) {
|
||||
|
||||
holder.assigneesSelection.setChecked(true);
|
||||
assigneesStrings.add(currentAssignees.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
assigneesListener.assigneesInterface(assigneesStrings);
|
||||
|
||||
holder.assigneesSelection.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
if(isChecked) {
|
||||
|
||||
assigneesStrings.add(currentItem.getLogin());
|
||||
}
|
||||
else {
|
||||
|
||||
assigneesStrings.remove(currentItem.getLogin());
|
||||
}
|
||||
|
||||
assigneesListener.assigneesInterface(assigneesStrings);
|
||||
});
|
||||
|
||||
assigneesStrings = new ArrayList<>(new LinkedHashSet<>(assigneesStrings));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return assigneesList.size();
|
||||
}
|
||||
|
||||
public void updateList(List<String> list) {
|
||||
|
||||
currentAssignees = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.CommitsActivity;
|
||||
import org.mian.gitnex.models.Branches;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class BranchesAdapter extends RecyclerView.Adapter<BranchesAdapter.BranchesViewHolder> {
|
||||
|
||||
private List<Branches> branchesList;
|
||||
private Context mCtx;
|
||||
|
||||
static class BranchesViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private TextView branchNameTv;
|
||||
private TextView branchCommitAuthor;
|
||||
|
||||
private BranchesViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
branchNameTv = itemView.findViewById(R.id.branchName);
|
||||
branchCommitAuthor = itemView.findViewById(R.id.branchCommitAuthor);
|
||||
TextView branchCommitHash = itemView.findViewById(R.id.branchCommitHash);
|
||||
|
||||
branchCommitHash.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
|
||||
Intent intent = new Intent(v.getContext(), CommitsActivity.class);
|
||||
intent.putExtra("branchName", String.valueOf(branchNameTv.getText()));
|
||||
Objects.requireNonNull(v.getContext()).startActivity(intent);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public BranchesAdapter(Context mCtx, List<Branches> branchesMain) {
|
||||
this.mCtx = mCtx;
|
||||
this.branchesList = branchesMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public BranchesAdapter.BranchesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_branches, parent, false);
|
||||
return new BranchesAdapter.BranchesViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull BranchesAdapter.BranchesViewHolder holder, int position) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(mCtx);
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
|
||||
Branches currentItem = branchesList.get(position);
|
||||
holder.branchNameTv.setText(currentItem.getName());
|
||||
|
||||
if(currentItem.getCommit().getAuthor().getName() != null || !currentItem.getCommit().getAuthor().getName().equals("")) {
|
||||
holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getName()));
|
||||
}
|
||||
else {
|
||||
holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getUsername()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return branchesList.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,15 +2,19 @@ package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import org.gitnex.tea4j.models.Collaborators;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.ProfileActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.models.Collaborators;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import java.util.List;
|
||||
|
||||
@@ -20,22 +24,37 @@ import java.util.List;
|
||||
|
||||
public class CollaboratorsAdapter extends BaseAdapter {
|
||||
|
||||
private List<Collaborators> collaboratorsList;
|
||||
private Context mCtx;
|
||||
private final List<Collaborators> collaboratorsList;
|
||||
private final Context context;
|
||||
|
||||
private class ViewHolder {
|
||||
|
||||
private ImageView collaboratorAvatar;
|
||||
private TextView collaboratorName;
|
||||
private String userLoginId;
|
||||
|
||||
private final ImageView collaboratorAvatar;
|
||||
private final TextView collaboratorName;
|
||||
|
||||
ViewHolder(View v) {
|
||||
|
||||
collaboratorAvatar = v.findViewById(R.id.collaboratorAvatar);
|
||||
collaboratorName = v.findViewById(R.id.collaboratorName);
|
||||
|
||||
collaboratorAvatar.setOnClickListener(loginId -> {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.putExtra("username", userLoginId);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
collaboratorAvatar.setOnLongClickListener(loginId -> {
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public CollaboratorsAdapter(Context mCtx, List<Collaborators> collaboratorsListMain) {
|
||||
this.mCtx = mCtx;
|
||||
public CollaboratorsAdapter(Context ctx, List<Collaborators> collaboratorsListMain) {
|
||||
|
||||
this.context = ctx;
|
||||
this.collaboratorsList = collaboratorsListMain;
|
||||
}
|
||||
|
||||
@@ -61,28 +80,35 @@ public class CollaboratorsAdapter extends BaseAdapter {
|
||||
ViewHolder viewHolder = null;
|
||||
|
||||
if (finalView == null) {
|
||||
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_collaborators, null);
|
||||
|
||||
finalView = LayoutInflater.from(context).inflate(R.layout.list_collaborators, null);
|
||||
viewHolder = new ViewHolder(finalView);
|
||||
finalView.setTag(viewHolder);
|
||||
}
|
||||
else {
|
||||
|
||||
viewHolder = (ViewHolder) finalView.getTag();
|
||||
}
|
||||
|
||||
initData(viewHolder, position);
|
||||
return finalView;
|
||||
|
||||
}
|
||||
|
||||
private void initData(ViewHolder viewHolder, int position) {
|
||||
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
Collaborators currentItem = collaboratorsList.get(position);
|
||||
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.collaboratorAvatar);
|
||||
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(viewHolder.collaboratorAvatar);
|
||||
|
||||
viewHolder.userLoginId = currentItem.getLogin();
|
||||
|
||||
if(!currentItem.getFull_name().equals("")) {
|
||||
viewHolder.collaboratorName.setText(currentItem.getFull_name());
|
||||
|
||||
viewHolder.collaboratorName.setText(Html.fromHtml(currentItem.getFull_name()));
|
||||
}
|
||||
else {
|
||||
|
||||
viewHolder.collaboratorName.setText(currentItem.getLogin());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.text.Html;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.mikepenz.fastadapter.FastAdapter;
|
||||
import com.mikepenz.fastadapter.items.AbstractItem;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import org.gitnex.tea4j.models.Commits;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.Date;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -20,142 +24,127 @@ import java.util.Locale;
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class CommitsAdapter extends AbstractItem<CommitsAdapter, CommitsAdapter.ViewHolder> {
|
||||
public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
final private Context ctx;
|
||||
private String commitTitle;
|
||||
private String commitHtmlUrl;
|
||||
private String commitCommitter;
|
||||
private Date commitDate;
|
||||
private final Context context;
|
||||
private final int TYPE_LOAD = 0;
|
||||
private List<Commits> commitsList;
|
||||
private CommitsAdapter.OnLoadMoreListener loadMoreListener;
|
||||
private boolean isLoading = false;
|
||||
private boolean isMoreDataAvailable = true;
|
||||
|
||||
private boolean isSelectable = true;
|
||||
public CommitsAdapter(Context ctx, List<Commits> commitsListMain) {
|
||||
|
||||
public CommitsAdapter(Context ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public CommitsAdapter withNewItems(String commitTitle, String commitHtmlUrl, String commitCommitter, Date commitDate) {
|
||||
|
||||
this.setNewItems(commitTitle, commitHtmlUrl, commitCommitter, commitDate);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
private void setNewItems(String commitTitle, String commitHtmlUrl, String commitCommitter, Date commitDate) {
|
||||
|
||||
this.commitTitle = commitTitle;
|
||||
this.commitHtmlUrl = commitHtmlUrl;
|
||||
this.commitCommitter = commitCommitter;
|
||||
this.commitDate = commitDate;
|
||||
|
||||
}
|
||||
|
||||
public String getCommitTitle() {
|
||||
return commitTitle;
|
||||
}
|
||||
|
||||
private String getCommitHtmlUrl() {
|
||||
return commitHtmlUrl;
|
||||
}
|
||||
|
||||
private String getcommitCommitter() {
|
||||
return commitCommitter;
|
||||
}
|
||||
|
||||
private Date getcommitDate() {
|
||||
return commitDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommitsAdapter withEnabled(boolean enabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return isSelectable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommitsAdapter withSelectable(boolean selectable) {
|
||||
|
||||
this.isSelectable = selectable;
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return R.id.commitList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayoutRes() {
|
||||
return R.layout.list_commits;
|
||||
this.context = ctx;
|
||||
this.commitsList = commitsListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public CommitsAdapter.ViewHolder getViewHolder(@NonNull View v) {
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
return new CommitsAdapter.ViewHolder(v);
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
|
||||
if(viewType == TYPE_LOAD) {
|
||||
return new CommitsHolder(inflater.inflate(R.layout.list_commits, parent, false));
|
||||
}
|
||||
else {
|
||||
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends FastAdapter.ViewHolder<CommitsAdapter> {
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(ctx);
|
||||
final String locale = tinyDb.getString("locale");
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
|
||||
isLoading = true;
|
||||
loadMoreListener.onLoadMore();
|
||||
}
|
||||
|
||||
TextView commitTitleVw;
|
||||
TextView commitCommitterVw;
|
||||
TextView commitDateVw;
|
||||
TextView commitHtmlUrlVw;
|
||||
if(getItemViewType(position) == TYPE_LOAD) {
|
||||
((CommitsHolder) holder).bindData(commitsList.get(position));
|
||||
}
|
||||
}
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
|
||||
if(commitsList.get(position).getSha() != null) {
|
||||
return TYPE_LOAD;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return commitsList.size();
|
||||
}
|
||||
|
||||
class CommitsHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView commitTitle;
|
||||
TextView commitCommitter;
|
||||
TextView commitDate;
|
||||
Button commitHtmlUrl;
|
||||
|
||||
CommitsHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
commitTitleVw = itemView.findViewById(R.id.commitTitleVw);
|
||||
commitCommitterVw = itemView.findViewById(R.id.commitCommitterVw);
|
||||
commitDateVw = itemView.findViewById(R.id.commitDateVw);
|
||||
commitHtmlUrlVw = itemView.findViewById(R.id.commitHtmlUrlVw);
|
||||
|
||||
commitTitle = itemView.findViewById(R.id.commitTitleVw);
|
||||
commitCommitter = itemView.findViewById(R.id.commitCommitterVw);
|
||||
commitDate = itemView.findViewById(R.id.commitDateVw);
|
||||
commitHtmlUrl = itemView.findViewById(R.id.commitHtmlUrlVw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(CommitsAdapter item, @NonNull List<Object> payloads) {
|
||||
@SuppressLint("SetTextI18n")
|
||||
void bindData(Commits commitsModel) {
|
||||
|
||||
commitTitleVw.setText(item.getCommitTitle());
|
||||
commitCommitterVw.setText(ctx.getString(R.string.commitCommittedBy, item.getcommitCommitter()));
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
Locale locale = context.getResources().getConfiguration().locale;
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
commitDateVw.setText(TimeHelper.formatTime(item.getcommitDate(), new Locale(locale), timeFormat, ctx));
|
||||
commitTitle.setText(EmojiParser.parseToUnicode(commitsModel.getCommit().getMessage()));
|
||||
commitCommitter.setText(context.getString(R.string.commitCommittedBy, commitsModel.getCommit().getCommitter().getName()));
|
||||
commitDate.setText(TimeHelper.formatTime(commitsModel.getCommit().getCommitter().getDate(), locale, timeFormat, context));
|
||||
|
||||
if(timeFormat.equals("pretty")) {
|
||||
commitDateVw.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getcommitDate()), ctx));
|
||||
commitDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(commitsModel.getCommit().getCommitter().getDate()), context));
|
||||
}
|
||||
|
||||
commitHtmlUrlVw.setText(Html.fromHtml("<a href='" + item.getCommitHtmlUrl() + "'>" + ctx.getResources().getString(R.string.viewInBrowser) + "</a> "));
|
||||
commitHtmlUrlVw.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbindView(@NonNull CommitsAdapter item) {
|
||||
|
||||
commitTitleVw.setText(null);
|
||||
commitCommitterVw.setText(null);
|
||||
commitDateVw.setText(null);
|
||||
commitHtmlUrlVw.setText(null);
|
||||
|
||||
commitHtmlUrl.setOnClickListener(v -> context.startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(commitsModel.getHtml_url()))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class LoadHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
LoadHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
public void setMoreDataAvailable(boolean moreDataAvailable) {
|
||||
isMoreDataAvailable = moreDataAvailable;
|
||||
}
|
||||
|
||||
public void notifyDataChanged() {
|
||||
notifyDataSetChanged();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
public interface OnLoadMoreListener {
|
||||
void onLoadMore();
|
||||
}
|
||||
|
||||
public void setLoadMoreListener(CommitsAdapter.OnLoadMoreListener loadMoreListener) {
|
||||
this.loadMoreListener = loadMoreListener;
|
||||
}
|
||||
|
||||
public void updateList(List<Commits> list) {
|
||||
commitsList = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.mian.gitnex.R;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class CreditsAdapter extends RecyclerView.Adapter<CreditsAdapter.CreditsViewHolder> {
|
||||
|
||||
private List<CharSequence> creditsList;
|
||||
|
||||
static class CreditsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private TextView creditText;
|
||||
|
||||
private CreditsViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
creditText = itemView.findViewById(R.id.creditText);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public CreditsAdapter(List<CharSequence> creditsListMain) {
|
||||
this.creditsList = creditsListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public CreditsAdapter.CreditsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.credits, parent, false);
|
||||
return new CreditsAdapter.CreditsViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull CreditsAdapter.CreditsViewHolder holder, int position) {
|
||||
|
||||
SpannableStringBuilder strBuilder = new SpannableStringBuilder(creditsList.get(position));
|
||||
holder.creditText.setText((strBuilder));
|
||||
holder.creditText.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return creditsList.size();
|
||||
}
|
||||
|
||||
}
|
||||
151
app/src/main/java/org/mian/gitnex/adapters/DraftsAdapter.java
Normal file
151
app/src/main/java/org/mian/gitnex/adapters/DraftsAdapter.java
Normal file
@@ -0,0 +1,151 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Spanned;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.IssueDetailActivity;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.DraftsApi;
|
||||
import org.mian.gitnex.database.models.DraftWithRepository;
|
||||
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
|
||||
import org.mian.gitnex.helpers.Markdown;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsViewHolder> {
|
||||
|
||||
private List<DraftWithRepository> draftsList;
|
||||
private final FragmentManager fragmentManager;
|
||||
private final Context context;
|
||||
|
||||
class DraftsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private DraftWithRepository draftWithRepository;
|
||||
|
||||
private final TextView draftText;
|
||||
private final TextView repoInfo;
|
||||
private final ImageView editCommentStatus;
|
||||
|
||||
private DraftsViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
draftText = itemView.findViewById(R.id.draftText);
|
||||
repoInfo = itemView.findViewById(R.id.repoInfo);
|
||||
ImageView deleteDraft = itemView.findViewById(R.id.deleteDraft);
|
||||
editCommentStatus = itemView.findViewById(R.id.editCommentStatus);
|
||||
|
||||
deleteDraft.setOnClickListener(itemDelete -> {
|
||||
|
||||
int getDraftId = draftWithRepository.getDraftId();
|
||||
deleteDraft(getAdapterPosition());
|
||||
|
||||
DraftsApi draftsApi = BaseApi.getInstance(context, DraftsApi.class);
|
||||
assert draftsApi != null;
|
||||
draftsApi.deleteSingleDraft(getDraftId);
|
||||
|
||||
});
|
||||
|
||||
itemView.setOnClickListener(itemEdit -> {
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
bundle.putString("commentBody", draftWithRepository.getDraftText());
|
||||
bundle.putString("issueNumber", String.valueOf(draftWithRepository.getIssueId()));
|
||||
bundle.putString("repositoryId", String.valueOf(draftWithRepository.getRepositoryId()));
|
||||
bundle.putString("draftTitle", repoInfo.getText().toString());
|
||||
bundle.putString("commentId", draftWithRepository.getCommentId());
|
||||
bundle.putString("draftId", String.valueOf(draftWithRepository.getDraftId()));
|
||||
|
||||
if(!draftWithRepository.getCommentId().isEmpty()) {
|
||||
bundle.putString("commentAction", "edit");
|
||||
}
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
tinyDb.putString("issueNumber", String.valueOf(draftWithRepository.getIssueId()));
|
||||
tinyDb.putLong("repositoryId", draftWithRepository.getRepositoryId());
|
||||
tinyDb.putString("issueType", draftWithRepository.getIssueType());
|
||||
tinyDb.putString("repoFullName", draftWithRepository.getRepositoryOwner() + "/" + draftWithRepository.getRepositoryName());
|
||||
|
||||
BottomSheetReplyFragment bottomSheetReplyFragment = BottomSheetReplyFragment.newInstance(bundle);
|
||||
bottomSheetReplyFragment.setOnInteractedListener(() -> context.startActivity(new Intent(context, IssueDetailActivity.class)));
|
||||
bottomSheetReplyFragment.show(fragmentManager, "replyBottomSheet");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DraftsAdapter(Context ctx, FragmentManager fragmentManager, List<DraftWithRepository> draftsListMain) {
|
||||
this.context = ctx;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.draftsList = draftsListMain;
|
||||
}
|
||||
|
||||
private void deleteDraft(int position) {
|
||||
|
||||
draftsList.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
notifyItemRangeChanged(position, draftsList.size());
|
||||
Toasty.success(context, context.getResources().getString(R.string.draftsSingleDeleteSuccess));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DraftsAdapter.DraftsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_drafts, parent, false);
|
||||
return new DraftsViewHolder(v);
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull DraftsAdapter.DraftsViewHolder holder, int position) {
|
||||
|
||||
DraftWithRepository currentItem = draftsList.get(position);
|
||||
|
||||
String issueNumber = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + context.getResources().getString(R.string.hash) + currentItem.getIssueId() + "</font>";
|
||||
Spanned headTitle = HtmlCompat
|
||||
.fromHtml(issueNumber + " " + currentItem.getRepositoryOwner() + " / " + currentItem.getRepositoryName(), HtmlCompat.FROM_HTML_MODE_LEGACY);
|
||||
|
||||
holder.repoInfo.setText(headTitle);
|
||||
holder.draftWithRepository = currentItem;
|
||||
|
||||
Markdown.render(context, currentItem.getDraftText(), holder.draftText);
|
||||
|
||||
if(!currentItem.getCommentId().equalsIgnoreCase("new")) {
|
||||
holder.editCommentStatus.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
holder.editCommentStatus.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return draftsList.size();
|
||||
}
|
||||
|
||||
public void updateList(List<DraftWithRepository> list) {
|
||||
|
||||
draftsList = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.Issues;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.IssueDetailActivity;
|
||||
import org.mian.gitnex.activities.ProfileActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class ExploreIssuesAdapter extends RecyclerView.Adapter<ExploreIssuesAdapter.SearchViewHolder> {
|
||||
|
||||
private final List<Issues> searchedList;
|
||||
private final Context context;
|
||||
private final TinyDB tinyDb;
|
||||
|
||||
public ExploreIssuesAdapter(List<Issues> dataList, Context ctx) {
|
||||
|
||||
this.context = ctx;
|
||||
this.searchedList = dataList;
|
||||
this.tinyDb = TinyDB.getInstance(context);
|
||||
}
|
||||
|
||||
class SearchViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private Issues issue;
|
||||
private final ImageView issueAssigneeAvatar;
|
||||
private final TextView issueTitle;
|
||||
private final TextView issueCreatedTime;
|
||||
private final TextView issueCommentsCount;
|
||||
|
||||
private SearchViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
|
||||
issueTitle = itemView.findViewById(R.id.issueTitle);
|
||||
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
|
||||
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(context, IssueDetailActivity.class);
|
||||
intent.putExtra("issueNumber", issue.getNumber());
|
||||
|
||||
tinyDb.putString("issueNumber", String.valueOf(issue.getNumber()));
|
||||
tinyDb.putString("issueType", "Issue");
|
||||
|
||||
tinyDb.putString("repoFullName", issue.getRepository().getFull_name());
|
||||
|
||||
String[] parts = issue.getRepository().getFull_name().split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
|
||||
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
|
||||
|
||||
assert repositoryData != null;
|
||||
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
|
||||
if(count == 0) {
|
||||
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDb.putLong("repositoryId", id);
|
||||
}
|
||||
else {
|
||||
|
||||
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDb.putLong("repositoryId", data.getRepositoryId());
|
||||
}
|
||||
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
issueAssigneeAvatar.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.putExtra("username", issue.getUser().getLogin());
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
issueAssigneeAvatar.setOnLongClickListener(loginId -> {
|
||||
AppUtil.copyToClipboard(context, issue.getUser().getLogin(), context.getString(R.string.copyLoginIdToClipBoard, issue.getUser().getLogin()));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ExploreIssuesAdapter.SearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_issues, parent, false);
|
||||
return new ExploreIssuesAdapter.SearchViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ExploreIssuesAdapter.SearchViewHolder holder, int position) {
|
||||
|
||||
Issues currentItem = searchedList.get(position);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
Locale locale = context.getResources().getConfiguration().locale;
|
||||
String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(currentItem.getUser().getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(imgRadius, 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop()
|
||||
.into(holder.issueAssigneeAvatar);
|
||||
|
||||
String issueNumber_ = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + currentItem.getRepository().getFull_name() + context.getResources().getString(R.string.hash) + currentItem.getNumber() + "</font>";
|
||||
|
||||
holder.issue = currentItem;
|
||||
holder.issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + currentItem.getTitle(), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
holder.issueCommentsCount.setText(String.valueOf(currentItem.getComments()));
|
||||
|
||||
switch(timeFormat) {
|
||||
case "pretty": {
|
||||
PrettyTime prettyTime = new PrettyTime(locale);
|
||||
String createdTime = prettyTime.format(currentItem.getCreated_at());
|
||||
holder.issueCreatedTime.setText(createdTime);
|
||||
holder.issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), context));
|
||||
break;
|
||||
}
|
||||
case "normal": {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
String createdTime = formatter.format(currentItem.getCreated_at());
|
||||
holder.issueCreatedTime.setText(createdTime);
|
||||
break;
|
||||
}
|
||||
case "normal1": {
|
||||
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
String createdTime = formatter.format(currentItem.getCreated_at());
|
||||
holder.issueCreatedTime.setText(createdTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return searchedList.size();
|
||||
}
|
||||
|
||||
public void notifyDataChanged() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.Organization;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.OrganizationDetailActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class ExplorePublicOrganizationsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private final Context context;
|
||||
private final int TYPE_LOAD = 0;
|
||||
private List<Organization> organizationsList;
|
||||
private OnLoadMoreListener loadMoreListener;
|
||||
private boolean isLoading = false, isMoreDataAvailable = true;
|
||||
|
||||
public ExplorePublicOrganizationsAdapter(Context ctx, List<Organization> organizationsListMain) {
|
||||
this.context = ctx;
|
||||
this.organizationsList = organizationsListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
if(viewType == TYPE_LOAD) {
|
||||
return new ExplorePublicOrganizationsAdapter.OrganizationsHolder(inflater.inflate(R.layout.list_organizations, parent, false));
|
||||
}
|
||||
else {
|
||||
return new ExplorePublicOrganizationsAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
|
||||
isLoading = true;
|
||||
loadMoreListener.onLoadMore();
|
||||
}
|
||||
|
||||
if(getItemViewType(position) == TYPE_LOAD) {
|
||||
((ExplorePublicOrganizationsAdapter.OrganizationsHolder) holder).bindData(organizationsList.get(position));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if(organizationsList.get(position).getFull_name() != null) {
|
||||
return TYPE_LOAD;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return organizationsList.size();
|
||||
}
|
||||
|
||||
class OrganizationsHolder extends RecyclerView.ViewHolder {
|
||||
private Organization organization;
|
||||
private final ImageView image;
|
||||
private final TextView orgName;
|
||||
private final TextView orgDescription;
|
||||
|
||||
OrganizationsHolder(View itemView) {
|
||||
super(itemView);
|
||||
image = itemView.findViewById(R.id.imageAvatar);
|
||||
orgName = itemView.findViewById(R.id.orgName);
|
||||
orgDescription = itemView.findViewById(R.id.orgDescription);
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
Context context = v.getContext();
|
||||
Intent intent = new Intent(context, OrganizationDetailActivity.class);
|
||||
intent.putExtra("orgName", organization.getUsername());
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
tinyDb.putString("orgName", organization.getUsername());
|
||||
tinyDb.putString("organizationId", String.valueOf(organization.getId()));
|
||||
tinyDb.putBoolean("organizationAction", true);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
void bindData(Organization organization) {
|
||||
this.organization = organization;
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
orgName.setText(organization.getUsername());
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(organization.getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(imgRadius, 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop()
|
||||
.into(image);
|
||||
if (!organization.getDescription().equals("")) {
|
||||
orgDescription.setText(organization.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class LoadHolder extends RecyclerView.ViewHolder {
|
||||
LoadHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
public void setMoreDataAvailable(boolean moreDataAvailable) {
|
||||
isMoreDataAvailable = moreDataAvailable;
|
||||
}
|
||||
|
||||
public void notifyDataChanged() {
|
||||
notifyDataSetChanged();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
public interface OnLoadMoreListener {
|
||||
void onLoadMore();
|
||||
}
|
||||
|
||||
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
|
||||
this.loadMoreListener = loadMoreListener;
|
||||
}
|
||||
|
||||
public void updateList(List<Organization> list) {
|
||||
organizationsList = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
@@ -14,20 +13,26 @@ import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import org.gitnex.tea4j.models.UserRepositories;
|
||||
import org.gitnex.tea4j.models.WatchInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
|
||||
import org.mian.gitnex.activities.RepoDetailActivity;
|
||||
import org.mian.gitnex.activities.RepoStargazersActivity;
|
||||
import org.mian.gitnex.activities.RepoWatchersActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.UserRepositories;
|
||||
import org.mian.gitnex.models.WatchRepository;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@@ -37,153 +42,115 @@ import retrofit2.Callback;
|
||||
|
||||
public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepositoriesAdapter.ReposSearchViewHolder> {
|
||||
|
||||
private final List<UserRepositories> reposList;
|
||||
private final Context context;
|
||||
|
||||
private List<UserRepositories> searchedReposList;
|
||||
private Context mCtx;
|
||||
public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context ctx) {
|
||||
|
||||
public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context mCtx) {
|
||||
|
||||
this.mCtx = mCtx;
|
||||
this.searchedReposList = dataList;
|
||||
this.context = ctx;
|
||||
this.reposList = dataList;
|
||||
}
|
||||
|
||||
static class ReposSearchViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private ImageView image;
|
||||
private TextView repoName;
|
||||
private TextView repoDescription;
|
||||
private TextView fullName;
|
||||
private UserRepositories userRepositories;
|
||||
|
||||
private final ImageView image;
|
||||
private final TextView repoName;
|
||||
private final TextView orgName;
|
||||
private final TextView repoDescription;
|
||||
private CheckBox isRepoAdmin;
|
||||
private ImageView repoPrivatePublic;
|
||||
private TextView repoStars;
|
||||
private TextView repoForks;
|
||||
private TextView repoOpenIssuesCount;
|
||||
private final TextView repoStars;
|
||||
private final TextView repoLastUpdated;
|
||||
|
||||
private ReposSearchViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
repoName = itemView.findViewById(R.id.repoName);
|
||||
orgName = itemView.findViewById(R.id.orgName);
|
||||
repoDescription = itemView.findViewById(R.id.repoDescription);
|
||||
image = itemView.findViewById(R.id.imageAvatar);
|
||||
fullName = itemView.findViewById(R.id.repoFullName);
|
||||
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
|
||||
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
|
||||
image = itemView.findViewById(R.id.imageAvatar);
|
||||
repoStars = itemView.findViewById(R.id.repoStars);
|
||||
repoForks = itemView.findViewById(R.id.repoForks);
|
||||
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
|
||||
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
|
||||
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
|
||||
Context context = v.getContext();
|
||||
TextView repoFullName = v.findViewById(R.id.repoFullName);
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
Intent intent = new Intent(context, RepoDetailActivity.class);
|
||||
intent.putExtra("repoFullName", repoFullName.getText().toString());
|
||||
intent.putExtra("repoFullName", userRepositories.getFullName());
|
||||
|
||||
TinyDB tinyDb = new TinyDB(context);
|
||||
tinyDb.putString("repoFullName", repoFullName.getText().toString());
|
||||
tinyDb.putString("repoFullName", userRepositories.getFullName());
|
||||
tinyDb.putBoolean("resumeIssues", true);
|
||||
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
|
||||
tinyDb.putString("repoBranch", userRepositories.getDefault_branch());
|
||||
|
||||
if(userRepositories.getPrivateFlag()) {
|
||||
tinyDb.putString("repoType", context.getResources().getString(R.string.strPrivate));
|
||||
}
|
||||
else {
|
||||
tinyDb.putString("repoType", context.getResources().getString(R.string.strPublic));
|
||||
}
|
||||
|
||||
String[] parts = userRepositories.getFullName().split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
|
||||
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
|
||||
|
||||
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
|
||||
assert repositoryData != null;
|
||||
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
|
||||
if(count == 0) {
|
||||
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDb.putLong("repositoryId", id);
|
||||
}
|
||||
else {
|
||||
|
||||
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDb.putLong("repositoryId", data.getRepositoryId());
|
||||
}
|
||||
|
||||
//store if user is watching this repo
|
||||
{
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
String[] parts = repoFullName.getText().toString().split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
|
||||
|
||||
WatchRepository watch = new WatchRepository();
|
||||
|
||||
Call<WatchRepository> call;
|
||||
|
||||
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<WatchRepository>() {
|
||||
WatchInfo watch = new WatchInfo();
|
||||
Call<WatchInfo> call;
|
||||
call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<WatchInfo>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
|
||||
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
|
||||
|
||||
} else {
|
||||
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
|
||||
if(response.code() != 404) {
|
||||
|
||||
Toasty.info(context, context.getString(R.string.genericApiStatusError));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
if(response.code() != 404) {
|
||||
Toasty.error(context, context.getString(R.string.genericApiStatusError));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
|
||||
|
||||
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
Toasty.info(context, context.getString(R.string.genericApiStatusError));
|
||||
|
||||
Toasty.error(context, context.getString(R.string.genericApiStatusError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
context.startActivity(intent);
|
||||
|
||||
});
|
||||
|
||||
reposDropdownMenu.setOnClickListener(v -> {
|
||||
|
||||
final Context context = v.getContext();
|
||||
|
||||
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
|
||||
|
||||
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
|
||||
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
|
||||
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
|
||||
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
|
||||
|
||||
bottomSheetHeader.setText(fullName.getText());
|
||||
BottomSheetDialog dialog = new BottomSheetDialog(context);
|
||||
dialog.setContentView(view);
|
||||
dialog.show();
|
||||
|
||||
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
|
||||
|
||||
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
|
||||
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
|
||||
context.startActivity(intentOpenInBrowser);
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
repoStargazers.setOnClickListener(stargazers -> {
|
||||
|
||||
Intent intent = new Intent(context, RepoStargazersActivity.class);
|
||||
intent.putExtra("repoFullNameForStars", fullName.getText());
|
||||
context.startActivity(intent);
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
repoWatchers.setOnClickListener(watchers -> {
|
||||
|
||||
Intent intentW = new Intent(context, RepoWatchersActivity.class);
|
||||
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
|
||||
context.startActivity(intentW);
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -192,27 +159,33 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
|
||||
@Override
|
||||
public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repos, parent, false);
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
|
||||
return new ExploreRepositoriesAdapter.ReposSearchViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ExploreRepositoriesAdapter.ReposSearchViewHolder holder, int position) {
|
||||
|
||||
final UserRepositories currentItem = searchedReposList.get(position);
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
UserRepositories currentItem = reposList.get(position);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
|
||||
holder.repoDescription.setVisibility(View.GONE);
|
||||
Locale locale = context.getResources().getConfiguration().locale;
|
||||
String timeFormat = tinyDb.getString("dateFormat");
|
||||
holder.userRepositories = currentItem;
|
||||
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
|
||||
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
|
||||
holder.repoStars.setText(currentItem.getStars_count());
|
||||
|
||||
ColorGenerator generator = ColorGenerator.MATERIAL;
|
||||
int color = generator.getColor(currentItem.getName());
|
||||
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
|
||||
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
|
||||
|
||||
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
|
||||
|
||||
if(currentItem.getAvatar_url() != null) {
|
||||
if(!currentItem.getAvatar_url().equals("")) {
|
||||
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
|
||||
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
|
||||
}
|
||||
else {
|
||||
holder.image.setImageDrawable(drawable);
|
||||
@@ -222,32 +195,56 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
|
||||
holder.image.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
holder.repoName.setText(currentItem.getName());
|
||||
if(!currentItem.getDescription().equals("")) {
|
||||
holder.repoDescription.setVisibility(View.VISIBLE);
|
||||
holder.repoDescription.setText(currentItem.getDescription());
|
||||
}
|
||||
holder.fullName.setText(currentItem.getFullname());
|
||||
if(currentItem.getPrivateFlag()) {
|
||||
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
|
||||
if(currentItem.getUpdated_at() != null) {
|
||||
|
||||
switch(timeFormat) {
|
||||
case "pretty": {
|
||||
PrettyTime prettyTime = new PrettyTime(locale);
|
||||
String createdTime = prettyTime.format(currentItem.getUpdated_at());
|
||||
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
|
||||
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
|
||||
break;
|
||||
}
|
||||
case "normal": {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
String createdTime = formatter.format(currentItem.getUpdated_at());
|
||||
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
|
||||
break;
|
||||
}
|
||||
case "normal1": {
|
||||
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
String createdTime = formatter.format(currentItem.getUpdated_at());
|
||||
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
|
||||
holder.repoLastUpdated.setVisibility(View.GONE);
|
||||
}
|
||||
holder.repoStars.setText(currentItem.getStars_count());
|
||||
holder.repoForks.setText(currentItem.getForks_count());
|
||||
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
|
||||
|
||||
if(!currentItem.getDescription().equals("")) {
|
||||
holder.repoDescription.setText(currentItem.getDescription());
|
||||
}
|
||||
else {
|
||||
holder.repoDescription.setText(context.getString(R.string.noDataDescription));
|
||||
}
|
||||
|
||||
if(holder.isRepoAdmin == null) {
|
||||
holder.isRepoAdmin = new CheckBox(mCtx);
|
||||
holder.isRepoAdmin = new CheckBox(context);
|
||||
}
|
||||
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return searchedReposList.size();
|
||||
return reposList.size();
|
||||
}
|
||||
|
||||
public void notifyDataChanged() {
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,13 +7,14 @@ 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 androidx.annotation.NonNull;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.gitnex.tea4j.models.Files;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.Files;
|
||||
import org.mian.gitnex.util.AppUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -23,54 +24,39 @@ import java.util.List;
|
||||
|
||||
public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHolder> implements Filterable {
|
||||
|
||||
private List<Files> filesList;
|
||||
private Context mCtx;
|
||||
private List<Files> filesListFull;
|
||||
private final List<Files> originalFiles = new ArrayList<>();
|
||||
private final List<Files> alteredFiles = new ArrayList<>();
|
||||
|
||||
private FilesAdapterListener filesListener;
|
||||
private final Context context;
|
||||
|
||||
private final FilesAdapterListener filesListener;
|
||||
|
||||
public interface FilesAdapterListener {
|
||||
void onClickDir(String str);
|
||||
void onClickFile(String str);
|
||||
|
||||
void onClickFile(Files file);
|
||||
}
|
||||
|
||||
class FilesViewHolder extends RecyclerView.ViewHolder {
|
||||
class FilesViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private ImageView fileTypeImage;
|
||||
private TextView fileName;
|
||||
private TextView fileType;
|
||||
private TextView fileInfo;
|
||||
private Files file;
|
||||
|
||||
private final ImageView fileTypeIs;
|
||||
private final TextView fileName;
|
||||
private final TextView fileInfo;
|
||||
|
||||
private FilesViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
LinearLayout fileFrame = itemView.findViewById(R.id.fileFrame);
|
||||
fileName = itemView.findViewById(R.id.fileName);
|
||||
fileTypeImage = itemView.findViewById(R.id.fileImage);
|
||||
fileType = itemView.findViewById(R.id.fileType);
|
||||
fileTypeIs = itemView.findViewById(R.id.fileTypeIs);
|
||||
fileInfo = itemView.findViewById(R.id.fileInfo);
|
||||
|
||||
fileFrame.setOnClickListener(v -> filesListener.onClickFile(file));
|
||||
|
||||
//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) {
|
||||
@@ -137,13 +123,24 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
|
||||
}
|
||||
}
|
||||
|
||||
public FilesAdapter(Context mCtx, List<Files> filesListMain, FilesAdapterListener filesListener) {
|
||||
this.mCtx = mCtx;
|
||||
this.filesList = filesListMain;
|
||||
filesListFull = new ArrayList<>(filesList);
|
||||
public FilesAdapter(Context ctx, FilesAdapterListener filesListener) {
|
||||
|
||||
this.context = ctx;
|
||||
this.filesListener = filesListener;
|
||||
}
|
||||
|
||||
public List<Files> getOriginalFiles() {
|
||||
return originalFiles;
|
||||
}
|
||||
|
||||
public void notifyOriginalDataSetChanged() {
|
||||
|
||||
alteredFiles.clear();
|
||||
alteredFiles.addAll(originalFiles);
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public FilesAdapter.FilesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
@@ -154,28 +151,43 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull FilesAdapter.FilesViewHolder holder, int position) {
|
||||
|
||||
Files currentItem = filesList.get(position);
|
||||
Files currentItem = alteredFiles.get(position);
|
||||
|
||||
holder.fileType.setText(currentItem.getType());
|
||||
holder.file = currentItem;
|
||||
holder.fileName.setText(currentItem.getName());
|
||||
|
||||
if(currentItem.getType().equals("file")) {
|
||||
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_file_new));
|
||||
holder.fileInfo.setVisibility(View.VISIBLE);
|
||||
holder.fileInfo.setText(AppUtil.formatFileSizeInDetail(currentItem.getSize()));
|
||||
}
|
||||
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));
|
||||
}
|
||||
switch(currentItem.getType()) {
|
||||
|
||||
case "file":
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_file));
|
||||
holder.fileInfo.setVisibility(View.VISIBLE);
|
||||
holder.fileInfo.setText(FileUtils.byteCountToDisplaySize(currentItem.getSize()));
|
||||
break;
|
||||
|
||||
case "dir":
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_directory));
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
case "submodule":
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_submodule));
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
case "symlink":
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_symlink));
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
default:
|
||||
holder.fileTypeIs.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.ic_question));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return filesList.size();
|
||||
return alteredFiles.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,17 +195,19 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
|
||||
return filesFilter;
|
||||
}
|
||||
|
||||
private Filter filesFilter = new Filter() {
|
||||
private final Filter filesFilter = new Filter() {
|
||||
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
|
||||
List<Files> filteredList = new ArrayList<>();
|
||||
|
||||
if (constraint == null || constraint.length() == 0) {
|
||||
filteredList.addAll(filesListFull);
|
||||
filteredList.addAll(originalFiles);
|
||||
} else {
|
||||
String filterPattern = constraint.toString().toLowerCase().trim();
|
||||
|
||||
for (Files item : filesListFull) {
|
||||
for (Files item : originalFiles) {
|
||||
if (item.getName().toLowerCase().contains(filterPattern) || item.getPath().toLowerCase().contains(filterPattern)) {
|
||||
filteredList.add(item);
|
||||
}
|
||||
@@ -204,14 +218,19 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
|
||||
results.values = filteredList;
|
||||
|
||||
return results;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
filesList.clear();
|
||||
filesList.addAll((List) results.values);
|
||||
|
||||
alteredFiles.clear();
|
||||
alteredFiles.addAll((List) results.values);
|
||||
|
||||
notifyDataSetChanged();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,139 +1,252 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.models.FileDiffView;
|
||||
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.views.DiffTextView;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
* Author opyale
|
||||
*/
|
||||
|
||||
public class FilesDiffAdapter extends RecyclerView.Adapter<FilesDiffAdapter.FilesDiffViewHolder> {
|
||||
public class FilesDiffAdapter extends BaseAdapter {
|
||||
|
||||
private List<FileDiffView> dataList;
|
||||
private Context ctx;
|
||||
private static Map<Long, View> selectedViews;
|
||||
private static final int MAXIMUM_LINES = 5000;
|
||||
|
||||
static class FilesDiffViewHolder extends RecyclerView.ViewHolder {
|
||||
private static int COLOR_ADDED;
|
||||
private static int COLOR_REMOVED;
|
||||
private static int COLOR_NORMAL;
|
||||
private static int COLOR_SELECTED;
|
||||
private static int COLOR_FONT;
|
||||
|
||||
private TextView fileContents;
|
||||
private TextView fileName;
|
||||
private TextView fileInfo;
|
||||
private ImageView fileImage;
|
||||
private HorizontalScrollView fileContentsView;
|
||||
private LinearLayout allLines;
|
||||
private final Context context;
|
||||
private final FragmentManager fragmentManager;
|
||||
private final List<FileDiffView> fileDiffViews;
|
||||
|
||||
private FilesDiffViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
public FilesDiffAdapter(Context context, FragmentManager fragmentManager, List<FileDiffView> fileDiffViews) {
|
||||
|
||||
fileContents = itemView.findViewById(R.id.fileContents);
|
||||
fileName = itemView.findViewById(R.id.fileName);
|
||||
fileInfo = itemView.findViewById(R.id.fileInfo);
|
||||
fileImage = itemView.findViewById(R.id.fileImage);
|
||||
fileContentsView = itemView.findViewById(R.id.fileContentsView);
|
||||
allLines = itemView.findViewById(R.id.allLinesLayout);
|
||||
this.context = context;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.fileDiffViews = fileDiffViews;
|
||||
|
||||
}
|
||||
}
|
||||
selectedViews = new ConcurrentSkipListMap<>();
|
||||
|
||||
public FilesDiffAdapter(List<FileDiffView> dataListMain, Context ctx) {
|
||||
this.dataList = dataListMain;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
COLOR_ADDED = AppUtil.getColorFromAttribute(context, R.attr.diffAddedColor);
|
||||
COLOR_REMOVED = AppUtil.getColorFromAttribute(context, R.attr.diffRemovedColor);
|
||||
COLOR_NORMAL = AppUtil.getColorFromAttribute(context, R.attr.primaryBackgroundColor);
|
||||
COLOR_SELECTED = AppUtil.getColorFromAttribute(context, R.attr.diffSelectedColor);
|
||||
COLOR_FONT = AppUtil.getColorFromAttribute(context, R.attr.inputTextColor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public FilesDiffAdapter.FilesDiffViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_files_diffs, parent, false);
|
||||
return new FilesDiffAdapter.FilesDiffViewHolder(v);
|
||||
}
|
||||
@Override
|
||||
public int getCount() {
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull FilesDiffViewHolder holder, int position) {
|
||||
return fileDiffViews.size();
|
||||
}
|
||||
|
||||
holder.setIsRecyclable(false);
|
||||
FileDiffView data = dataList.get(position);
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
|
||||
if(data.isFileType()) {
|
||||
return fileDiffViews.get(position);
|
||||
}
|
||||
|
||||
holder.fileName.setText(data.getFileName());
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
return position;
|
||||
}
|
||||
|
||||
//byte[] imageData = Base64.decode(data.getFileContents(), Base64.DEFAULT);
|
||||
//Drawable imageDrawable = new BitmapDrawable(ctx.getResources(), BitmapFactory.decodeByteArray(imageData, 0, imageData.length));
|
||||
//holder.fileImage.setImageDrawable(imageDrawable);
|
||||
holder.fileContentsView.setVisibility(View.GONE);
|
||||
@SuppressLint({"ViewHolder", "InflateParams"})
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
|
||||
}
|
||||
else {
|
||||
convertView = LayoutInflater.from(context).inflate(R.layout.list_files_diffs, null, false);
|
||||
|
||||
String[] splitData = data.getFileContents().split("\\R");
|
||||
TextView headerFileName = convertView.findViewById(R.id.headerFileName);
|
||||
TextView headerFileInfo = convertView.findViewById(R.id.headerFileInfo);
|
||||
ImageView footerImage = convertView.findViewById(R.id.footerImage);
|
||||
LinearLayout diffStats = convertView.findViewById(R.id.diff_stats);
|
||||
LinearLayout diffLines = convertView.findViewById(R.id.diffLines);
|
||||
|
||||
for (String eachSplit : splitData) {
|
||||
FileDiffView data = (FileDiffView) getItem(position);
|
||||
headerFileName.setText(data.getFileName());
|
||||
|
||||
TextView textLine = new TextView(ctx);
|
||||
textLine.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
if(data.isFileBinary()) {
|
||||
|
||||
if (eachSplit.startsWith("+")) {
|
||||
diffStats.setVisibility(View.GONE);
|
||||
diffLines.addView(getMessageView(context.getResources().getString(R.string.binaryFileError)));
|
||||
}
|
||||
else {
|
||||
|
||||
textLine.setText(eachSplit);
|
||||
holder.allLines.addView(textLine);
|
||||
diffStats.setVisibility(View.VISIBLE);
|
||||
headerFileInfo.setText(data.getFileInfo());
|
||||
|
||||
textLine.setTextColor(ctx.getResources().getColor(R.color.colorPrimary));
|
||||
textLine.setPadding(5, 5, 5, 5);
|
||||
textLine.setBackgroundColor(ctx.getResources().getColor(R.color.diffAddedColor));
|
||||
String[] codeLines = getLines(data.toString());
|
||||
|
||||
}
|
||||
else if (eachSplit.startsWith("-")) {
|
||||
if(MAXIMUM_LINES > codeLines.length) {
|
||||
|
||||
textLine.setText(eachSplit);
|
||||
holder.allLines.addView(textLine);
|
||||
for(int l=0; l<codeLines.length; l++) {
|
||||
|
||||
textLine.setTextColor(ctx.getResources().getColor(R.color.colorPrimary));
|
||||
textLine.setPadding(5, 5, 5, 5);
|
||||
textLine.setBackgroundColor(ctx.getResources().getColor(R.color.diffRemovedColor));
|
||||
if(codeLines[l].length() > 0) {
|
||||
|
||||
}
|
||||
else {
|
||||
int uniquePosition = l + (position * MAXIMUM_LINES);
|
||||
|
||||
if(eachSplit.length() > 0) {
|
||||
textLine.setText(eachSplit);
|
||||
holder.allLines.addView(textLine);
|
||||
DiffTextView diffTextView = new DiffTextView(context);
|
||||
|
||||
textLine.setTextColor(ctx.getResources().getColor(R.color.colorPrimary));
|
||||
textLine.setPadding(5, 5, 5, 5);
|
||||
textLine.setBackgroundColor(ctx.getResources().getColor(R.color.white));
|
||||
}
|
||||
diffTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
|
||||
diffTextView.setPadding(15, 2, 15, 2);
|
||||
diffTextView.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf"));
|
||||
diffTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
diffTextView.setPosition(uniquePosition);
|
||||
|
||||
}
|
||||
boolean isSelected = false;
|
||||
|
||||
}
|
||||
for(View view : selectedViews.values()) {
|
||||
|
||||
holder.fileName.setText(data.getFileName());
|
||||
if(!data.getFileInfo().equals("")) {
|
||||
holder.fileInfo.setText(ctx.getResources().getString(R.string.fileDiffInfoChanges, data.getFileInfo()));
|
||||
}
|
||||
else {
|
||||
holder.fileInfo.setVisibility(View.GONE);
|
||||
}
|
||||
if(((DiffTextView) view).getPosition() == uniquePosition) {
|
||||
|
||||
}
|
||||
diffTextView.setBackgroundColor(COLOR_SELECTED);
|
||||
isSelected = true;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataList.size();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(codeLines[l].startsWith("+")) {
|
||||
|
||||
diffTextView.setText(codeLines[l]);
|
||||
diffTextView.setTextColor(COLOR_FONT);
|
||||
|
||||
if(!isSelected) {
|
||||
|
||||
diffTextView.setInitialBackgroundColor(COLOR_ADDED);
|
||||
}
|
||||
|
||||
}
|
||||
else if(codeLines[l].startsWith("-")) {
|
||||
|
||||
diffTextView.setText(codeLines[l]);
|
||||
diffTextView.setTextColor(COLOR_FONT);
|
||||
|
||||
if(!isSelected) {
|
||||
|
||||
diffTextView.setInitialBackgroundColor(COLOR_REMOVED);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
diffTextView.setText(codeLines[l]);
|
||||
diffTextView.setTextColor(COLOR_FONT);
|
||||
|
||||
if(!isSelected) {
|
||||
|
||||
diffTextView.setInitialBackgroundColor(COLOR_NORMAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
diffTextView.setOnClickListener(v -> {
|
||||
|
||||
if(((DiffTextView) v).getCurrentBackgroundColor() != COLOR_SELECTED) {
|
||||
|
||||
selectedViews.put(((DiffTextView) v).getPosition(), v);
|
||||
v.setBackgroundColor(COLOR_SELECTED);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
selectedViews.remove(((DiffTextView) v).getPosition());
|
||||
v.setBackgroundColor(((DiffTextView) v).getInitialBackgroundColor());
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
diffTextView.setOnLongClickListener(v -> {
|
||||
|
||||
if(((DiffTextView) v).getCurrentBackgroundColor() == COLOR_SELECTED) {
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("```\n");
|
||||
|
||||
for(View view : selectedViews.values()) {
|
||||
|
||||
stringBuilder.append(((DiffTextView) view).getText());
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
|
||||
stringBuilder.append("```\n\n");
|
||||
|
||||
selectedViews.clear();
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("commentBody", stringBuilder.toString());
|
||||
bundle.putBoolean("cursorToEnd", true);
|
||||
|
||||
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
diffLines.addView(diffTextView);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
diffLines.addView(getMessageView(context.getResources().getString(R.string.fileTooLarge)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return convertView;
|
||||
|
||||
}
|
||||
|
||||
private TextView getMessageView(String message) {
|
||||
|
||||
TextView textView = new TextView(context);
|
||||
|
||||
textView.setTextColor(COLOR_FONT);
|
||||
textView.setBackgroundColor(COLOR_NORMAL);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
textView.setPadding(15, 15, 15, 15);
|
||||
textView.setTypeface(Typeface.DEFAULT);
|
||||
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
textView.setText(message);
|
||||
|
||||
return textView;
|
||||
}
|
||||
|
||||
private String[] getLines(String content) {
|
||||
|
||||
return content.split("\\R");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,55 +1,43 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.text.Spanned;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import org.gitnex.tea4j.models.IssueComments;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.ReplyToIssueActivity;
|
||||
import org.mian.gitnex.activities.ProfileActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.helpers.UserMentions;
|
||||
import org.mian.gitnex.models.IssueComments;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Markdown;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
import java.sql.Time;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.views.ReactionList;
|
||||
import org.mian.gitnex.views.ReactionSpinner;
|
||||
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 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;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -57,103 +45,249 @@ import io.noties.markwon.linkify.LinkifyPlugin;
|
||||
|
||||
public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> {
|
||||
|
||||
private List<IssueComments> issuesComments;
|
||||
private Context mCtx;
|
||||
private final Context context;
|
||||
private final TinyDB tinyDB;
|
||||
private final Bundle bundle;
|
||||
private final List<IssueComments> issuesComments;
|
||||
private final FragmentManager fragmentManager;
|
||||
private final BottomSheetReplyFragment.OnInteractedListener onInteractedListener;
|
||||
private final Locale locale;
|
||||
|
||||
static class IssueCommentViewHolder extends RecyclerView.ViewHolder {
|
||||
public IssueCommentsAdapter(Context ctx, Bundle bundle, List<IssueComments> issuesCommentsMain, FragmentManager fragmentManager, BottomSheetReplyFragment.OnInteractedListener onInteractedListener) {
|
||||
|
||||
private TextView issueNumber;
|
||||
private TextView commendId;
|
||||
private ImageView issueCommenterAvatar;
|
||||
private TextView issueComment;
|
||||
private TextView issueCommentDate;
|
||||
private ImageView commentsOptionsMenu;
|
||||
private TextView commendBodyRaw;
|
||||
private TextView commentModified;
|
||||
private TextView commenterUsername;
|
||||
private TextView htmlUrl;
|
||||
this.context = ctx;
|
||||
this.bundle = bundle;
|
||||
this.issuesComments = issuesCommentsMain;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.onInteractedListener = onInteractedListener;
|
||||
tinyDB = TinyDB.getInstance(ctx);
|
||||
locale = ctx.getResources().getConfiguration().locale;
|
||||
}
|
||||
|
||||
private IssueCommentViewHolder(View itemView) {
|
||||
class IssueCommentViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
super(itemView);
|
||||
private String userLoginId;
|
||||
private IssueComments issueComment;
|
||||
|
||||
issueNumber = itemView.findViewById(R.id.issueNumber);
|
||||
commendId = itemView.findViewById(R.id.commendId);
|
||||
issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar);
|
||||
issueComment = itemView.findViewById(R.id.issueComment);
|
||||
issueCommentDate = itemView.findViewById(R.id.issueCommentDate);
|
||||
commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu);
|
||||
commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw);
|
||||
commentModified = itemView.findViewById(R.id.commentModified);
|
||||
commenterUsername = itemView.findViewById(R.id.commenterUsername);
|
||||
htmlUrl = itemView.findViewById(R.id.htmlUrl);
|
||||
private final ImageView avatar;
|
||||
private final TextView author;
|
||||
private final TextView information;
|
||||
private final TextView comment;
|
||||
private final LinearLayout commentReactionBadges;
|
||||
|
||||
commentsOptionsMenu.setOnClickListener(v -> {
|
||||
private IssueCommentViewHolder(View view) {
|
||||
|
||||
final Context context = v.getContext();
|
||||
final TinyDB tinyDb = new TinyDB(context);
|
||||
final String loginUid = tinyDb.getString("loginUid");
|
||||
super(view);
|
||||
|
||||
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_issue_comments, null);
|
||||
avatar = view.findViewById(R.id.avatar);
|
||||
author = view.findViewById(R.id.author);
|
||||
information = view.findViewById(R.id.information);
|
||||
ImageView menu = view.findViewById(R.id.menu);
|
||||
comment = view.findViewById(R.id.comment);
|
||||
commentReactionBadges = view.findViewById(R.id.commentReactionBadges);
|
||||
|
||||
TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit);
|
||||
TextView commentShare = view.findViewById(R.id.issueCommentShare);
|
||||
//TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete);
|
||||
menu.setOnClickListener(v -> {
|
||||
|
||||
if(!loginUid.contentEquals(commenterUsername.getText())) {
|
||||
final String loginUid = tinyDB.getString("loginUid");
|
||||
|
||||
@SuppressLint("InflateParams") View vw = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_issue_comments, null);
|
||||
|
||||
TextView commentMenuEdit = vw.findViewById(R.id.commentMenuEdit);
|
||||
TextView commentShare = vw.findViewById(R.id.issueCommentShare);
|
||||
TextView commentMenuQuote = vw.findViewById(R.id.commentMenuQuote);
|
||||
TextView commentMenuCopy = vw.findViewById(R.id.commentMenuCopy);
|
||||
TextView commentMenuDelete = vw.findViewById(R.id.commentMenuDelete);
|
||||
TextView issueCommentCopyUrl = vw.findViewById(R.id.issueCommentCopyUrl);
|
||||
|
||||
if(!loginUid.contentEquals(issueComment.getUser().getUsername())) {
|
||||
commentMenuEdit.setVisibility(View.GONE);
|
||||
//commentMenuDelete.setVisibility(View.GONE);
|
||||
commentMenuDelete.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(issueComment.getBody().isEmpty()) {
|
||||
commentMenuCopy.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
BottomSheetDialog dialog = new BottomSheetDialog(context);
|
||||
dialog.setContentView(view);
|
||||
dialog.setContentView(vw);
|
||||
dialog.show();
|
||||
|
||||
commentMenuEdit.setOnClickListener(ediComment -> {
|
||||
LinearLayout linearLayout = vw.findViewById(R.id.commentReactionButtons);
|
||||
|
||||
Intent intent = new Intent(context, ReplyToIssueActivity.class);
|
||||
intent.putExtra("commentId", commendId.getText());
|
||||
intent.putExtra("commentAction", "edit");
|
||||
intent.putExtra("commentBody", commendBodyRaw.getText());
|
||||
context.startActivity(intent);
|
||||
Bundle bundle1 = new Bundle();
|
||||
bundle1.putAll(bundle);
|
||||
bundle1.putInt("commentId", issueComment.getId());
|
||||
|
||||
ReactionSpinner reactionSpinner = new ReactionSpinner(context, bundle1);
|
||||
reactionSpinner.setOnInteractedListener(() -> {
|
||||
tinyDB.putBoolean("commentEdited", true);
|
||||
|
||||
onInteractedListener.onInteracted();
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
commentShare.setOnClickListener(ediComment -> {
|
||||
linearLayout.addView(reactionSpinner);
|
||||
|
||||
commentMenuEdit.setOnClickListener(v1 -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("commentId", issueComment.getId());
|
||||
bundle.putString("commentAction", "edit");
|
||||
bundle.putString("commentBody", issueComment.getBody());
|
||||
|
||||
BottomSheetReplyFragment bottomSheetReplyFragment = BottomSheetReplyFragment.newInstance(bundle);
|
||||
bottomSheetReplyFragment.setOnInteractedListener(onInteractedListener);
|
||||
bottomSheetReplyFragment.show(fragmentManager, "replyBottomSheet");
|
||||
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
commentShare.setOnClickListener(v1 -> {
|
||||
// get comment Url
|
||||
CharSequence commentUrl = htmlUrl.getText();
|
||||
CharSequence commentUrl = issueComment.getHtml_url();
|
||||
|
||||
// share issue comment
|
||||
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||
sharingIntent.setType("text/plain");
|
||||
String intentHeader = tinyDb.getString("issueNumber") + context.getResources().getString(R.string.hash) + "issuecomment-" + commendId.getText() + " " + tinyDb.getString("issueTitle");
|
||||
String intentHeader = tinyDB.getString("issueNumber") + context.getResources().getString(R.string.hash) + "issuecomment-" + issueComment.getId() + " " + tinyDB.getString("issueTitle");
|
||||
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, intentHeader);
|
||||
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, commentUrl);
|
||||
context.startActivity(Intent.createChooser(sharingIntent, intentHeader));
|
||||
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
/*commentMenuDelete.setOnClickListener(deleteComment -> {
|
||||
issueCommentCopyUrl.setOnClickListener(v1 -> {
|
||||
// comment Url
|
||||
CharSequence commentUrl = issueComment.getHtml_url();
|
||||
|
||||
dialog.dismiss();
|
||||
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
assert clipboard != null;
|
||||
|
||||
});*/
|
||||
ClipData clip = ClipData.newPlainText(commentUrl, commentUrl);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
|
||||
dialog.dismiss();
|
||||
Toasty.success(context, context.getString(R.string.copyIssueUrlToastMsg));
|
||||
});
|
||||
|
||||
commentMenuQuote.setOnClickListener(v1 -> {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
String commenterName = issueComment.getUser().getUsername();
|
||||
|
||||
if(!commenterName.equals(tinyDB.getString("userLogin"))) {
|
||||
stringBuilder.append("@").append(commenterName).append("\n\n");
|
||||
}
|
||||
|
||||
String[] lines = issueComment.getBody().split("\\R");
|
||||
|
||||
for(String line : lines) {
|
||||
stringBuilder.append(">").append(line).append("\n");
|
||||
}
|
||||
|
||||
stringBuilder.append("\n");
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("commentBody", stringBuilder.toString());
|
||||
bundle.putBoolean("cursorToEnd", true);
|
||||
|
||||
dialog.dismiss();
|
||||
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
|
||||
});
|
||||
|
||||
commentMenuCopy.setOnClickListener(v1 -> {
|
||||
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
assert clipboard != null;
|
||||
|
||||
ClipData clip = ClipData.newPlainText("Comment on issue #" + tinyDB.getString("issueNumber"), issueComment.getBody());
|
||||
clipboard.setPrimaryClip(clip);
|
||||
|
||||
dialog.dismiss();
|
||||
Toasty.success(context, context.getString(R.string.copyIssueCommentToastMsg));
|
||||
});
|
||||
|
||||
commentMenuDelete.setOnClickListener(v1 -> {
|
||||
deleteIssueComment(context, issueComment.getId(), getAdapterPosition());
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
avatar.setOnClickListener(loginId -> {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.putExtra("username", userLoginId);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
avatar.setOnLongClickListener(loginId -> {
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {
|
||||
private void updateAdapter(int position) {
|
||||
|
||||
this.mCtx = mCtx;
|
||||
this.issuesComments = issuesCommentsMain;
|
||||
issuesComments.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
notifyItemRangeChanged(position, issuesComments.size());
|
||||
}
|
||||
|
||||
private void deleteIssueComment(final Context ctx, final int commentId, int position) {
|
||||
|
||||
final String loginUid = tinyDB.getString("loginUid");
|
||||
final String instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
String[] repoFullName = tinyDB.getString("repoFullName").split("/");
|
||||
|
||||
if (repoFullName.length != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String repoOwner = repoFullName[0];
|
||||
final String repoName = repoFullName[1];
|
||||
|
||||
Call<JsonElement> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.deleteComment(instanceToken, repoOwner, repoName, commentId);
|
||||
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 204:
|
||||
updateAdapter(position);
|
||||
Toasty.success(ctx, ctx.getResources().getString(R.string.deleteCommentSuccess));
|
||||
break;
|
||||
|
||||
case 401:
|
||||
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
|
||||
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
|
||||
break;
|
||||
|
||||
case 403:
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
break;
|
||||
|
||||
case 404:
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
break;
|
||||
|
||||
default:
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericError));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -162,118 +296,68 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_issue_comments, parent, false);
|
||||
return new IssueCommentsAdapter.IssueCommentViewHolder(v);
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull IssueCommentsAdapter.IssueCommentViewHolder holder, int position) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(mCtx);
|
||||
final String locale = tinyDb.getString("locale");
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
String timeFormat = tinyDB.getString("dateFormat");
|
||||
IssueComments issueComment = issuesComments.get(position);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
IssueComments currentItem = issuesComments.get(position);
|
||||
holder.userLoginId = issueComment.getUser().getLogin();
|
||||
|
||||
holder.htmlUrl.setText(currentItem.getHtml_url());
|
||||
holder.commenterUsername.setText(currentItem.getUser().getUsername());
|
||||
holder.commendId.setText(String.valueOf(currentItem.getId()));
|
||||
holder.commendBodyRaw.setText(currentItem.getBody());
|
||||
holder.issueComment = issueComment;
|
||||
holder.author.setText(issueComment.getUser().getUsername());
|
||||
|
||||
if(!currentItem.getUser().getFull_name().equals("")) {
|
||||
holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getFull_name(), mCtx));
|
||||
}
|
||||
else {
|
||||
holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getLogin(), mCtx));
|
||||
}
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(issueComment.getUser().getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(imgRadius, 0))
|
||||
.resize(AppUtil.getPixelsFromDensity(context, 35), AppUtil.getPixelsFromDensity(context, 35))
|
||||
.centerCrop()
|
||||
.into(holder.avatar);
|
||||
|
||||
PicassoService.getInstance(mCtx).get().load(currentItem.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);
|
||||
Markdown.render(context, EmojiParser.parseToUnicode(issueComment.getBody()), holder.comment);
|
||||
|
||||
String cleanIssueComments = currentItem.getBody().trim();
|
||||
StringBuilder informationBuilder = null;
|
||||
if(issueComment.getCreated_at() != null) {
|
||||
|
||||
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)).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) {
|
||||
|
||||
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());
|
||||
if(timeFormat.equals("pretty")) {
|
||||
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), locale, "pretty", context));
|
||||
holder.information.setOnClickListener(v -> TimeHelper.customDateFormatForToastDateFormat(issueComment.getCreated_at()));
|
||||
}
|
||||
})).usePlugin(new AbstractMarkwonPlugin() {
|
||||
|
||||
@Override
|
||||
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
|
||||
|
||||
builder.codeTextColor(tinyDb.getInt("codeBlockColor")).codeBackgroundColor(tinyDb.getInt("codeBlockBackground")).linkColor(mCtx.getResources().getColor(R.color.lightBlue));
|
||||
else if(timeFormat.equals("normal")) {
|
||||
informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), locale, "normal", context));
|
||||
}
|
||||
|
||||
}).usePlugin(TablePlugin.create(mCtx)).usePlugin(TaskListPlugin.create(mCtx)).usePlugin(HtmlPlugin.create()).usePlugin(StrikethroughPlugin.create()).usePlugin(LinkifyPlugin.create()).build();
|
||||
|
||||
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
|
||||
markwon.setParsedMarkdown(holder.issueComment, UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments));
|
||||
|
||||
String edited;
|
||||
|
||||
if(!currentItem.getUpdated_at().equals(currentItem.getCreated_at())) {
|
||||
|
||||
edited = mCtx.getResources().getString(R.string.colorfulBulletSpan) + mCtx.getResources().getString(R.string.modifiedText);
|
||||
holder.commentModified.setVisibility(View.VISIBLE);
|
||||
holder.commentModified.setText(edited);
|
||||
holder.commentModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), mCtx));
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
holder.commentModified.setVisibility(View.INVISIBLE);
|
||||
|
||||
if(!issueComment.getCreated_at().equals(issueComment.getUpdated_at())) {
|
||||
if(informationBuilder != null) {
|
||||
informationBuilder.append(context.getString(R.string.colorfulBulletSpan)).append(context.getString(R.string.modifiedText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
holder.issueCommentDate.setText(TimeHelper.formatTime(currentItem.getCreated_at(), new Locale(locale), timeFormat, mCtx));
|
||||
holder.information.setText(informationBuilder);
|
||||
|
||||
Bundle bundle1 = new Bundle();
|
||||
bundle1.putAll(bundle);
|
||||
bundle1.putInt("commentId", issueComment.getId());
|
||||
|
||||
ReactionList reactionList = new ReactionList(context, bundle1);
|
||||
|
||||
holder.commentReactionBadges.addView(reactionList);
|
||||
reactionList.setOnReactionAddedListener(() -> {
|
||||
|
||||
if(holder.commentReactionBadges.getVisibility() != View.VISIBLE) {
|
||||
holder.commentReactionBadges.post(() -> holder.commentReactionBadges.setVisibility(View.VISIBLE));
|
||||
}
|
||||
});
|
||||
|
||||
if(timeFormat.equals("pretty")) {
|
||||
holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return issuesComments.size();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.mikepenz.fastadapter.FastAdapter;
|
||||
import com.mikepenz.fastadapter.items.AbstractItem;
|
||||
import com.mikepenz.fastadapter.listeners.ClickEventHook;
|
||||
import com.mikepenz.fastadapter.utils.EventHookUtil;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import org.gitnex.tea4j.models.Issues;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.IssueDetailActivity;
|
||||
import org.mian.gitnex.activities.ProfileActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -31,215 +33,187 @@ import java.util.Locale;
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class IssuesAdapter extends AbstractItem<IssuesAdapter, IssuesAdapter.ViewHolder> {
|
||||
public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
final private Context ctx;
|
||||
private String issueTitle;
|
||||
private int issueNumber;
|
||||
private String issueAssigneeAvatar;
|
||||
private Date issueCreatedTime;
|
||||
private int issueCommentsCount;
|
||||
private String userFullname;
|
||||
private String userLogin;
|
||||
private final Context context;
|
||||
private final int TYPE_LOAD = 0;
|
||||
private List<Issues> issuesList;
|
||||
private OnLoadMoreListener loadMoreListener;
|
||||
private boolean isLoading = false, isMoreDataAvailable = true;
|
||||
|
||||
private boolean isSelectable = true;
|
||||
public IssuesAdapter(Context ctx, List<Issues> issuesListMain) {
|
||||
|
||||
public IssuesAdapter(Context ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public IssuesAdapter withNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) {
|
||||
|
||||
this.setNewItems(issueTitle, issueNumber, issueAssigneeAvatar, issueCreatedTime, issueCommentsCount, userFullname, userLogin);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
private void setNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) {
|
||||
|
||||
this.issueTitle = issueTitle;
|
||||
this.issueNumber = issueNumber;
|
||||
this.issueAssigneeAvatar = issueAssigneeAvatar;
|
||||
this.issueCreatedTime = issueCreatedTime;
|
||||
this.issueCommentsCount = issueCommentsCount;
|
||||
this.userFullname = userFullname;
|
||||
this.userLogin = userLogin;
|
||||
|
||||
}
|
||||
|
||||
private int getIssueNumber() {
|
||||
return issueNumber;
|
||||
}
|
||||
|
||||
public String getIssueTitle() {
|
||||
return issueTitle;
|
||||
}
|
||||
|
||||
private String getIssueAssigneeAvatar() {
|
||||
return issueAssigneeAvatar;
|
||||
}
|
||||
|
||||
private Date getIssueCreatedTime() {
|
||||
return issueCreatedTime;
|
||||
}
|
||||
|
||||
private int getIssueCommentsCount() {
|
||||
return issueCommentsCount;
|
||||
}
|
||||
|
||||
private String getUserFullname() {
|
||||
return userFullname;
|
||||
}
|
||||
|
||||
private String getUserLogin() {
|
||||
return userLogin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IssuesAdapter withEnabled(boolean enabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return isSelectable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IssuesAdapter withSelectable(boolean selectable) {
|
||||
this.isSelectable = selectable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return R.id.relativeLayoutFrameIssuesList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayoutRes() {
|
||||
return R.layout.list_issues;
|
||||
this.context = ctx;
|
||||
this.issuesList = issuesListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public IssuesAdapter.ViewHolder getViewHolder(@NonNull View v) {
|
||||
return new IssuesAdapter.ViewHolder(v);
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
|
||||
if(viewType == TYPE_LOAD) {
|
||||
return new IssuesHolder(inflater.inflate(R.layout.list_issues, parent, false));
|
||||
}
|
||||
else {
|
||||
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends FastAdapter.ViewHolder<IssuesAdapter> {
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(ctx);
|
||||
final String locale = tinyDb.getString("locale");
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
|
||||
|
||||
private TextView issueNumber;
|
||||
private ImageView issueAssigneeAvatar;
|
||||
private TextView issueTitle;
|
||||
private TextView issueCreatedTime;
|
||||
private TextView issueCommentsCount;
|
||||
isLoading = true;
|
||||
loadMoreListener.onLoadMore();
|
||||
}
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
if(getItemViewType(position) == TYPE_LOAD) {
|
||||
|
||||
((IssuesHolder) holder).bindData(issuesList.get(position));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
|
||||
if(issuesList.get(position).getTitle() != null) {
|
||||
return TYPE_LOAD;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return issuesList.size();
|
||||
}
|
||||
|
||||
class IssuesHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private Issues issue;
|
||||
|
||||
private final ImageView issueAssigneeAvatar;
|
||||
private final TextView issueTitle;
|
||||
private final TextView issueCreatedTime;
|
||||
private final TextView issueCommentsCount;
|
||||
|
||||
IssuesHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
issueNumber = itemView.findViewById(R.id.issueNumber);
|
||||
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
|
||||
issueTitle = itemView.findViewById(R.id.issueTitle);
|
||||
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
|
||||
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
|
||||
|
||||
itemView.setOnClickListener(layoutView -> {
|
||||
Intent intent = new Intent(context, IssueDetailActivity.class);
|
||||
intent.putExtra("issueNumber", issue.getNumber());
|
||||
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
tinyDb.putString("issueNumber", String.valueOf(issue.getNumber()));
|
||||
tinyDb.putString("issueType", "Issue");
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
issueAssigneeAvatar.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.putExtra("username", issue.getUser().getLogin());
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
issueAssigneeAvatar.setOnLongClickListener(loginId -> {
|
||||
AppUtil.copyToClipboard(context, issue.getUser().getLogin(), context.getString(R.string.copyLoginIdToClipBoard, issue.getUser().getLogin()));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(@NonNull IssuesAdapter item, @NonNull List<Object> payloads) {
|
||||
@SuppressLint("SetTextI18n")
|
||||
void bindData(Issues issue) {
|
||||
|
||||
if (!item.getUserFullname().equals("")) {
|
||||
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserFullname(), ctx));
|
||||
}
|
||||
else {
|
||||
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserLogin(), ctx));
|
||||
}
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
Locale locale = context.getResources().getConfiguration().locale;
|
||||
String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
PicassoService.getInstance(ctx).get().load(item.getIssueAssigneeAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
String issueNumber_ = "<font color='" + ctx.getResources().getColor(R.color.lightGray) + "'>" + ctx.getResources().getString(R.string.hash) + item.getIssueNumber() + "</font>";
|
||||
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + item.getIssueTitle()));
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(issue.getUser().getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(imgRadius, 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop()
|
||||
.into(issueAssigneeAvatar);
|
||||
|
||||
issueNumber.setText(String.valueOf(item.getIssueNumber()));
|
||||
issueCommentsCount.setText(String.valueOf(item.getIssueCommentsCount()));
|
||||
String issueNumber_ = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + context.getResources().getString(R.string.hash) + issue.getNumber() + "</font>";
|
||||
issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + EmojiParser.parseToUnicode(issue.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
|
||||
switch (timeFormat) {
|
||||
this.issue = issue;
|
||||
this.issueCommentsCount.setText(String.valueOf(issue.getComments()));
|
||||
|
||||
switch(timeFormat) {
|
||||
case "pretty": {
|
||||
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
|
||||
String createdTime = prettyTime.format(item.getIssueCreatedTime());
|
||||
issueCreatedTime.setText(createdTime);
|
||||
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getIssueCreatedTime()), ctx));
|
||||
PrettyTime prettyTime = new PrettyTime(locale);
|
||||
String createdTime = prettyTime.format(issue.getCreated_at());
|
||||
this.issueCreatedTime.setText(createdTime);
|
||||
this.issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issue.getCreated_at()), context));
|
||||
break;
|
||||
}
|
||||
case "normal": {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
|
||||
String createdTime = formatter.format(item.getIssueCreatedTime());
|
||||
issueCreatedTime.setText(createdTime);
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
String createdTime = formatter.format(issue.getCreated_at());
|
||||
this.issueCreatedTime.setText(createdTime);
|
||||
break;
|
||||
}
|
||||
case "normal1": {
|
||||
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
|
||||
String createdTime = formatter.format(item.getIssueCreatedTime());
|
||||
issueCreatedTime.setText(createdTime);
|
||||
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
String createdTime = formatter.format(issue.getCreated_at());
|
||||
this.issueCreatedTime.setText(createdTime);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbindView(@NonNull IssuesAdapter item) {
|
||||
|
||||
issueTitle.setText(null);
|
||||
issueCommentsCount.setText(null);
|
||||
issueCreatedTime.setText(null);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class IssueTitleClickEvent extends ClickEventHook<IssuesAdapter> {
|
||||
static class LoadHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<View> onBindMany(@NonNull RecyclerView.ViewHolder viewHolder) {
|
||||
|
||||
if (viewHolder instanceof IssuesAdapter.ViewHolder) {
|
||||
return EventHookUtil.toList(((ViewHolder) viewHolder).issueTitle);
|
||||
}
|
||||
|
||||
return super.onBindMany(viewHolder);
|
||||
LoadHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v, int position, @NonNull FastAdapter<IssuesAdapter> fastAdapter, IssuesAdapter item) {
|
||||
public void setMoreDataAvailable(boolean moreDataAvailable) {
|
||||
|
||||
Context context = v.getContext();
|
||||
isMoreDataAvailable = moreDataAvailable;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(context, IssueDetailActivity.class);
|
||||
intent.putExtra("issueNumber", item.getIssueNumber());
|
||||
public void notifyDataChanged() {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(context);
|
||||
tinyDb.putString("issueNumber", String.valueOf(item.getIssueNumber()));
|
||||
tinyDb.putString("issueType", "issue");
|
||||
context.startActivity(intent);
|
||||
notifyDataSetChanged();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
}
|
||||
public interface OnLoadMoreListener {
|
||||
|
||||
void onLoadMore();
|
||||
}
|
||||
|
||||
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
|
||||
|
||||
this.loadMoreListener = loadMoreListener;
|
||||
}
|
||||
|
||||
public void updateList(List<Issues> list) {
|
||||
|
||||
issuesList = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,26 +3,24 @@ package org.mian.gitnex.adapters;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.core.widget.ImageViewCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import org.gitnex.tea4j.models.Labels;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.CreateLabelActivity;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.ColorInverter;
|
||||
import org.mian.gitnex.helpers.LabelWidthCalculator;
|
||||
import org.mian.gitnex.models.Labels;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
@@ -30,25 +28,25 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsViewHolder> {
|
||||
|
||||
private List<Labels> labelsList;
|
||||
final private Context mCtx;
|
||||
private ArrayList<Integer> labelsArray = new ArrayList<>();
|
||||
private final List<Labels> labelsList;
|
||||
private static String type;
|
||||
private static String orgName;
|
||||
|
||||
static class LabelsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private TextView labelTitle;
|
||||
private TextView labelId;
|
||||
private TextView labelColor;
|
||||
private ImageView labelsView;
|
||||
private Labels labels;
|
||||
|
||||
private final CardView labelView;
|
||||
private final ImageView labelIcon;
|
||||
private final TextView labelName;
|
||||
|
||||
private LabelsViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
labelsView = itemView.findViewById(R.id.labelsView);
|
||||
labelView = itemView.findViewById(R.id.labelView);
|
||||
labelIcon = itemView.findViewById(R.id.labelIcon);
|
||||
labelName = itemView.findViewById(R.id.labelName);
|
||||
ImageView labelsOptionsMenu = itemView.findViewById(R.id.labelsOptionsMenu);
|
||||
labelTitle = itemView.findViewById(R.id.labelTitle);
|
||||
labelId = itemView.findViewById(R.id.labelId);
|
||||
labelColor = itemView.findViewById(R.id.labelColor);
|
||||
|
||||
labelsOptionsMenu.setOnClickListener(v -> {
|
||||
|
||||
@@ -61,7 +59,7 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
|
||||
TextView labelMenuDelete = view.findViewById(R.id.labelMenuDelete);
|
||||
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
|
||||
|
||||
bottomSheetHeader.setText(labelTitle.getText());
|
||||
bottomSheetHeader.setText(labels.getName());
|
||||
BottomSheetDialog dialog = new BottomSheetDialog(context);
|
||||
dialog.setContentView(view);
|
||||
dialog.show();
|
||||
@@ -69,24 +67,25 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
|
||||
labelMenuEdit.setOnClickListener(editLabel -> {
|
||||
|
||||
Intent intent = new Intent(context, CreateLabelActivity.class);
|
||||
intent.putExtra("labelId", labelId.getText());
|
||||
intent.putExtra("labelTitle", labelTitle.getText());
|
||||
intent.putExtra("labelColor", labelColor.getText());
|
||||
intent.putExtra("labelId", String.valueOf(labels.getId()));
|
||||
intent.putExtra("labelTitle", labels.getName());
|
||||
intent.putExtra("labelColor", labels.getColor());
|
||||
intent.putExtra("labelAction", "edit");
|
||||
intent.putExtra("type", type);
|
||||
intent.putExtra("orgName", orgName);
|
||||
context.startActivity(intent);
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
labelMenuDelete.setOnClickListener(deleteLabel -> {
|
||||
|
||||
AlertDialogs.labelDeleteDialog(context, labelTitle.getText().toString(), labelId.getText().toString(),
|
||||
AlertDialogs.labelDeleteDialog(context, labels.getName(), String.valueOf(labels.getId()),
|
||||
context.getResources().getString(R.string.labelDeleteTitle),
|
||||
context.getResources().getString(R.string.labelDeleteMessage),
|
||||
context.getResources().getString(R.string.labelDeletePositiveButton),
|
||||
context.getResources().getString(R.string.labelDeleteNegativeButton));
|
||||
context.getResources().getString(R.string.labelDeleteTitle),
|
||||
context.getResources().getString(R.string.labelDeleteNegativeButton),
|
||||
type, orgName);
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -94,9 +93,11 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
|
||||
}
|
||||
}
|
||||
|
||||
public LabelsAdapter(Context mCtx, List<Labels> labelsMain) {
|
||||
this.mCtx = mCtx;
|
||||
this.labelsList = labelsMain;
|
||||
public LabelsAdapter(Context ctx, List<Labels> labelsMain, String type, String orgName) {
|
||||
|
||||
this.labelsList = labelsMain;
|
||||
LabelsAdapter.type = type;
|
||||
LabelsAdapter.orgName = orgName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -110,29 +111,19 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
|
||||
public void onBindViewHolder(@NonNull LabelsAdapter.LabelsViewHolder holder, int position) {
|
||||
|
||||
Labels currentItem = labelsList.get(position);
|
||||
|
||||
holder.labelTitle.setText(currentItem.getName());
|
||||
holder.labelId.setText(String.valueOf(currentItem.getId()));
|
||||
holder.labelColor.setText(currentItem.getColor());
|
||||
holder.labels = currentItem;
|
||||
|
||||
String labelColor = currentItem.getColor();
|
||||
String labelName = currentItem.getName();
|
||||
|
||||
int color = Color.parseColor("#" + labelColor);
|
||||
int contrastColor = new ColorInverter().getContrastColor(color);
|
||||
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.useFont(Typeface.DEFAULT)
|
||||
.bold()
|
||||
.textColor(new ColorInverter().getContrastColor(color))
|
||||
.fontSize(35)
|
||||
.width(LabelWidthCalculator.calculateLabelWidth(labelName, Typeface.DEFAULT, 40, 20))
|
||||
.height(55)
|
||||
.endConfig()
|
||||
.buildRoundRect(labelName, color, 10);
|
||||
|
||||
holder.labelsView.setImageDrawable(drawable);
|
||||
ImageViewCompat.setImageTintList(holder.labelIcon, ColorStateList.valueOf(contrastColor));
|
||||
|
||||
holder.labelName.setTextColor(contrastColor);
|
||||
holder.labelName.setText(labelName);
|
||||
holder.labelView.setCardBackgroundColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,4 +131,4 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
|
||||
return labelsList.size();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.Labels;
|
||||
import org.mian.gitnex.R;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class LabelsListAdapter extends RecyclerView.Adapter<LabelsListAdapter.LabelsViewHolder> {
|
||||
|
||||
private List<Integer> currentLabelsIds;
|
||||
private final List<Labels> labels;
|
||||
private final List<String> labelsStrings = new ArrayList<>();
|
||||
private List<Integer> labelsIds = new ArrayList<>();
|
||||
|
||||
private final LabelsListAdapterListener labelsListener;
|
||||
|
||||
public interface LabelsListAdapterListener {
|
||||
|
||||
void labelsInterface(List<String> data);
|
||||
void labelsIdsInterface(List<Integer> data);
|
||||
}
|
||||
|
||||
public LabelsListAdapter(List<Labels> labelsMain, LabelsListAdapterListener labelsListener, List<Integer> currentLabelsIds) {
|
||||
|
||||
this.labels = labelsMain;
|
||||
this.labelsListener = labelsListener;
|
||||
this.currentLabelsIds = currentLabelsIds;
|
||||
}
|
||||
|
||||
static class LabelsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final CheckBox labelSelection;
|
||||
private final TextView labelText;
|
||||
private final ImageView labelColor;
|
||||
|
||||
private LabelsViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
this.setIsRecyclable(false);
|
||||
|
||||
labelSelection = itemView.findViewById(R.id.labelSelection);
|
||||
labelText = itemView.findViewById(R.id.labelText);
|
||||
labelColor = itemView.findViewById(R.id.labelColor);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public LabelsListAdapter.LabelsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_labels_list, parent, false);
|
||||
return new LabelsListAdapter.LabelsViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull LabelsListAdapter.LabelsViewHolder holder, int position) {
|
||||
|
||||
Labels currentItem = labels.get(position);
|
||||
|
||||
String labelColor = currentItem.getColor();
|
||||
int color = Color.parseColor("#" + labelColor);
|
||||
|
||||
holder.labelText.setText(currentItem.getName());
|
||||
holder.labelColor.setBackgroundColor(color);
|
||||
|
||||
for(int i = 0; i < labelsIds.size(); i++) {
|
||||
|
||||
if(labelsStrings.contains(currentItem.getName())) {
|
||||
|
||||
holder.labelSelection.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
currentLabelsIds = new ArrayList<>(new LinkedHashSet<>(currentLabelsIds));
|
||||
|
||||
for(int i = 0; i < currentLabelsIds.size(); i++) {
|
||||
|
||||
if(currentLabelsIds.contains(currentItem.getId())) {
|
||||
|
||||
holder.labelSelection.setChecked(true);
|
||||
labelsIds.add(currentLabelsIds.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
labelsListener.labelsIdsInterface(labelsIds);
|
||||
|
||||
holder.labelSelection.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
||||
if(isChecked) {
|
||||
|
||||
labelsStrings.add(currentItem.getName());
|
||||
labelsIds.add(currentItem.getId());
|
||||
}
|
||||
else {
|
||||
|
||||
labelsStrings.remove(currentItem.getName());
|
||||
labelsIds.remove(Integer.valueOf(currentItem.getId()));
|
||||
}
|
||||
|
||||
labelsListener.labelsInterface(labelsStrings);
|
||||
labelsListener.labelsIdsInterface(labelsIds);
|
||||
});
|
||||
|
||||
labelsIds = new ArrayList<>(new LinkedHashSet<>(labelsIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return labels.size();
|
||||
}
|
||||
|
||||
public void updateList(List<Integer> list) {
|
||||
|
||||
currentLabelsIds = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -10,10 +12,12 @@ import android.widget.Filter;
|
||||
import android.widget.Filterable;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.ProfileActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.models.UserInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -23,26 +27,40 @@ import java.util.List;
|
||||
|
||||
public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
|
||||
|
||||
private List<UserInfo> membersList;
|
||||
private Context mCtx;
|
||||
private List<UserInfo> membersListFull;
|
||||
private final List<UserInfo> membersList;
|
||||
private final Context context;
|
||||
private final List<UserInfo> membersListFull;
|
||||
|
||||
private class ViewHolder {
|
||||
|
||||
private ImageView memberAvatar;
|
||||
private TextView memberName;
|
||||
private String userLoginId;
|
||||
|
||||
private final ImageView memberAvatar;
|
||||
private final TextView memberName;
|
||||
|
||||
ViewHolder(View v) {
|
||||
|
||||
memberAvatar = v.findViewById(R.id.memberAvatar);
|
||||
memberName = v.findViewById(R.id.memberName);
|
||||
|
||||
memberAvatar.setOnClickListener(loginId -> {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.putExtra("username", userLoginId);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
memberAvatar.setOnLongClickListener(loginId -> {
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public MembersByOrgAdapter(Context mCtx, List<UserInfo> membersListMain) {
|
||||
this.mCtx = mCtx;
|
||||
public MembersByOrgAdapter(Context ctx, List<UserInfo> membersListMain) {
|
||||
|
||||
this.context = ctx;
|
||||
this.membersList = membersListMain;
|
||||
membersListFull = new ArrayList<>(membersList);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,31 +85,37 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
|
||||
MembersByOrgAdapter.ViewHolder viewHolder = null;
|
||||
|
||||
if (finalView == null) {
|
||||
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_members_by_org, null);
|
||||
viewHolder = new MembersByOrgAdapter.ViewHolder(finalView);
|
||||
|
||||
finalView = LayoutInflater.from(context).inflate(R.layout.list_members_by_org, null);
|
||||
viewHolder = new ViewHolder(finalView);
|
||||
finalView.setTag(viewHolder);
|
||||
}
|
||||
else {
|
||||
|
||||
viewHolder = (MembersByOrgAdapter.ViewHolder) finalView.getTag();
|
||||
}
|
||||
|
||||
initData(viewHolder, position);
|
||||
return finalView;
|
||||
|
||||
}
|
||||
|
||||
private void initData(MembersByOrgAdapter.ViewHolder viewHolder, int position) {
|
||||
|
||||
UserInfo currentItem = membersList.get(position);
|
||||
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(viewHolder.memberAvatar);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(viewHolder.memberAvatar);
|
||||
|
||||
viewHolder.userLoginId = currentItem.getLogin();
|
||||
|
||||
if(!currentItem.getFullname().equals("")) {
|
||||
viewHolder.memberName.setText(currentItem.getFullname());
|
||||
|
||||
viewHolder.memberName.setText(Html.fromHtml(currentItem.getFullname()));
|
||||
}
|
||||
else {
|
||||
|
||||
viewHolder.memberName.setText(currentItem.getLogin());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,14 +123,17 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
|
||||
return membersFilter;
|
||||
}
|
||||
|
||||
private Filter membersFilter = new Filter() {
|
||||
private final Filter membersFilter = new Filter() {
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
List<UserInfo> filteredList = new ArrayList<>();
|
||||
|
||||
if (constraint == null || constraint.length() == 0) {
|
||||
|
||||
filteredList.addAll(membersListFull);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
String filterPattern = constraint.toString().toLowerCase().trim();
|
||||
|
||||
for (UserInfo item : membersListFull) {
|
||||
@@ -124,6 +151,7 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
|
||||
membersList.clear();
|
||||
membersList.addAll((List) results.values);
|
||||
notifyDataSetChanged();
|
||||
|
||||
@@ -2,361 +2,300 @@ 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.util.Log;
|
||||
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 androidx.annotation.NonNull;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import org.gitnex.tea4j.models.Milestones;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.MilestoneActions;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.Markdown;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.models.Milestones;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
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.recyclerview.widget.RecyclerView;
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.core.CorePlugin;
|
||||
import io.noties.markwon.core.MarkwonTheme;
|
||||
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
|
||||
import io.noties.markwon.ext.tables.TablePlugin;
|
||||
import io.noties.markwon.ext.tasklist.TaskListPlugin;
|
||||
import io.noties.markwon.html.HtmlPlugin;
|
||||
import io.noties.markwon.image.DefaultMediaDecoder;
|
||||
import io.noties.markwon.image.ImageItem;
|
||||
import io.noties.markwon.image.ImagesPlugin;
|
||||
import io.noties.markwon.image.SchemeHandler;
|
||||
import io.noties.markwon.image.gif.GifMediaDecoder;
|
||||
import io.noties.markwon.image.svg.SvgMediaDecoder;
|
||||
import io.noties.markwon.linkify.LinkifyPlugin;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.MilestonesViewHolder> implements Filterable {
|
||||
public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private List<Milestones> milestonesList;
|
||||
private Context mCtx;
|
||||
private List<Milestones> milestonesListFull;
|
||||
private final Context context;
|
||||
private final int TYPE_LOAD = 0;
|
||||
private List<Milestones> dataList;
|
||||
private OnLoadMoreListener loadMoreListener;
|
||||
private boolean isLoading = false;
|
||||
private boolean isMoreDataAvailable = true;
|
||||
|
||||
static class MilestonesViewHolder extends RecyclerView.ViewHolder {
|
||||
public MilestonesAdapter(Context ctx, List<Milestones> dataListMain) {
|
||||
|
||||
private TextView milestoneId;
|
||||
private TextView msTitle;
|
||||
private TextView msDescription;
|
||||
private TextView msOpenIssues;
|
||||
private TextView msClosedIssues;
|
||||
private TextView msDueDate;
|
||||
private ImageView msStatus;
|
||||
private ProgressBar msProgress;
|
||||
private TextView milestoneStatus;
|
||||
this.context = ctx;
|
||||
this.dataList = dataListMain;
|
||||
}
|
||||
|
||||
private MilestonesViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
milestoneId = itemView.findViewById(R.id.milestoneId);
|
||||
msTitle = itemView.findViewById(R.id.milestoneTitle);
|
||||
msStatus = itemView.findViewById(R.id.milestoneState);
|
||||
msDescription = itemView.findViewById(R.id.milestoneDescription);
|
||||
msOpenIssues = itemView.findViewById(R.id.milestoneIssuesOpen);
|
||||
msClosedIssues = itemView.findViewById(R.id.milestoneIssuesClosed);
|
||||
msDueDate = itemView.findViewById(R.id.milestoneDueDate);
|
||||
msProgress = itemView.findViewById(R.id.milestoneProgress);
|
||||
ImageView milestonesMenu = itemView.findViewById(R.id.milestonesMenu);
|
||||
milestoneStatus = itemView.findViewById(R.id.milestoneStatus);
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
|
||||
milestonesMenu.setOnClickListener(v -> {
|
||||
if(viewType == TYPE_LOAD) {
|
||||
return new MilestonesAdapter.DataHolder(inflater.inflate(R.layout.list_milestones, parent, false));
|
||||
}
|
||||
else {
|
||||
return new MilestonesAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
Context ctx = v.getContext();
|
||||
int milestoneId_ = Integer.parseInt(milestoneId.getText().toString());
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
|
||||
@SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_milestones_in_list, null);
|
||||
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
|
||||
|
||||
TextView closeMilestone = view.findViewById(R.id.closeMilestone);
|
||||
TextView openMilestone = view.findViewById(R.id.openMilestone);
|
||||
|
||||
BottomSheetDialog dialog = new BottomSheetDialog(ctx);
|
||||
dialog.setContentView(view);
|
||||
dialog.show();
|
||||
|
||||
if(milestoneStatus.getText().toString().equals("open")) {
|
||||
|
||||
closeMilestone.setVisibility(View.VISIBLE);
|
||||
openMilestone.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
closeMilestone.setVisibility(View.GONE);
|
||||
openMilestone.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
|
||||
closeMilestone.setOnClickListener(v12 -> {
|
||||
|
||||
MilestoneActions.closeMilestone(ctx, milestoneId_);
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
openMilestone.setOnClickListener(v12 -> {
|
||||
|
||||
MilestoneActions.openMilestone(ctx, milestoneId_);
|
||||
dialog.dismiss();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public MilestonesAdapter(Context mCtx, List<Milestones> milestonesMain) {
|
||||
this.mCtx = mCtx;
|
||||
this.milestonesList = milestonesMain;
|
||||
milestonesListFull = new ArrayList<>(milestonesList);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MilestonesAdapter.MilestonesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_milestones, parent, false);
|
||||
return new MilestonesAdapter.MilestonesViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MilestonesAdapter.MilestonesViewHolder holder, int position) {
|
||||
|
||||
final TinyDB tinyDb = new TinyDB(mCtx);
|
||||
final String locale = tinyDb.getString("locale");
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
Milestones currentItem = milestonesList.get(position);
|
||||
|
||||
holder.milestoneId.setText(String.valueOf(currentItem.getId()));
|
||||
holder.milestoneStatus.setText(currentItem.getState());
|
||||
|
||||
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
|
||||
.usePlugin(CorePlugin.create())
|
||||
.usePlugin(ImagesPlugin.create(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(drawable -> null);
|
||||
plugin.addMediaDecoder(GifMediaDecoder.create(false));
|
||||
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
|
||||
plugin.addMediaDecoder(SvgMediaDecoder.create());
|
||||
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
|
||||
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
|
||||
}))
|
||||
.usePlugin(new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
|
||||
builder
|
||||
.codeTextColor(tinyDb.getInt("codeBlockColor"))
|
||||
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
|
||||
.linkColor(mCtx.getResources().getColor(R.color.lightBlue));
|
||||
}
|
||||
})
|
||||
.usePlugin(TablePlugin.create(mCtx))
|
||||
.usePlugin(TaskListPlugin.create(mCtx))
|
||||
.usePlugin(HtmlPlugin.create())
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(LinkifyPlugin.create())
|
||||
.build();
|
||||
|
||||
Spanned msTitle = markwon.toMarkdown(currentItem.getTitle());
|
||||
markwon.setParsedMarkdown(holder.msTitle, msTitle);
|
||||
|
||||
if(currentItem.getState().equals("open")) {
|
||||
|
||||
@SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.releaseStable));
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
//.useFont(Typeface.DEFAULT)
|
||||
.textColor(mCtx.getResources().getColor(R.color.white))
|
||||
.fontSize(30)
|
||||
.toUpperCase()
|
||||
.width(120)
|
||||
.height(60)
|
||||
.endConfig()
|
||||
.buildRoundRect("open", color, 8);
|
||||
|
||||
holder.msStatus.setImageDrawable(drawable);
|
||||
|
||||
}
|
||||
else if(currentItem.getState().equals("closed")) {
|
||||
|
||||
@SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.colorRed));
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
//.useFont(Typeface.DEFAULT)
|
||||
.textColor(mCtx.getResources().getColor(R.color.white))
|
||||
.fontSize(30)
|
||||
.toUpperCase()
|
||||
.width(140)
|
||||
.height(60)
|
||||
.endConfig()
|
||||
.buildRoundRect("closed", color, 8);
|
||||
|
||||
holder.msStatus.setImageDrawable(drawable);
|
||||
|
||||
}
|
||||
|
||||
if (!currentItem.getDescription().equals("")) {
|
||||
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getDescription()));
|
||||
holder.msDescription.setText(bodyWithMD);
|
||||
}
|
||||
else {
|
||||
holder.msDescription.setText("");
|
||||
}
|
||||
|
||||
holder.msOpenIssues.setText(String.valueOf(currentItem.getOpen_issues()));
|
||||
holder.msOpenIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneOpenIssues, currentItem.getOpen_issues()), mCtx));
|
||||
|
||||
holder.msClosedIssues.setText(String.valueOf(currentItem.getClosed_issues()));
|
||||
holder.msClosedIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneClosedIssues, currentItem.getClosed_issues()), mCtx));
|
||||
|
||||
if ((currentItem.getOpen_issues() + currentItem.getClosed_issues()) > 0) {
|
||||
|
||||
if (currentItem.getOpen_issues() == 0) {
|
||||
holder.msProgress.setProgress(100);
|
||||
holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 100), mCtx));
|
||||
}
|
||||
else {
|
||||
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")) {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
|
||||
Date date = null;
|
||||
try {
|
||||
date = formatter.parse(currentItem.getDue_on());
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
assert date != null;
|
||||
String dueDate = formatter.format(date);
|
||||
|
||||
if(date.before(new Date())) {
|
||||
holder.msDueDate.setTextColor(mCtx.getResources().getColor(R.color.darkRed));
|
||||
}
|
||||
|
||||
holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate));
|
||||
holder.msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(currentItem.getDue_on()), mCtx));
|
||||
|
||||
} else if (timeFormat.equals("normal1")) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
|
||||
Date date1 = null;
|
||||
try {
|
||||
date1 = formatter.parse(currentItem.getDue_on());
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
assert date1 != null;
|
||||
String dueDate = formatter.format(date1);
|
||||
holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
holder.msDueDate.setText("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return milestonesList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
return milestoneFilter;
|
||||
}
|
||||
|
||||
private Filter milestoneFilter = new Filter() {
|
||||
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
List<Milestones> filteredList = new ArrayList<>();
|
||||
|
||||
if (constraint == null || constraint.length() == 0) {
|
||||
filteredList.addAll(milestonesListFull);
|
||||
} else {
|
||||
String filterPattern = constraint.toString().toLowerCase().trim();
|
||||
|
||||
for (Milestones item : milestonesListFull) {
|
||||
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
|
||||
filteredList.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FilterResults results = new FilterResults();
|
||||
results.values = filteredList;
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
milestonesList.clear();
|
||||
milestonesList.addAll((List) results.values);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
};
|
||||
isLoading = true;
|
||||
loadMoreListener.onLoadMore();
|
||||
}
|
||||
|
||||
if(getItemViewType(position) == TYPE_LOAD) {
|
||||
|
||||
((MilestonesAdapter.DataHolder) holder).bindData(dataList.get(position));
|
||||
}
|
||||
}
|
||||
|
||||
class DataHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private Milestones milestones;
|
||||
|
||||
private final TextView msTitle;
|
||||
private final TextView msDescription;
|
||||
private final TextView msOpenIssues;
|
||||
private final TextView msClosedIssues;
|
||||
private final TextView msDueDate;
|
||||
private final ProgressBar msProgress;
|
||||
|
||||
DataHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
msTitle = itemView.findViewById(R.id.milestoneTitle);
|
||||
msDescription = itemView.findViewById(R.id.milestoneDescription);
|
||||
msOpenIssues = itemView.findViewById(R.id.milestoneIssuesOpen);
|
||||
msClosedIssues = itemView.findViewById(R.id.milestoneIssuesClosed);
|
||||
msDueDate = itemView.findViewById(R.id.milestoneDueDate);
|
||||
msProgress = itemView.findViewById(R.id.milestoneProgress);
|
||||
ImageView milestonesMenu = itemView.findViewById(R.id.milestonesMenu);
|
||||
|
||||
milestonesMenu.setOnClickListener(v -> {
|
||||
|
||||
Context ctx = v.getContext();
|
||||
int milestoneId_ = Integer.parseInt(String.valueOf(milestones.getId()));
|
||||
|
||||
@SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_milestones_in_list, null);
|
||||
|
||||
TextView closeMilestone = view.findViewById(R.id.closeMilestone);
|
||||
TextView openMilestone = view.findViewById(R.id.openMilestone);
|
||||
|
||||
BottomSheetDialog dialog = new BottomSheetDialog(ctx);
|
||||
dialog.setContentView(view);
|
||||
dialog.show();
|
||||
|
||||
if(milestones.getState().equals("open")) {
|
||||
|
||||
closeMilestone.setVisibility(View.VISIBLE);
|
||||
openMilestone.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
closeMilestone.setVisibility(View.GONE);
|
||||
openMilestone.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
closeMilestone.setOnClickListener(v12 -> {
|
||||
|
||||
MilestoneActions.closeMilestone(ctx, milestoneId_);
|
||||
dialog.dismiss();
|
||||
updateAdapter(getAdapterPosition());
|
||||
});
|
||||
|
||||
openMilestone.setOnClickListener(v12 -> {
|
||||
|
||||
MilestoneActions.openMilestone(ctx, milestoneId_);
|
||||
dialog.dismiss();
|
||||
updateAdapter(getAdapterPosition());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
void bindData(Milestones dataModel) {
|
||||
|
||||
this.milestones = dataModel;
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
final String locale = context.getResources().getConfiguration().locale.getLanguage();
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
|
||||
Markdown.render(context, dataModel.getTitle(), msTitle);
|
||||
|
||||
if(!dataModel.getDescription().equals("")) {
|
||||
|
||||
Markdown.render(context, EmojiParser.parseToUnicode(dataModel.getDescription()), msDescription);
|
||||
}
|
||||
else {
|
||||
|
||||
msDescription.setText(context.getString(R.string.milestoneNoDescription));
|
||||
}
|
||||
|
||||
msOpenIssues.setText(context.getString(R.string.milestoneIssueStatusOpen, dataModel.getOpen_issues()));
|
||||
msClosedIssues.setText(context.getString(R.string.milestoneIssueStatusClosed, dataModel.getClosed_issues()));
|
||||
|
||||
if((dataModel.getOpen_issues() + dataModel.getClosed_issues()) > 0) {
|
||||
|
||||
if(dataModel.getOpen_issues() == 0) {
|
||||
|
||||
msProgress.setProgress(100);
|
||||
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 100), context));
|
||||
}
|
||||
else {
|
||||
|
||||
int msCompletion = 100 * dataModel.getClosed_issues() / (dataModel.getOpen_issues() + dataModel.getClosed_issues());
|
||||
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, msCompletion), context));
|
||||
msProgress.setProgress(msCompletion);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
msProgress.setProgress(0);
|
||||
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 0), context));
|
||||
}
|
||||
|
||||
if(dataModel.getDue_on() != null) {
|
||||
|
||||
String TAG = Constants.tagMilestonesAdapter;
|
||||
if(timeFormat.equals("normal") || timeFormat.equals("pretty")) {
|
||||
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
|
||||
Date date = null;
|
||||
|
||||
try {
|
||||
date = formatter.parse(dataModel.getDue_on());
|
||||
}
|
||||
catch(ParseException e) {
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
|
||||
assert date != null;
|
||||
String dueDate = formatter.format(date);
|
||||
|
||||
if(date.before(new Date())) {
|
||||
msDueDate.setTextColor(ResourcesCompat.getColor(context.getResources(), R.color.darkRed, null));
|
||||
}
|
||||
|
||||
msDueDate.setText(dueDate);
|
||||
msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(dataModel.getDue_on()), context));
|
||||
}
|
||||
else if(timeFormat.equals("normal1")) {
|
||||
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
|
||||
|
||||
Date date1 = null;
|
||||
|
||||
try {
|
||||
date1 = formatter.parse(dataModel.getDue_on());
|
||||
}
|
||||
catch(ParseException e) {
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
|
||||
assert date1 != null;
|
||||
String dueDate = formatter.format(date1);
|
||||
msDueDate.setText(dueDate);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
msDueDate.setText(context.getString(R.string.milestoneNoDueDate));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateAdapter(int position) {
|
||||
|
||||
dataList.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
notifyItemRangeChanged(position, dataList.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
|
||||
if(dataList.get(position).getTitle() != null) {
|
||||
return TYPE_LOAD;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return dataList.size();
|
||||
}
|
||||
|
||||
static class LoadHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
LoadHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
public void setMoreDataAvailable(boolean moreDataAvailable) {
|
||||
|
||||
isMoreDataAvailable = moreDataAvailable;
|
||||
}
|
||||
|
||||
public void notifyDataChanged() {
|
||||
|
||||
notifyDataSetChanged();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
public interface OnLoadMoreListener {
|
||||
|
||||
void onLoadMore();
|
||||
}
|
||||
|
||||
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
|
||||
|
||||
this.loadMoreListener = loadMoreListener;
|
||||
}
|
||||
|
||||
public void updateList(List<Milestones> list) {
|
||||
|
||||
dataList = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.TextAppearanceSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.helpers.MultiSelectDialog;
|
||||
import org.mian.gitnex.models.MultiSelectModel;
|
||||
import java.util.ArrayList;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.AppCompatCheckBox;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* Author com.github.abumoallim, modified by M M Arif
|
||||
*/
|
||||
|
||||
public class MutliSelectAdapter extends RecyclerView.Adapter<MutliSelectAdapter.MultiSelectDialogViewHolder> {
|
||||
|
||||
private ArrayList<MultiSelectModel> mDataSet;
|
||||
private String mSearchQuery = "";
|
||||
private Context mContext;
|
||||
|
||||
public MutliSelectAdapter(ArrayList<MultiSelectModel> dataSet, Context context) {
|
||||
this.mDataSet = dataSet;
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MultiSelectDialogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.multi_select_item, parent, false);
|
||||
return new MultiSelectDialogViewHolder(view);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final MultiSelectDialogViewHolder holder, int position) {
|
||||
|
||||
if (!mSearchQuery.equals("") && mSearchQuery.length() > 1) {
|
||||
setHighlightedText(position, holder.dialog_name_item);
|
||||
} else {
|
||||
holder.dialog_name_item.setText(mDataSet.get(position).getName());
|
||||
}
|
||||
|
||||
if (mDataSet.get(position).getSelected()) {
|
||||
|
||||
if (!MultiSelectDialog.selectedIdsForCallback.contains(mDataSet.get(position).getId())) {
|
||||
MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(position).getId());
|
||||
}
|
||||
}
|
||||
|
||||
if (checkForSelection(mDataSet.get(position).getId())) {
|
||||
holder.dialog_item_checkbox.setChecked(true);
|
||||
} else {
|
||||
holder.dialog_item_checkbox.setChecked(false);
|
||||
}
|
||||
|
||||
/*holder.dialog_item_checkbox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (holder.dialog_item_checkbox.isChecked()) {
|
||||
MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(holder.getAdapterPosition()).getId());
|
||||
holder.dialog_item_checkbox.setChecked(true);
|
||||
} else {
|
||||
removeFromSelection(mDataSet.get(holder.getAdapterPosition()).getId());
|
||||
holder.dialog_item_checkbox.setChecked(false);
|
||||
}
|
||||
}
|
||||
});*/
|
||||
|
||||
holder.main_container.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (!holder.dialog_item_checkbox.isChecked()) {
|
||||
MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(holder.getAdapterPosition()).getId());
|
||||
holder.dialog_item_checkbox.setChecked(true);
|
||||
mDataSet.get(holder.getAdapterPosition()).setSelected(true);
|
||||
notifyItemChanged(holder.getAdapterPosition());
|
||||
} else {
|
||||
removeFromSelection(mDataSet.get(holder.getAdapterPosition()).getId());
|
||||
holder.dialog_item_checkbox.setChecked(false);
|
||||
mDataSet.get(holder.getAdapterPosition()).setSelected(false);
|
||||
notifyItemChanged(holder.getAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void setHighlightedText(int position, TextView textview) {
|
||||
|
||||
String name = mDataSet.get(position).getName();
|
||||
SpannableString str = new SpannableString(name);
|
||||
int endLength = name.toLowerCase().indexOf(mSearchQuery) + mSearchQuery.length();
|
||||
ColorStateList highlightedColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{ContextCompat.getColor(mContext, R.color.colorAccent)});
|
||||
TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(null, Typeface.NORMAL, -1, highlightedColor, null);
|
||||
str.setSpan(textAppearanceSpan, name.toLowerCase().indexOf(mSearchQuery), endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
textview.setText(str);
|
||||
|
||||
}
|
||||
|
||||
private void removeFromSelection(Integer id) {
|
||||
|
||||
for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) {
|
||||
if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) {
|
||||
MultiSelectDialog.selectedIdsForCallback.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean checkForSelection(Integer id) {
|
||||
|
||||
for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) {
|
||||
if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/*//get selected name string separated by coma
|
||||
public String getDataString() {
|
||||
String data = "";
|
||||
for (int i = 0; i < mDataSet.size(); i++) {
|
||||
if (checkForSelection(mDataSet.get(i).getId())) {
|
||||
data = data + ", " + mDataSet.get(i).getName();
|
||||
}
|
||||
}
|
||||
if (data.length() > 0) {
|
||||
return data.substring(1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
//get selected name ararylist
|
||||
public ArrayList<String> getSelectedNameList() {
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
for (int i = 0; i < mDataSet.size(); i++) {
|
||||
if (checkForSelection(mDataSet.get(i).getId())) {
|
||||
names.add(mDataSet.get(i).getName());
|
||||
}
|
||||
}
|
||||
// return names.toArray(new String[names.size()]);
|
||||
return names;
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mDataSet.size();
|
||||
}
|
||||
|
||||
public void setData(ArrayList<MultiSelectModel> data, String query, MutliSelectAdapter mutliSelectAdapter) {
|
||||
|
||||
this.mDataSet = data;
|
||||
this.mSearchQuery = query;
|
||||
mutliSelectAdapter.notifyDataSetChanged();
|
||||
|
||||
}
|
||||
|
||||
class MultiSelectDialogViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private TextView dialog_name_item;
|
||||
private AppCompatCheckBox dialog_item_checkbox;
|
||||
private LinearLayout main_container;
|
||||
|
||||
MultiSelectDialogViewHolder(View view) {
|
||||
|
||||
super(view);
|
||||
dialog_name_item = view.findViewById(R.id.dialog_item_name);
|
||||
dialog_item_checkbox = view.findViewById(R.id.dialog_item_checkbox);
|
||||
main_container = view.findViewById(R.id.main_container);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,26 +6,27 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.models.Emails;
|
||||
import java.util.List;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import org.gitnex.tea4j.models.Emails;
|
||||
import org.mian.gitnex.R;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdapter.EmailsViewHolder> {
|
||||
public class MyProfileEmailsAdapter extends RecyclerView.Adapter<MyProfileEmailsAdapter.EmailsViewHolder> {
|
||||
|
||||
private List<Emails> emailsList;
|
||||
private Context mCtx;
|
||||
private final List<Emails> emailsList;
|
||||
private final Context context;
|
||||
|
||||
static class EmailsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private ImageView emailPrimary;
|
||||
private TextView userEmail;
|
||||
private final ImageView emailPrimary;
|
||||
private final TextView userEmail;
|
||||
|
||||
private EmailsViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
@@ -36,20 +37,20 @@ public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdap
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileEmailsAdapter(Context mCtx, List<Emails> emailsListMain) {
|
||||
this.mCtx = mCtx;
|
||||
public MyProfileEmailsAdapter(Context ctx, List<Emails> emailsListMain) {
|
||||
this.context = ctx;
|
||||
this.emailsList = emailsListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
public MyProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_emails, parent, false);
|
||||
return new ProfileEmailsAdapter.EmailsViewHolder(v);
|
||||
return new MyProfileEmailsAdapter.EmailsViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ProfileEmailsAdapter.EmailsViewHolder holder, int position) {
|
||||
public void onBindViewHolder(@NonNull MyProfileEmailsAdapter.EmailsViewHolder holder, int position) {
|
||||
|
||||
Emails currentItem = emailsList.get(position);
|
||||
|
||||
@@ -58,12 +59,12 @@ public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdap
|
||||
if(currentItem.getPrimary()) {
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.textColor(mCtx.getResources().getColor(R.color.white))
|
||||
.textColor(ResourcesCompat.getColor(context.getResources(), R.color.colorWhite, null))
|
||||
.fontSize(36)
|
||||
.width(220)
|
||||
.height(60)
|
||||
.endConfig()
|
||||
.buildRoundRect(mCtx.getResources().getString(R.string.emailTypeText), mCtx.getResources().getColor(R.color.tooltipBackground), 8);
|
||||
.buildRoundRect(context.getResources().getString(R.string.emailTypeText), ResourcesCompat.getColor(context.getResources(), R.color.tooltipBackground, null), 8);
|
||||
holder.emailPrimary.setImageDrawable(drawable);
|
||||
}
|
||||
else {
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.ProfileActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class MyProfileFollowersAdapter extends RecyclerView.Adapter<MyProfileFollowersAdapter.FollowersViewHolder> {
|
||||
|
||||
private final List<UserInfo> followersList;
|
||||
private final Context context;
|
||||
|
||||
class FollowersViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private String userLoginId;
|
||||
|
||||
private final ImageView userAvatar;
|
||||
private final TextView userFullName;
|
||||
private final TextView userName;
|
||||
|
||||
private FollowersViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
userAvatar = itemView.findViewById(R.id.userAvatar);
|
||||
userFullName = itemView.findViewById(R.id.userFullName);
|
||||
userName = itemView.findViewById(R.id.userName);
|
||||
|
||||
itemView.setOnClickListener(loginId -> {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.putExtra("username", userLoginId);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
itemView.setOnLongClickListener(loginId -> {
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public MyProfileFollowersAdapter(Context ctx, List<UserInfo> followersListMain) {
|
||||
|
||||
this.context = ctx;
|
||||
this.followersList = followersListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MyProfileFollowersAdapter.FollowersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_followers_following, parent, false);
|
||||
return new FollowersViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MyProfileFollowersAdapter.FollowersViewHolder holder, int position) {
|
||||
|
||||
UserInfo currentItem = followersList.get(position);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
holder.userLoginId = currentItem.getLogin();
|
||||
|
||||
if(!currentItem.getFullname().equals("")) {
|
||||
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
|
||||
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
|
||||
}
|
||||
else {
|
||||
holder.userFullName.setText(currentItem.getUsername());
|
||||
holder.userName.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return followersList.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.ProfileActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class MyProfileFollowingAdapter extends RecyclerView.Adapter<MyProfileFollowingAdapter.FollowingViewHolder> {
|
||||
|
||||
private final List<UserInfo> followingList;
|
||||
private final Context context;
|
||||
|
||||
class FollowingViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private String userLoginId;
|
||||
|
||||
private final ImageView userAvatar;
|
||||
private final TextView userFullName;
|
||||
private final TextView userName;
|
||||
|
||||
private FollowingViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
userAvatar = itemView.findViewById(R.id.userAvatar);
|
||||
userFullName = itemView.findViewById(R.id.userFullName);
|
||||
userName = itemView.findViewById(R.id.userName);
|
||||
|
||||
itemView.setOnClickListener(loginId -> {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.putExtra("username", userLoginId);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
itemView.setOnLongClickListener(loginId -> {
|
||||
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public MyProfileFollowingAdapter(Context ctx, List<UserInfo> followingListMain) {
|
||||
|
||||
this.context = ctx;
|
||||
this.followingList = followingListMain;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MyProfileFollowingAdapter.FollowingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_followers_following, parent, false);
|
||||
return new FollowingViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MyProfileFollowingAdapter.FollowingViewHolder holder, int position) {
|
||||
|
||||
UserInfo currentItem = followingList.get(position);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
holder.userLoginId = currentItem.getLogin();
|
||||
|
||||
if(!currentItem.getFullname().equals("")) {
|
||||
holder.userFullName.setText(Html.fromHtml(currentItem.getFullname()));
|
||||
holder.userName.setText(context.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
|
||||
}
|
||||
else {
|
||||
holder.userFullName.setText(currentItem.getUsername());
|
||||
holder.userName.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return followingList.size();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,35 +1,41 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.Filter;
|
||||
import android.widget.Filterable;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
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.clients.PicassoService;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.models.UserRepositories;
|
||||
import org.mian.gitnex.models.WatchRepository;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
|
||||
import org.gitnex.tea4j.models.UserRepositories;
|
||||
import org.gitnex.tea4j.models.WatchInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.RepoDetailActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@@ -39,250 +45,262 @@ import retrofit2.Callback;
|
||||
|
||||
public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.MyReposViewHolder> implements Filterable {
|
||||
|
||||
private List<UserRepositories> reposList;
|
||||
private Context mCtx;
|
||||
private List<UserRepositories> reposListFull;
|
||||
private final List<UserRepositories> reposList;
|
||||
private final Context context;
|
||||
private final List<UserRepositories> reposListFull;
|
||||
|
||||
static class MyReposViewHolder extends RecyclerView.ViewHolder {
|
||||
static class MyReposViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private ImageView imageMy;
|
||||
private TextView mTextView1My;
|
||||
private TextView mTextView2My;
|
||||
private TextView fullNameMy;
|
||||
private ImageView repoPrivatePublicMy;
|
||||
private TextView repoStarsMy;
|
||||
private TextView repoForksMy;
|
||||
private TextView repoOpenIssuesCountMy;
|
||||
private TextView repoType;
|
||||
private UserRepositories userRepositories;
|
||||
|
||||
private MyReposViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
mTextView1My = itemView.findViewById(R.id.repoNameMy);
|
||||
mTextView2My = itemView.findViewById(R.id.repoDescriptionMy);
|
||||
imageMy = itemView.findViewById(R.id.imageAvatarMy);
|
||||
fullNameMy = itemView.findViewById(R.id.repoFullNameMy);
|
||||
repoPrivatePublicMy = itemView.findViewById(R.id.imageRepoTypeMy);
|
||||
repoStarsMy = itemView.findViewById(R.id.repoStarsMy);
|
||||
repoForksMy = itemView.findViewById(R.id.repoForksMy);
|
||||
repoOpenIssuesCountMy = itemView.findViewById(R.id.repoOpenIssuesCountMy);
|
||||
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
|
||||
repoType = itemView.findViewById(R.id.repoType);
|
||||
private final ImageView image;
|
||||
private final TextView repoName;
|
||||
private final TextView orgName;
|
||||
private final TextView repoDescription;
|
||||
private CheckBox isRepoAdmin;
|
||||
private final TextView repoStars;
|
||||
private final TextView repoLastUpdated;
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
private MyReposViewHolder(View itemView) {
|
||||
|
||||
Context context = v.getContext();
|
||||
super(itemView);
|
||||
repoName = itemView.findViewById(R.id.repoName);
|
||||
orgName = itemView.findViewById(R.id.orgName);
|
||||
repoDescription = itemView.findViewById(R.id.repoDescription);
|
||||
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
|
||||
image = itemView.findViewById(R.id.imageAvatar);
|
||||
repoStars = itemView.findViewById(R.id.repoStars);
|
||||
repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
|
||||
|
||||
Intent intent = new Intent(context, RepoDetailActivity.class);
|
||||
intent.putExtra("repoFullName", fullNameMy.getText().toString());
|
||||
itemView.setOnClickListener(v -> {
|
||||
|
||||
TinyDB tinyDb = new TinyDB(context);
|
||||
tinyDb.putString("repoFullName", fullNameMy.getText().toString());
|
||||
tinyDb.putString("repoType", repoType.getText().toString());
|
||||
//tinyDb.putBoolean("resumeIssues", true);
|
||||
Context context = v.getContext();
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
|
||||
//store if user is watching this repo
|
||||
{
|
||||
final String instanceUrl = tinyDb.getString("instanceUrl");
|
||||
String[] parts = fullNameMy.getText().toString().split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
|
||||
Intent intent = new Intent(context, RepoDetailActivity.class);
|
||||
intent.putExtra("repoFullName", userRepositories.getFullName());
|
||||
|
||||
WatchRepository watch = new WatchRepository();
|
||||
tinyDb.putString("repoFullName", userRepositories.getFullName());
|
||||
//tinyDb.putBoolean("resumeIssues", true);
|
||||
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
|
||||
tinyDb.putString("repoBranch", userRepositories.getDefault_branch());
|
||||
|
||||
Call<WatchRepository> call;
|
||||
if(userRepositories.getPrivateFlag()) {
|
||||
tinyDb.putString("repoType", context.getResources().getString(R.string.strPrivate));
|
||||
}
|
||||
else {
|
||||
tinyDb.putString("repoType", context.getResources().getString(R.string.strPublic));
|
||||
}
|
||||
|
||||
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
|
||||
String[] parts = userRepositories.getFullName().split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
call.enqueue(new Callback<WatchRepository>() {
|
||||
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
|
||||
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
|
||||
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
|
||||
assert repositoryData != null;
|
||||
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(count == 0) {
|
||||
|
||||
assert response.body() != null;
|
||||
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDb.putLong("repositoryId", id);
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDb.putLong("repositoryId", data.getRepositoryId());
|
||||
}
|
||||
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
//store if user is watching this repo
|
||||
{
|
||||
|
||||
if(response.code() != 404) {
|
||||
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
|
||||
|
||||
Toasty.info(context, context.getString(R.string.genericApiStatusError));
|
||||
WatchInfo watch = new WatchInfo();
|
||||
|
||||
}
|
||||
Call<WatchInfo> call;
|
||||
|
||||
}
|
||||
call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName);
|
||||
|
||||
}
|
||||
call.enqueue(new Callback<WatchInfo>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
|
||||
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
Toasty.info(context, context.getString(R.string.genericApiStatusError));
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
assert response.body() != null;
|
||||
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
|
||||
|
||||
context.startActivity(intent);
|
||||
}
|
||||
else {
|
||||
|
||||
});
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
|
||||
reposDropdownMenu.setOnClickListener(v -> {
|
||||
if(response.code() != 404) {
|
||||
|
||||
final Context context = v.getContext();
|
||||
Toasty.error(context, context.getString(R.string.genericApiStatusError));
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
|
||||
}
|
||||
|
||||
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
|
||||
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
|
||||
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
|
||||
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
|
||||
}
|
||||
|
||||
bottomSheetHeader.setText(fullNameMy.getText());
|
||||
BottomSheetDialog dialog = new BottomSheetDialog(context);
|
||||
dialog.setContentView(view);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
|
||||
|
||||
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
|
||||
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullNameMy.getText());
|
||||
context.startActivity(intentOpenInBrowser);
|
||||
dialog.dismiss();
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
Toasty.error(context, context.getString(R.string.genericApiStatusError));
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
repoStargazers.setOnClickListener(stargazers -> {
|
||||
}
|
||||
|
||||
Intent intent = new Intent(context, RepoStargazersActivity.class);
|
||||
intent.putExtra("repoFullNameForStars", fullNameMy.getText());
|
||||
context.startActivity(intent);
|
||||
dialog.dismiss();
|
||||
context.startActivity(intent);
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
repoWatchers.setOnClickListener(watchers -> {
|
||||
}
|
||||
|
||||
Intent intentW = new Intent(context, RepoWatchersActivity.class);
|
||||
intentW.putExtra("repoFullNameForWatchers", fullNameMy.getText());
|
||||
context.startActivity(intentW);
|
||||
dialog.dismiss();
|
||||
public MyReposListAdapter(Context ctx, List<UserRepositories> reposListMain) {
|
||||
|
||||
});
|
||||
this.context = ctx;
|
||||
this.reposList = reposListMain;
|
||||
reposListFull = new ArrayList<>(reposList);
|
||||
}
|
||||
|
||||
});
|
||||
@NonNull
|
||||
@Override
|
||||
public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
}
|
||||
}
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
|
||||
return new MyReposListAdapter.MyReposViewHolder(v);
|
||||
}
|
||||
|
||||
public MyReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
|
||||
this.mCtx = mCtx;
|
||||
this.reposList = reposListMain;
|
||||
reposListFull = new ArrayList<>(reposList);
|
||||
}
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MyReposListAdapter.MyReposViewHolder holder, int position) {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_my_repos, parent, false);
|
||||
return new MyReposListAdapter.MyReposViewHolder(v);
|
||||
}
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
UserRepositories currentItem = reposList.get(position);
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MyReposListAdapter.MyReposViewHolder holder, int position) {
|
||||
Locale locale = context.getResources().getConfiguration().locale;
|
||||
String timeFormat = tinyDb.getString("dateFormat");
|
||||
holder.userRepositories = currentItem;
|
||||
holder.orgName.setText(currentItem.getFullName().split("/")[0]);
|
||||
holder.repoName.setText(currentItem.getFullName().split("/")[1]);
|
||||
holder.repoStars.setText(currentItem.getStars_count());
|
||||
|
||||
UserRepositories currentItem = reposList.get(position);
|
||||
holder.mTextView2My.setVisibility(View.GONE);
|
||||
ColorGenerator generator = ColorGenerator.MATERIAL;
|
||||
int color = generator.getColor(currentItem.getName());
|
||||
String firstCharacter = String.valueOf(currentItem.getFullName().charAt(0));
|
||||
|
||||
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);
|
||||
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.useFont(Typeface.DEFAULT)
|
||||
.fontSize(18)
|
||||
.toUpperCase()
|
||||
.width(28)
|
||||
.height(28)
|
||||
.endConfig()
|
||||
.buildRoundRect(firstCharacter, color, 3);
|
||||
if(currentItem.getAvatar_url() != null) {
|
||||
if(!currentItem.getAvatar_url().equals("")) {
|
||||
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
|
||||
}
|
||||
else {
|
||||
holder.image.setImageDrawable(drawable);
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.image.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
if (currentItem.getAvatar_url() != null) {
|
||||
if (!currentItem.getAvatar_url().equals("")) {
|
||||
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.imageMy);
|
||||
} else {
|
||||
holder.imageMy.setImageDrawable(drawable);
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.imageMy.setImageDrawable(drawable);
|
||||
}
|
||||
if(currentItem.getUpdated_at() != null) {
|
||||
|
||||
holder.mTextView1My.setText(currentItem.getName());
|
||||
if (!currentItem.getDescription().equals("")) {
|
||||
holder.mTextView2My.setVisibility(View.VISIBLE);
|
||||
holder.mTextView2My.setText(currentItem.getDescription());
|
||||
}
|
||||
holder.fullNameMy.setText(currentItem.getFullname());
|
||||
if(currentItem.getPrivateFlag()) {
|
||||
holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_lock_bold);
|
||||
holder.repoType.setText(R.string.strPrivate);
|
||||
}
|
||||
else {
|
||||
holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_public);
|
||||
holder.repoType.setText(R.string.strPublic);
|
||||
}
|
||||
holder.repoStarsMy.setText(currentItem.getStars_count());
|
||||
holder.repoForksMy.setText(currentItem.getForks_count());
|
||||
holder.repoOpenIssuesCountMy.setText(currentItem.getOpen_issues_count());
|
||||
switch(timeFormat) {
|
||||
case "pretty": {
|
||||
PrettyTime prettyTime = new PrettyTime(locale);
|
||||
String createdTime = prettyTime.format(currentItem.getUpdated_at());
|
||||
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
|
||||
holder.repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), context));
|
||||
break;
|
||||
}
|
||||
case "normal": {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
String createdTime = formatter.format(currentItem.getUpdated_at());
|
||||
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
|
||||
break;
|
||||
}
|
||||
case "normal1": {
|
||||
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
String createdTime = formatter.format(currentItem.getUpdated_at());
|
||||
holder.repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, createdTime));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.repoLastUpdated.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
if(!currentItem.getDescription().equals("")) {
|
||||
holder.repoDescription.setText(currentItem.getDescription());
|
||||
}
|
||||
else {
|
||||
holder.repoDescription.setText(context.getString(R.string.noDataDescription));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return reposList.size();
|
||||
}
|
||||
if(holder.isRepoAdmin == null) {
|
||||
holder.isRepoAdmin = new CheckBox(context);
|
||||
}
|
||||
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
return myReposFilter;
|
||||
}
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
private Filter myReposFilter = new Filter() {
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
List<UserRepositories> filteredList = new ArrayList<>();
|
||||
return reposList.size();
|
||||
}
|
||||
|
||||
if (constraint == null || constraint.length() == 0) {
|
||||
filteredList.addAll(reposListFull);
|
||||
} else {
|
||||
String filterPattern = constraint.toString().toLowerCase().trim();
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
|
||||
for (UserRepositories item : reposListFull) {
|
||||
if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
|
||||
filteredList.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return myReposFilter;
|
||||
}
|
||||
|
||||
FilterResults results = new FilterResults();
|
||||
results.values = filteredList;
|
||||
private final Filter myReposFilter = new Filter() {
|
||||
|
||||
return results;
|
||||
}
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
|
||||
List<UserRepositories> filteredList = new ArrayList<>();
|
||||
|
||||
if(constraint == null || constraint.length() == 0) {
|
||||
filteredList.addAll(reposListFull);
|
||||
}
|
||||
else {
|
||||
String filterPattern = constraint.toString().toLowerCase().trim();
|
||||
|
||||
for(UserRepositories item : reposListFull) {
|
||||
if(item.getFullName().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
|
||||
filteredList.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FilterResults results = new FilterResults();
|
||||
results.values = filteredList;
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
|
||||
reposList.clear();
|
||||
reposList.addAll((List) results.values);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
reposList.clear();
|
||||
reposList.addAll((List) results.values);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.NotificationThread;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author opyale
|
||||
*/
|
||||
|
||||
public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.NotificationsViewHolder> {
|
||||
|
||||
private final Context context;
|
||||
private final List<NotificationThread> notificationThreads;
|
||||
private final OnMoreClickedListener onMoreClickedListener;
|
||||
private final OnNotificationClickedListener onNotificationClickedListener;
|
||||
private final TinyDB tinyDb;
|
||||
|
||||
public NotificationsAdapter(Context context, List<NotificationThread> notificationThreads, OnMoreClickedListener onMoreClickedListener, OnNotificationClickedListener onNotificationClickedListener) {
|
||||
|
||||
this.tinyDb = TinyDB.getInstance(context);
|
||||
this.context = context;
|
||||
this.notificationThreads = notificationThreads;
|
||||
this.onMoreClickedListener = onMoreClickedListener;
|
||||
this.onNotificationClickedListener = onNotificationClickedListener;
|
||||
}
|
||||
|
||||
static class NotificationsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final LinearLayout frame;
|
||||
private final TextView subject;
|
||||
private final TextView repository;
|
||||
private final ImageView typePr;
|
||||
private final ImageView typeIssue;
|
||||
private final ImageView typeUnknown;
|
||||
private final ImageView pinned;
|
||||
private final ImageView more;
|
||||
|
||||
public NotificationsViewHolder(@NonNull View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
frame = itemView.findViewById(R.id.frame);
|
||||
subject = itemView.findViewById(R.id.subject);
|
||||
repository = itemView.findViewById(R.id.repository);
|
||||
typePr = itemView.findViewById(R.id.typePr);
|
||||
typeIssue = itemView.findViewById(R.id.typeIssue);
|
||||
typeUnknown = itemView.findViewById(R.id.typeUnknown);
|
||||
pinned = itemView.findViewById(R.id.pinned);
|
||||
more = itemView.findViewById(R.id.more);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public NotificationsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(context).inflate(R.layout.list_notifications, parent, false);
|
||||
return new NotificationsAdapter.NotificationsViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull NotificationsViewHolder holder, int position) {
|
||||
|
||||
NotificationThread notificationThread = notificationThreads.get(position);
|
||||
|
||||
String url = notificationThread.getSubject().getUrl();
|
||||
String subjectId = "<font color='" + ResourcesCompat.getColor(context.getResources(), R.color.lightGray, null) + "'>" + context.getResources()
|
||||
.getString(R.string.hash) + url.substring(url.lastIndexOf("/") + 1) + "</font>";
|
||||
|
||||
holder.subject.setText(HtmlCompat.fromHtml(subjectId + " " + notificationThread.getSubject().getTitle(), HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
holder.repository.setText(notificationThread.getRepository().getFullName());
|
||||
|
||||
if(notificationThread.isPinned()) {
|
||||
holder.pinned.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.pinned.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
switch(notificationThread.getSubject().getType()) {
|
||||
|
||||
case "Pull":
|
||||
holder.typePr.setVisibility(View.VISIBLE);
|
||||
holder.typeIssue.setVisibility(View.GONE);
|
||||
holder.typeUnknown.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
case "Issue":
|
||||
holder.typePr.setVisibility(View.GONE);
|
||||
holder.typeIssue.setVisibility(View.VISIBLE);
|
||||
holder.typeUnknown.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
default:
|
||||
holder.typePr.setVisibility(View.GONE);
|
||||
holder.typeIssue.setVisibility(View.GONE);
|
||||
holder.typeUnknown.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
holder.frame.setOnClickListener(v -> {
|
||||
|
||||
onNotificationClickedListener.onNotificationClicked(notificationThread);
|
||||
|
||||
String[] parts = notificationThread.getRepository().getFullName().split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
|
||||
RepositoriesApi repositoryData = BaseApi.getInstance(context, RepositoriesApi.class);
|
||||
|
||||
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
|
||||
if(count == 0) {
|
||||
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDb.putLong("repositoryId", id);
|
||||
} else {
|
||||
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
|
||||
tinyDb.putLong("repositoryId", data.getRepositoryId());
|
||||
}
|
||||
});
|
||||
|
||||
holder.more.setOnClickListener(v -> onMoreClickedListener.onMoreClicked(notificationThread));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return notificationThreads.size();
|
||||
}
|
||||
|
||||
public interface OnNotificationClickedListener {
|
||||
|
||||
void onNotificationClicked(NotificationThread notificationThread);
|
||||
}
|
||||
|
||||
public interface OnMoreClickedListener {
|
||||
|
||||
void onMoreClicked(NotificationThread notificationThread);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.mian.gitnex.adapters;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -12,12 +10,15 @@ 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.gitnex.tea4j.models.UserOrganizations;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.OrganizationDetailActivity;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.models.UserOrganizations;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.util.TinyDB;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -27,46 +28,42 @@ import java.util.List;
|
||||
|
||||
public class OrganizationsListAdapter extends RecyclerView.Adapter<OrganizationsListAdapter.OrganizationsViewHolder> implements Filterable {
|
||||
|
||||
private List<UserOrganizations> orgList;
|
||||
private Context mCtx;
|
||||
private List<UserOrganizations> orgListFull;
|
||||
private final List<UserOrganizations> orgList;
|
||||
private final Context context;
|
||||
private final List<UserOrganizations> orgListFull;
|
||||
|
||||
static class OrganizationsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private ImageView image;
|
||||
private TextView mTextView1;
|
||||
private TextView mTextView2;
|
||||
private TextView organizationId;
|
||||
private UserOrganizations userOrganizations;
|
||||
|
||||
private final ImageView image;
|
||||
private final TextView orgName;
|
||||
private final TextView orgDescription;
|
||||
|
||||
private OrganizationsViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
mTextView1 = itemView.findViewById(R.id.orgUsername);
|
||||
mTextView2 = itemView.findViewById(R.id.orgDescription);
|
||||
orgName = itemView.findViewById(R.id.orgName);
|
||||
orgDescription = itemView.findViewById(R.id.orgDescription);
|
||||
image = itemView.findViewById(R.id.imageAvatar);
|
||||
organizationId = itemView.findViewById(R.id.organizationId);
|
||||
|
||||
itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
itemView.setOnClickListener(v -> {
|
||||
|
||||
Context context = v.getContext();
|
||||
Intent intent = new Intent(context, OrganizationDetailActivity.class);
|
||||
intent.putExtra("orgName", mTextView1.getText().toString());
|
||||
Context context = v.getContext();
|
||||
Intent intent = new Intent(context, OrganizationDetailActivity.class);
|
||||
intent.putExtra("orgName", userOrganizations.getUsername());
|
||||
|
||||
TinyDB tinyDb = new TinyDB(context);
|
||||
tinyDb.putString("orgName", mTextView1.getText().toString());
|
||||
tinyDb.putString("organizationId", organizationId.getText().toString());
|
||||
tinyDb.putBoolean("organizationAction", true);
|
||||
context.startActivity(intent);
|
||||
|
||||
}
|
||||
TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
tinyDb.putString("orgName", userOrganizations.getUsername());
|
||||
tinyDb.putString("organizationId", String.valueOf(userOrganizations.getId()));
|
||||
tinyDb.putBoolean("organizationAction", true);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public OrganizationsListAdapter(Context mCtx, List<UserOrganizations> orgsListMain) {
|
||||
this.mCtx = mCtx;
|
||||
public OrganizationsListAdapter(Context ctx, List<UserOrganizations> orgsListMain) {
|
||||
|
||||
this.context = ctx;
|
||||
this.orgList = orgsListMain;
|
||||
orgListFull = new ArrayList<>(orgList);
|
||||
}
|
||||
@@ -74,6 +71,7 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<Organizations
|
||||
@NonNull
|
||||
@Override
|
||||
public OrganizationsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_organizations, parent, false);
|
||||
return new OrganizationsViewHolder(v);
|
||||
}
|
||||
@@ -83,16 +81,17 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<Organizations
|
||||
public void onBindViewHolder(@NonNull OrganizationsViewHolder holder, int position) {
|
||||
|
||||
UserOrganizations currentItem = orgList.get(position);
|
||||
holder.mTextView2.setVisibility(View.GONE);
|
||||
holder.organizationId.setText(Integer.toString(currentItem.getId()));
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
holder.userOrganizations = currentItem;
|
||||
holder.orgName.setText(currentItem.getUsername());
|
||||
|
||||
PicassoService.getInstance(context).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(holder.image);
|
||||
|
||||
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
|
||||
holder.mTextView1.setText(currentItem.getUsername());
|
||||
if (!currentItem.getDescription().equals("")) {
|
||||
holder.mTextView2.setVisibility(View.VISIBLE);
|
||||
holder.mTextView2.setText(currentItem.getDescription());
|
||||
}
|
||||
|
||||
holder.orgDescription.setText(currentItem.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,14 +104,19 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<Organizations
|
||||
return orgFilter;
|
||||
}
|
||||
|
||||
private Filter orgFilter = new Filter() {
|
||||
private final Filter orgFilter = new Filter() {
|
||||
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
|
||||
List<UserOrganizations> filteredList = new ArrayList<>();
|
||||
|
||||
if (constraint == null || constraint.length() == 0) {
|
||||
|
||||
filteredList.addAll(orgListFull);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
String filterPattern = constraint.toString().toLowerCase().trim();
|
||||
|
||||
for (UserOrganizations item : orgListFull) {
|
||||
@@ -130,6 +134,7 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<Organizations
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
|
||||
orgList.clear();
|
||||
orgList.addAll((List) results.values);
|
||||
notifyDataSetChanged();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user