Compare commits

..

10 Commits

Author SHA1 Message Date
7317f3c841 Merge pull request 'Prepare 2.4.1 release' (#301) from prepare-release-2.4.1 into release-2.4
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/301
2020-03-19 13:24:47 +00:00
8b12e51335 Prepare 2.4.1 release 2020-03-19 18:22:37 +05:00
086f982d26 Merge pull request 'Backport show only issues, use StandardCharsets instead in okhttp' (#300) from backport-show-only-issues into release-2.4
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/300
2020-03-19 13:16:55 +00:00
88feca3564 Backport show only issues, use StandardCharsets instead in okhttp 2020-03-19 18:14:13 +05:00
40337d10b4 Merge pull request 'fixed #297 in release-2.4 branch' (#299) from a671916c/GitNex:release-2.4 into release-2.4
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/299
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-03-18 18:43:37 +00:00
05056f28ac fixed #297 in release-2.4 branch 2020-03-18 19:32:56 +01:00
94af921a99 Merge pull request 'Fix files breadcrumb nav' (#289) from 287-fix-files-breadcrumb into release-2.4
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/289
2020-03-16 14:47:03 +00:00
ac3cc11920 Fix files breadcrumb nav 2020-03-16 19:40:46 +05:00
23c8bb3a48 Merge pull request 'crowdin update' (#285) from 6543/GitNex:backport_284 into release-2.4
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/285
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-03-15 18:46:52 +00:00
8c97160737 crowdin update 2020-03-15 19:40:47 +01:00
548 changed files with 13686 additions and 29687 deletions

View File

@ -1,65 +1,21 @@
--- ---
kind: pipeline kind: pipeline
type: docker name: gitnex-ci-test
name: tests
steps: steps:
- name: unit-tests - name: test
image: nextcloudci/android:android-49 image: nextcloudci/android:android-49
depends_on: [ clone ]
commands: commands:
- ./gradlew test - ./gradlew test
- name: check-formatting
image: zosiab/eclint:latest
depends_on: [ clone ]
commands:
- git pull origin master
- eclint check $(git diff --name-only origin/master)
# This may be used in the future, because it makes of intellij's native code inspection/formatting capabilities.
# Additional information: https://www.jetbrains.com/help/idea/command-line-formatter.html
#
# - name: do-or-check-formatting
# image: dlsniper/docker-intellij
# depends_on: [ clone ]
# commands:
# - /opt/intellij/bin/idea.sh inspect/format ...
#
# - 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: trigger:
event: event:
- pull_request - pull_request
--- ---
kind: pipeline kind: pipeline
type: docker name: gitnex-ci-build
name: code-analysis
steps:
- name: check-global-formatting
image: zosiab/eclint:latest
depends_on: [ clone ]
commands:
- eclint check $(git ls-files)
trigger:
event:
- push
branch:
- master
---
kind: pipeline
type: docker
name: build
steps: steps:
@ -68,35 +24,6 @@ steps:
commands: commands:
- ./gradlew build - ./gradlew build
- name: sign
image: nextcloudci/android:android-49
environment:
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
KS_FILE: ci_keystore.jks
KS_REPO:
from_secret: KS_REPO
commands:
- ./scripts/sign-build.sh
- name: publish
image: vividboarder/drone-webdav
environment:
WEBDAV_USERNAME: GitNexBot
WEBDAV_PASSWORD:
from_secret: NC_TOKEN
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: trigger:
event: event:
- push - push

View File

@ -1,25 +0,0 @@
[*]
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

View File

@ -1,32 +0,0 @@
## # What do you want to address?
(This step is required; examples are shown below)
- [ ] Bug
- [ ] Feature
- [ ] Suggestion
## # Describe your matter briefly
(This step is required)
##### What did you expect? (Useful when addressing bugs)
---
_(This step is optional)_
##### Some additional details (Useful, when we are trying to reproduce a bug)
---
_(This step is optional; an example is shown below)_
* The version of **Gitea** you are using:
* The version of **GitNex** you are using:
* Phone **OS** version and model:
* The type of certificate you are using (self-signed, signed):
* How you used to log in (via password or token):
##### We would appreciate some screenshots or stacktrace's, but this is also not required.
---
_(Screenshots and stacktrace's can go here)_
#### Thank you for your time.

View File

@ -1,8 +0,0 @@
Please check the following:
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 youre targeting (create one if does not exist)
**You MUST delete the content above including this line before posting, otherwise your pull request will be invalid.**

4
.gitignore vendored
View File

@ -8,9 +8,6 @@
*.ap_ *.ap_
*.aab *.aab
# Release dir
app/release/*
# Files for the ART/Dalvik VM # Files for the ART/Dalvik VM
*.dex *.dex
@ -51,7 +48,6 @@ captures/
.idea/dictionaries .idea/dictionaries
.idea/libraries .idea/libraries
.idea/caches .idea/caches
!.idea/codeStyles
# Keystore files # Keystore files
# Uncomment the following lines if you do not want to check your keystore files in. # Uncomment the following lines if you do not want to check your keystore files in.

View File

@ -1,63 +0,0 @@
stages:
- test
- build
- sign
- publish
test:
image: nextcloudci/android:android-49
stage: test
script:
- ./gradlew test
build:
image: nextcloudci/android:android-49
stage: build
only:
- master
script:
- ./gradlew build
artifacts:
paths:
- app/build/outputs/
expire_in: 15 minutes
sign:
image: nextcloudci/android:android-49
stage: sign
only:
- master
variables:
OUTPUT: "signed.apk"
GITEA: "https://gitea.com"
KS_FILE: "ci_keystore.jks"
script:
- ./scripts/sign-build.sh
artifacts:
paths:
- signed.apk
expire_in: 15 minutes
latest:
image: tutum/curl
stage: publish
only:
- master
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: tutum/curl
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'

View File

@ -1,165 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JavaCodeStyleSettings>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
<package name="androidx" withSubpackages="true" static="false" />
<package name="com" withSubpackages="true" static="false" />
<package name="junit" withSubpackages="true" static="false" />
<package name="net" withSubpackages="true" static="false" />
<package name="org" withSubpackages="true" static="false" />
<package name="java" withSubpackages="true" static="false" />
<package name="javax" withSubpackages="true" static="false" />
<package name="" withSubpackages="true" static="false" />
<package name="" withSubpackages="true" static="true" />
</value>
</option>
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="220" />
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="BLANK_LINES_BEFORE_METHOD_BODY" value="1" />
<option name="BLANK_LINES_AROUND_FIELD_IN_INTERFACE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="BLANK_LINES_AFTER_ANONYMOUS_CLASS_HEADER" value="1" />
<option name="BLANK_LINES_BEFORE_CLASS_END" value="1" />
<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" />
<option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
<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" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

View File

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

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

View File

@ -7,11 +7,6 @@ Patches, enhancements, features are always welcome. The PR should focus on the s
Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work. Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work.
**Code Standards**
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://codeberg.org/gitnex/GitNex/wiki/Code-Standards)
**How to submit a PR** **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. 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.

View File

@ -3,7 +3,6 @@ This part lists all PUBLIC individuals having contributed content to the code.
* M M Arif (mmarif) * M M Arif (mmarif)
* 6543 * 6543
* opyale
* Unpublished * Unpublished
# Translators # Translators

63
LICENSE
View File

@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@ -620,18 +620,55 @@ copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
GitNex is an Android client/application for Gitea. How to Apply These Terms to Your New Programs
Copyright (C) 2019 The GitNex Authors
This program is free software: you can redistribute it and/or modify If you develop a new program, and you want it to be of the greatest
it under the terms of the GNU General Public License as published by possible use to the public, the best way to achieve this is to make it
the Free Software Foundation, either version 3 of the License, or free software which everyone can redistribute and change under these terms.
(at your option) any later version.
This program is distributed in the hope that it will be useful, To do so, attach the following notices to the program. It is safest
but WITHOUT ANY WARRANTY; without even the implied warranty of to attach them to the start of each source file to most effectively
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the state the exclusion of warranty; and each file should have at least
GNU General Public License for more details. the "copyright" line and a pointer to where the full notice is found.
You should have received a copy of the GNU General Public License Mastalab is a Mastodon client for Android devices
along with this program. If not, see <https://www.gnu.org/licenses/>. 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>.

View File

@ -1,22 +1,27 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://codeberg.org/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://codeberg.org/gitnex/GitNex/releases) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://gitea.com/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://gitea.com/gitnex/GitNex/releases)
[![Build Status](https://drone.gitea.com/api/badges/gitnex/GitNex/status.svg)](https://drone.gitea.com/gitnex/GitNex)
[![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex)
[<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif) [<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate) [<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif)
[<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate)
# GitNex - Android client for Gitea # GitNex - Android client for Gitea
GitNex is a free, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go. GitNex is a free, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go.
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. 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 ## Downloads
[<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/) [<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/)
[<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex) [<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex)
[<img alt='Download builds and releases' src='assets/apk-badge.png' height="82"/>](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE) [<img alt='Download APK' src='https://gitnex.com/img/download-apk.png' height="80"/>](https://gitea.com/gitnex/GitNex/releases)
## Note about Gitea version ## Note about Gitea version
Please make sure that you are on latest stable release or later for better app experience. Please make sure that you are on latest stable release or later for better app experience.
Check the versions [compatibility page](https://codeberg.org/gitnex/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio. Check the versions [compatibility page](https://gitea.com/gitnex/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio.
## Build from source ## Build from source
Option 1 - Download the source code, open it in Android Studio and build it there. Option 1 - Download the source code, open it in Android Studio and build it there.
@ -24,50 +29,48 @@ Option 1 - Download the source code, open it in Android Studio and build it ther
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 build`.
## Features ## Features
- Repositories / issues/ org list
- File and directory browser - File and directory browser
- File viewer
- Create files - Create files
- Explore repositories - Explore repositories
- Issues list
- Pull requests - Pull requests
- Files diff for PRs - Merge pull request
- Notifications - [MANY MORE](https://gitea.com/gitnex/GitNex/wiki/Features)
- Drafts
- [MANY MORE](https://codeberg.org/gitnex/GitNex/wiki/Features)
## Contributing ## Contributing
[CONTRIBUTING](https://codeberg.org/gitnex/GitNex/src/branch/master/CONTRIBUTING.md) [CONTRIBUTING](https://gitea.com/gitnex/GitNex/src/branch/master/CONTRIBUTING.md)
## Translation ## Translation
Help us translate GitNex to your native language. Help us translate GitNex to your native language.
We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your language is not listed, please request [here](https://codeberg.org/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://gitea.com/gitnex/GitNex/issues) to add it to the project.
**Link: https://crowdin.com/project/GitNex** **Link: https://crowdin.com/project/GitNex**
## Screenshots: ## Screenshots:
<img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/001.png" alt="001.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/002.png" alt="002.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/003.png" alt="003.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/004.png" alt="004.png" width="200"/> <img src="https://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/master/fastlane/metadata/android/en-US/images/phoneScreenshots/005.png" alt="005.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/006.png" alt="006.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/007.png" alt="007.png" width="200"/> | <img src="https://codeberg.org/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/008.png" alt="008.png" width="200"/> <img src="https://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
[Faq](https://codeberg.org/gitnex/GitNex/wiki/FAQ) [Faq](https://gitea.com/gitnex/GitNex/wiki/FAQ)
## Links ## Links
[Website](https://gitnex.com) [Website](https://gitnex.com)
[Wiki](https://codeberg.org/gitnex/GitNex/wiki/Home) [Wiki](https://gitea.com/gitnex/GitNex/wiki/Home)
[Website Repository](https://gitlab.com/mmarif4u/gitnex-website) [Website Repository](https://gitlab.com/mmarif4u/gitnex-website)
[Troubleshoot Guide](https://codeberg.org/gitnex/GitNex/wiki/Troubleshoot-Guide) [Troubleshoot Guide](https://gitea.com/gitnex/GitNex/wiki/Troubleshoot-Guide)
## Thanks ## Thanks
Thanks to all the open source libraries, contributors and donators. Thanks to all the open source libraries, contributors and donators.
#### Open source libraries Open source libraries
- Retrofit - Retrofit
- Gson - Gson
- Okhttp - Okhttp
@ -87,8 +90,5 @@ Thanks to all the open source libraries, contributors and donators.
- Caverock/androidsvg - Caverock/androidsvg
- Droidsonroids.gif/android-gif-drawable - Droidsonroids.gif/android-gif-drawable
- Barteksc/AndroidPdfViewer - Barteksc/AndroidPdfViewer
- Ge0rg/MemorizingTrustManager
- Dimezis/BlurView
- mikaelhg/urlbuilder
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif) [Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)

View File

@ -6,17 +6,13 @@ android {
applicationId "org.mian.gitnex" applicationId "org.mian.gitnex"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 29
versionCode 301 versionCode 91
versionName "3.0.1" versionName "2.4.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildFeatures {
viewBinding = true
}
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
} }
@ -24,43 +20,31 @@ android {
//checkReleaseBuilds false //checkReleaseBuilds false
abortOnError false abortOnError false
} }
compileOptions {
targetCompatibility = "8"
sourceCompatibility = "8"
}
}
configurations {
cleanedAnnotations
compile.exclude group: 'org.jetbrains', module: 'annotations'
} }
dependencies { dependencies {
def lifecycle_version = "2.3.0-alpha05" def lifecycle_version = "2.2.0"
def markwon_version = "4.4.0" final def markwon_version = "4.1.1"
def work_version = "2.4.0"
def acra = "5.5.0"
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:1.3.0-alpha01" implementation "androidx.appcompat:appcompat:1.1.0"
implementation "com.google.android.material:material:1.3.0-alpha01" implementation "com.google.android.material:material:1.2.0-alpha05"
implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" testImplementation "junit:junit:4.12"
testImplementation "junit:junit:4.13"
androidTestImplementation "androidx.test:runner:1.2.0" androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0" androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
implementation "com.github.vihtarb:tooltip:0.2.0" implementation "com.github.vihtarb:tooltip:0.2.0"
implementation 'com.squareup.okhttp3:okhttp:4.8.0' implementation "com.squareup.okhttp3:okhttp:3.12.1"
implementation "com.google.code.gson:gson:2.8.6" implementation "com.google.code.gson:gson:2.8.5"
implementation "com.squareup.picasso:picasso:2.71828" implementation "com.squareup.picasso:picasso:2.71828"
implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1" implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1"
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation "com.squareup.retrofit2:retrofit:2.5.0"
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation "com.squareup.retrofit2:converter-gson:2.5.0"
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' implementation "com.squareup.retrofit2:converter-scalars:2.5.0"
implementation 'com.squareup.okhttp3:logging-interceptor:4.8.0' implementation "com.squareup.okhttp3:logging-interceptor:3.12.1"
implementation 'org.ocpsoft.prettytime:prettytime:4.0.5.Final' implementation "org.ocpsoft.prettytime:prettytime:4.0.1.Final"
implementation "com.vdurmont:emoji-java:5.1.1" implementation "com.vdurmont:emoji-java:4.0.0"
implementation "com.pes.materialcolorpicker:library:1.2.5" implementation "com.pes.materialcolorpicker:library:1.2.5"
implementation "io.noties.markwon:core:$markwon_version" implementation "io.noties.markwon:core:$markwon_version"
implementation "io.noties.markwon:ext-latex:$markwon_version" implementation "io.noties.markwon:ext-latex:$markwon_version"
@ -79,18 +63,11 @@ dependencies {
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.19" implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.19"
implementation "com.hendraanggrian.appcompat:socialview:0.2" implementation "com.hendraanggrian.appcompat:socialview:0.2"
implementation "com.hendraanggrian.appcompat:socialview-commons:0.2" implementation "com.hendraanggrian.appcompat:socialview-commons:0.2"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9" implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
implementation "commons-io:commons-io:20030203.000550" implementation "commons-io:commons-io:2.6"
implementation "org.apache.commons:commons-lang3:3.10"
implementation "com.github.chrisbanes:PhotoView:2.3.0" implementation "com.github.chrisbanes:PhotoView:2.3.0"
implementation "com.pddstudio:highlightjs-android:1.5.0"
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1" implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
implementation "ch.acra:acra-mail:$acra"
implementation "ch.acra:acra-limiter:$acra"
implementation "ch.acra:acra-notification:$acra"
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor "androidx.room:room-compiler:2.2.5"
implementation "androidx.work:work-runtime:$work_version"
implementation "com.eightbitlab:blurview:1.6.3"
implementation "io.mikael:urlbuilder:2.0.9"
} }

View File

@ -4,25 +4,23 @@
package="org.mian.gitnex"> package="org.mian.gitnex">
<uses-permission android:name="android.permission.INTERNET" /> <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.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/app_logo" android:icon="@mipmap/app_logo"
android:label="@string/app_name" android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:resizeableActivity="true"
android:roundIcon="@mipmap/app_logo_round" android:roundIcon="@mipmap/app_logo_round"
android:supportsRtl="true" android:supportsRtl="true"
tools:targetApi="n"> tools:targetApi="n">
<activity android:name=".activities.MergePullRequestActivity" /> <activity android:name=".activities.MergePullRequestActivity" />
<activity <activity
android:name=".activities.FileViewActivity" android:name=".activities.FileViewActivity"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.CreateFileActivity" android:name=".activities.NewFileActivity"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.RepoWatchersActivity" android:name=".activities.RepoWatchersActivity"
@ -43,16 +41,16 @@
<activity android:name=".activities.ProfileEmailActivity" /> <activity android:name=".activities.ProfileEmailActivity" />
<activity android:name=".activities.AddCollaboratorToRepositoryActivity" /> <activity android:name=".activities.AddCollaboratorToRepositoryActivity" />
<activity android:name=".activities.CreateTeamByOrgActivity" /> <activity android:name=".activities.CreateTeamByOrgActivity" />
<activity android:name=".activities.OrganizationTeamMembersActivity" /> <activity android:name=".activities.OrgTeamMembersActivity" />
<activity <activity
android:name=".activities.OrganizationDetailActivity" android:name=".activities.OrgDetailActivity"
android:label="@string/title_activity_org_detail" android:label="@string/title_activity_org_detail"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".activities.SponsorsActivity" /> <activity android:name=".activities.SponsorsActivity" />
<activity android:name=".activities.CreditsActivity" /> <activity android:name=".activities.CreditsActivity" />
<activity android:name=".activities.CreateLabelActivity" /> <activity android:name=".activities.CreateLabelActivity" />
<activity android:name=".activities.CreateIssueActivity" /> <activity android:name=".activities.CreateIssueActivity" />
<activity android:name=".activities.CreateMilestoneActivity" /> <activity android:name=".activities.NewMilestoneActivity" />
<activity android:name=".activities.ReplyToIssueActivity" /> <activity android:name=".activities.ReplyToIssueActivity" />
<activity <activity
android:name=".activities.IssueDetailActivity" android:name=".activities.IssueDetailActivity"
@ -61,7 +59,7 @@
android:name=".activities.RepoDetailActivity" android:name=".activities.RepoDetailActivity"
android:label="@string/title_activity_repo_detail" android:label="@string/title_activity_repo_detail"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".activities.MainActivity" android:theme="@android:style/Theme.NoTitleBar" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"> <activity android:name=".activities.MainActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -70,26 +68,11 @@
</activity> </activity>
<activity <activity
android:name=".activities.LoginActivity" android:name=".activities.LoginActivity"
android:launchMode="singleTask" android:theme="@android:style/Theme.NoTitleBar"/> android:launchMode="singleTask" />
<activity android:name=".activities.CreateRepoActivity" /> <activity android:name=".activities.NewRepoActivity" />
<activity android:name=".activities.CreateOrganizationActivity" /> <activity android:name=".activities.NewOrganizationActivity" />
<activity android:name=".activities.OpenRepoInBrowserActivity" /> <activity android:name=".activities.OpenRepoInBrowserActivity" />
<activity android:name=".activities.FileDiffActivity" /> <activity android:name=".activities.FileDiffActivity" />
<activity android:name=".activities.CommitsActivity" />
<activity android:name=".helpers.ssl.MemorizingActivity" android:theme="@android:style/Theme.Material.Dialog" />
<activity android:name=".activities.SettingsAppearanceActivity" />
<activity android:name=".activities.SettingsFileViewerActivity" />
<activity android:name=".activities.SettingsSecurityActivity" />
<activity android:name=".activities.SettingsTranslationActivity" />
<activity android:name=".activities.SettingsReportsActivity" />
<activity android:name=".activities.AddNewTeamMemberActivity" />
<activity android:name=".activities.SettingsDraftsActivity" />
<!-- 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"/>
</application> </application>
</manifest> </manifest>

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,16 +2,16 @@ package org.mian.gitnex.actions;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.AddCollaboratorToRepositoryActivity; import org.mian.gitnex.activities.AddCollaboratorToRepositoryActivity;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Permission; import org.mian.gitnex.models.Permission;
import org.mian.gitnex.util.TinyDB;
import androidx.annotation.NonNull;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;

View File

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

View File

@ -1,139 +0,0 @@
package org.mian.gitnex.actions;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Milestones;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class MilestoneActions {
static final private String TAG = "MilestoneActions : ";
public static void closeMilestone(final Context ctx, int milestoneId_) {
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 token = "token " + tinyDB.getString(loginUid + "-token");
Milestones milestoneStateJson = new Milestones("closed");
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.closeReopenMilestone(token, repoOwner, repoName, milestoneId_, milestoneStateJson);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()) {
Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate));
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
Toasty.info(ctx, ctx.getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
public static void openMilestone(final Context ctx, int milestoneId_) {
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 token = "token " + tinyDB.getString(loginUid + "-token");
Milestones milestoneStateJson = new Milestones("open");
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.closeReopenMilestone(token, repoOwner, repoName, milestoneId_, milestoneStateJson);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()) {
Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate));
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
Toasty.info(ctx, ctx.getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
}

View File

@ -1,59 +0,0 @@
package org.mian.gitnex.actions;
import android.content.Context;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.NotificationThread;
import java.io.IOException;
import java.util.Date;
import okhttp3.ResponseBody;
import retrofit2.Call;
/**
* Author opyale
*/
public class NotificationsActions {
public enum NotificationStatus {READ, UNREAD, PINNED}
private TinyDB tinyDB;
private Context context;
private String instanceUrl;
private String instanceToken;
public NotificationsActions(Context context) {
this.context = context;
this.tinyDB = new TinyDB(context);
String loginUid = tinyDB.getString("loginUid");
instanceUrl = tinyDB.getString("instanceUrl");
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
}
public void setNotificationStatus(NotificationThread notificationThread, NotificationStatus notificationStatus) throws IOException {
Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface()
.markNotificationThreadAsRead(instanceToken, notificationThread.getId(), notificationStatus.name());
if(!call.execute().isSuccessful()) {
throw new IllegalStateException();
}
}
public boolean setAllNotificationsRead(Date date) throws IOException {
Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface()
.markNotificationThreadsAsRead(instanceToken, AppUtil.getTimestampFromDate(context, date), true,
new String[]{"unread", "pinned"}, "read");
return call.execute().isSuccessful();
}
}

View File

@ -8,8 +8,8 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;

View File

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

View File

@ -1,29 +1,29 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
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 androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import 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.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.adapters.UserSearchAdapter; import org.mian.gitnex.adapters.UserSearchAdapter;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.models.UserSearch; import org.mian.gitnex.models.UserSearch;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import java.util.List; import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -33,7 +33,6 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private TextView addCollaboratorSearch; private TextView addCollaboratorSearch;
private TextView noData; private TextView noData;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
@ -47,13 +46,9 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -66,33 +61,29 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
mProgressBar = findViewById(R.id.progress_bar); mProgressBar = findViewById(R.id.progress_bar);
noData = findViewById(R.id.noData); noData = findViewById(R.id.noData);
addCollaboratorSearch.requestFocus();
assert imm != null;
imm.showSoftInput(addCollaboratorSearch, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
addCollaboratorSearch.setOnEditorActionListener((v, actionId, event) -> { addCollaboratorSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
if (actionId == EditorInfo.IME_ACTION_SEND) { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(!addCollaboratorSearch.getText().toString().equals("")) { if (actionId == EditorInfo.IME_ACTION_SEND) {
loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), loginUid); if(!addCollaboratorSearch.getText().toString().equals("")) {
loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), getApplicationContext(), loginUid);
}
} }
return false;
} }
return false;
}); });
} }
public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, String loginUid) { public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, final Context context, String loginUid) {
Call<UserSearch> call = RetrofitClient Call<UserSearch> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getUserBySearch(Authorization.returnAuthentication(ctx, loginUid, token), searchKeyword, 10); .getUserBySearch(Authorization.returnAuthentication(getApplicationContext(), loginUid, token), searchKeyword, 10);
call.enqueue(new Callback<UserSearch>() { call.enqueue(new Callback<UserSearch>() {
@ -101,7 +92,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
if (response.isSuccessful()) { if (response.isSuccessful()) {
assert response.body() != null; assert response.body() != null;
getUsersList(response.body().getData(), ctx); getUsersList(response.body().getData(), context);
} else { } else {
Log.i("onResponse", String.valueOf(response.code())); Log.i("onResponse", String.valueOf(response.code()));
} }
@ -121,7 +112,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
UserSearchAdapter adapter = new UserSearchAdapter(dataList, context); UserSearchAdapter adapter = new UserSearchAdapter(dataList, context);
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx)); mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL); DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
@ -141,7 +132,12 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> finish(); onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
} }

View File

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

View File

@ -1,23 +1,23 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.MultiSelectDialog; import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.MultiSelectModel; import org.mian.gitnex.models.MultiSelectModel;
import org.mian.gitnex.models.UpdateIssueAssignees; import org.mian.gitnex.models.UpdateIssueAssignees;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import retrofit2.Call; import retrofit2.Call;
@ -34,7 +34,6 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
private Boolean assigneesFlag = false; private Boolean assigneesFlag = false;
private MultiSelectDialog multiSelectDialogAssignees; private MultiSelectDialog multiSelectDialogAssignees;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -45,12 +44,11 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE); //supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT)); getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -66,12 +64,12 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) { private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -94,9 +92,9 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
// get current issue assignees // get current issue assignees
Call<Issues> callSingleIssueAssignees = RetrofitClient Call<Issues> callSingleIssueAssignees = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); .getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueAssignees.enqueue(new Callback<Issues>() { callSingleIssueAssignees.enqueue(new Callback<Issues>() {
@ -139,11 +137,11 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
.multiSelectList(listOfCollaborators) .multiSelectList(listOfCollaborators)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() { .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override @Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) { public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
Log.i("selectedNames", String.valueOf(selectedNames)); Log.i("selectedNames", String.valueOf(selectedNames));
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames); updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
tinyDb.putBoolean("singleIssueUpdate", true); tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity(); CloseActivity();
} }
@ -167,9 +165,9 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
.multiSelectList(listOfCollaborators) .multiSelectList(listOfCollaborators)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() { .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override @Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) { public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames); updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
tinyDb.putBoolean("singleIssueUpdate", true); tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity(); CloseActivity();
@ -217,7 +215,7 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
} }
else { else {
Toasty.info(ctx, getString(R.string.genericError)); Toasty.info(getApplicationContext(), getString(R.string.genericError));
} }
} }
@ -243,9 +241,9 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
Call<JsonElement> call3; Call<JsonElement> call3;
call3 = RetrofitClient call3 = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.patchIssueAssignees(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson); .patchIssueAssignees(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson);
call3.enqueue(new Callback<JsonElement>() { call3.enqueue(new Callback<JsonElement>() {
@ -277,7 +275,7 @@ public class AddRemoveAssigneesActivity extends BaseActivity {
} }
else { else {
Toasty.info(ctx, getString(R.string.genericError)); Toasty.info(getApplicationContext(), getString(R.string.genericError));
} }

View File

@ -1,25 +1,25 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.MultiSelectDialog; import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Labels; import org.mian.gitnex.models.Labels;
import org.mian.gitnex.models.MultiSelectModel; import org.mian.gitnex.models.MultiSelectModel;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -32,7 +32,6 @@ public class AddRemoveLabelsActivity extends BaseActivity {
private Boolean labelsFlag = false; private Boolean labelsFlag = false;
private MultiSelectDialog multiSelectDialogLabels; private MultiSelectDialog multiSelectDialogLabels;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -41,14 +40,12 @@ public class AddRemoveLabelsActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE); //supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT)); getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -64,12 +61,12 @@ public class AddRemoveLabelsActivity extends BaseActivity {
private void getLabels(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) { private void getLabels(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<List<Labels>> call = RetrofitClient Call<List<Labels>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getlabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); .getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Labels>>() { call.enqueue(new Callback<List<Labels>>() {
@ -92,9 +89,9 @@ public class AddRemoveLabelsActivity extends BaseActivity {
// get current issue labels // get current issue labels
Call<List<Labels>> callSingleIssueLabels = RetrofitClient Call<List<Labels>> callSingleIssueLabels = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); .getIssueLabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueLabels.enqueue(new Callback<List<Labels>>() { callSingleIssueLabels.enqueue(new Callback<List<Labels>>() {
@ -128,7 +125,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
.multiSelectList(listOfLabels) .multiSelectList(listOfLabels)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() { .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override @Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) { public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
String labelIds = selectedIds.toString(); String labelIds = selectedIds.toString();
int[] integers; int[] integers;
@ -145,7 +142,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
integers = new int[0]; integers = new int[0];
} }
updateIssueLabels(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid); updateIssueLabels(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
tinyDb.putBoolean("singleIssueUpdate", true); tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity(); CloseActivity();
} }
@ -169,7 +166,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
.multiSelectList(listOfLabels) .multiSelectList(listOfLabels)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() { .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override @Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) { public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
String labelIds = selectedIds.toString(); String labelIds = selectedIds.toString();
int[] integers; int[] integers;
@ -186,7 +183,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
integers = new int[0]; integers = new int[0];
} }
updateIssueLabels(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid); updateIssueLabels(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
tinyDb.putBoolean("singleIssueUpdate", true); tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity(); CloseActivity();
@ -234,7 +231,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
} }
else { else {
Toasty.info(ctx, getString(R.string.genericError)); Toasty.info(getApplicationContext(), getString(R.string.genericError));
} }
} }
@ -254,9 +251,9 @@ public class AddRemoveLabelsActivity extends BaseActivity {
Labels patchIssueLabels = new Labels(issueLabels); Labels patchIssueLabels = new Labels(issueLabels);
Call<JsonElement> call = RetrofitClient Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.updateIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels); .updateIssueLabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels);
call.enqueue(new Callback<JsonElement>() { call.enqueue(new Callback<JsonElement>() {
@ -288,7 +285,7 @@ public class AddRemoveLabelsActivity extends BaseActivity {
} }
else { else {
Toasty.info(ctx, getString(R.string.genericError)); Toasty.info(getApplicationContext(), getString(R.string.genericError));
} }

View File

@ -1,5 +1,13 @@
package org.mian.gitnex.activities; 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.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -11,30 +19,25 @@ import android.view.View;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; 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.R;
import org.mian.gitnex.adapters.AdminGetUsersAdapter; import org.mian.gitnex.adapters.AdminGetUsersAdapter;
import org.mian.gitnex.fragments.BottomSheetAdminUsersFragment; import org.mian.gitnex.fragments.AdminUsersBottomSheetFragment;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB; 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 org.mian.gitnex.viewmodels.AdminGetUsersViewModel;
import java.util.List;
import java.util.Objects;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAdminUsersFragment.BottomSheetListener { public class AdminGetUsersActivity extends BaseActivity implements AdminUsersBottomSheetFragment.BottomSheetListener {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private AdminGetUsersAdapter adapter; private AdminGetUsersAdapter adapter;
private RecyclerView mRecyclerView; private RecyclerView mRecyclerView;
private TextView noDataUsers; private TextView noDataUsers;
@ -49,9 +52,8 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -69,43 +71,50 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx)); mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL); DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> { 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.setRefreshing(false); fetchDataAsync(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken));
AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
}, 500));
fetchDataAsync(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
} }
private void fetchDataAsync(Context ctx, String instanceUrl, String instanceToken) { private void fetchDataAsync(Context ctx, String instanceUrl, String instanceToken) {
AdminGetUsersViewModel usersModel = new ViewModelProvider(this).get(AdminGetUsersViewModel.class); AdminGetUsersViewModel usersModel = ViewModelProviders.of(this).get(AdminGetUsersViewModel.class);
usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, usersListMain -> { usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
@Override
adapter = new AdminGetUsersAdapter(ctx, usersListMain); public void onChanged(@Nullable List<UserInfo> usersListMain) {
if(adapter.getItemCount() > 0) { adapter = new AdminGetUsersAdapter(getApplicationContext(), usersListMain);
mRecyclerView.setVisibility(View.VISIBLE); if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter); mRecyclerView.setVisibility(View.VISIBLE);
noDataUsers.setVisibility(View.GONE); mRecyclerView.setAdapter(adapter);
searchFilter = true; noDataUsers.setVisibility(View.GONE);
searchFilter = true;
}
else {
//adapter.notifyDataSetChanged();
//mRecyclerView.setAdapter(adapter);
mRecyclerView.setVisibility(View.GONE);
noDataUsers.setVisibility(View.VISIBLE);
}
} }
else {
//adapter.notifyDataSetChanged();
//mRecyclerView.setAdapter(adapter);
mRecyclerView.setVisibility(View.GONE);
noDataUsers.setVisibility(View.VISIBLE);
}
}); });
} }
@ -116,36 +125,37 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
final MenuInflater inflater = getMenuInflater(); final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu); inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
new Handler().postDelayed(() -> { new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if(searchFilter) {
if(searchFilter) { boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getApplicationContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); inflater.inflate(R.menu.search_menu, menu);
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);
MenuItem searchItem = menu.findItem(R.id.action_search); if(!connToInternet) {
SearchView searchView = (SearchView) searchItem.getActionView(); return;
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); }, 500);
return true; return true;
@ -161,7 +171,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
finish(); finish();
return true; return true;
case R.id.genericMenu: case R.id.genericMenu:
BottomSheetAdminUsersFragment bottomSheet = new BottomSheetAdminUsersFragment(); AdminUsersBottomSheetFragment bottomSheet = new AdminUsersBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet");
return true; return true;
default: default:
@ -182,7 +192,12 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> finish(); onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
} }
} }

View File

@ -1,143 +1,68 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; 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 org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FontsOverride; import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.notifications.NotificationsMaster;
/** /**
* Author M M Arif * 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 { public abstract class BaseActivity extends AppCompatActivity {
private Context appCtx; @Override
public void onCreate(Bundle savedInstanceState) {
@Override final TinyDB tinyDb = new TinyDB(getApplicationContext());
public void onCreate(Bundle savedInstanceState) {
appCtx = getApplicationContext(); if(tinyDb.getInt("themeId") == 1) {
final TinyDB tinyDb = new TinyDB(appCtx); setTheme(R.style.AppThemeLight);
}
switch(tinyDb.getInt("themeId")) { else {
setTheme(R.style.AppTheme);
case 1:
setTheme(R.style.AppThemeLight);
break;
case 2:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
setTheme(R.style.AppTheme);
}
else {
setTheme(R.style.AppThemeLight);
}
break;
default:
setTheme(R.style.AppTheme);
break;
}
String appLocale = tinyDb.getString("locale");
AppUtil.setAppLocale(getResources(), appLocale);
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;
}
if(tinyDb.getInt("pollingDelayMinutes") == 0) {
tinyDb.putInt("pollingDelayMinutes", 15);
} }
NotificationsMaster.hireWorker(appCtx); super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId());
if(tinyDb.getInt("customFontId") == 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");
}
else if (tinyDb.getInt("customFontId") == 1) {
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");
}
else if (tinyDb.getInt("customFontId") == 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");
}
else {
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");
// enabling counter badges by default
if(tinyDb.getString("enableCounterBadgesInit").isEmpty()) {
tinyDb.putBoolean("enableCounterBadges", true);
tinyDb.putString("enableCounterBadgesInit", "yes");
} }
// enable crash reports by default }
if(tinyDb.getString("crashReportingEnabledInit").isEmpty()) {
tinyDb.putBoolean("crashReportingEnabled", true);
tinyDb.putString("crashReportingEnabledInit", "yes");
}
// default cache setter protected abstract int getLayoutResourceId();
if(tinyDb.getString("cacheSizeStr").isEmpty()) {
tinyDb.putString("cacheSizeStr", getResources().getString(R.string.cacheSizeDataSelectionSelectedText));
}
if(tinyDb.getString("cacheSizeImagesStr").isEmpty()) {
tinyDb.putString("cacheSizeImagesStr", getResources().getString(R.string.cacheSizeImagesSelectionSelectedText));
}
// enable comment drafts by default
if(tinyDb.getString("draftsCommentsDeletionEnabledInit").isEmpty()) {
tinyDb.putBoolean("draftsCommentsDeletionEnabled", true);
tinyDb.putString("draftsCommentsDeletionEnabledInit", "yes");
}
if(!tinyDb.getString("instanceUrlWithProtocol").endsWith("/")) {
tinyDb.putString("instanceUrlWithProtocol", tinyDb.getString("instanceUrlWithProtocol") + "/");
}
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);
}
}
protected abstract int getLayoutResourceId();
} }

View File

@ -1,286 +0,0 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
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.Toolbar;
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.CommitsAdapter;
import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Commits;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class CommitsActivity extends BaseActivity {
final Context ctx = this;
private Context appCtx;
private View.OnClickListener onClickListener;
private TextView noData;
private ProgressBar progressBar;
private String TAG = "CommitsActivity";
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private int pageSize = 1;
private RecyclerView recyclerView;
private List<Commits> commitsList;
private CommitsAdapter adapter;
private ApiInterface api;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_commits;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String 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 branchName = getIntent().getStringExtra("branchName");
TextView toolbar_title = findViewById(R.id.toolbar_title);
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
toolbar_title.setText(branchName);
ImageView closeActivity = findViewById(R.id.close);
noData = findViewById(R.id.noDataCommits);
progressBar = findViewById(R.id.progress_bar);
SwipeRefreshLayout swipeRefresh = findViewById(R.id.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 = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
recyclerView = findViewById(R.id.recyclerView);
commitsList = new ArrayList<>();
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setRefreshing(false);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit);
adapter.notifyDataChanged();
}, 200));
adapter = new CommitsAdapter(ctx, commitsList);
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
if(commitsList.size() == resultLimit || pageSize == resultLimit) {
int page = (commitsList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, branchName, resultLimit);
}
}));
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
recyclerView.setAdapter(adapter);
api = AppApiService.createService(ApiInterface.class, instanceUrl, ctx);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit);
}
private void loadInitial(String token, String repoOwner, String repoName, String branchName, int resultLimit) {
Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, 1, branchName, resultLimit);
call.enqueue(new Callback<List<Commits>>() {
@Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
commitsList.clear();
commitsList.addAll(response.body());
adapter.notifyDataChanged();
noData.setVisibility(View.GONE);
}
else {
commitsList.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<Commits>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadMore(String token, String repoOwner, String repoName, final int page, String branchName, int resultLimit) {
//add loading progress view
commitsList.add(new Commits("load"));
adapter.notifyItemInserted((commitsList.size() - 1));
Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, page, branchName, resultLimit);
call.enqueue(new Callback<List<Commits>>() {
@Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
if(response.isSuccessful()) {
//remove loading view
commitsList.remove(commitsList.size() - 1);
List<Commits> result = response.body();
assert result != null;
if(result.size() > 0) {
pageSize = result.size();
commitsList.addAll(result);
}
else {
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) {
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);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter(newText);
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
private void filter(String text) {
List<Commits> arr = new ArrayList<>();
for(Commits d : commitsList) {
if(d.getCommit().getMessage().toLowerCase().contains(text) || d.getSha().toLowerCase().contains(text)) {
arr.add(d);
}
}
adapter.updateList(arr);
}
private void initCloseListener() {
onClickListener = view -> {
getIntent().removeExtra("branchName");
finish();
};
}
}

View File

@ -1,5 +1,9 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.content.Context; import android.content.Context;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
@ -7,7 +11,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.DatePicker; import android.widget.DatePicker;
@ -15,7 +18,6 @@ import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.hendraanggrian.appcompat.socialview.Mention; import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter; import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
@ -23,25 +25,20 @@ import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.MultiSelectDialog; import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.Labels; import org.mian.gitnex.models.Labels;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.models.MultiSelectModel; import org.mian.gitnex.models.MultiSelectModel;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -63,8 +60,6 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private boolean assigneesFlag; private boolean assigneesFlag;
private boolean labelsFlag; private boolean labelsFlag;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
List<Milestones> milestonesList = new ArrayList<>(); List<Milestones> milestonesList = new ArrayList<>();
ArrayList<MultiSelectModel> listOfAssignees = new ArrayList<>(); ArrayList<MultiSelectModel> listOfAssignees = new ArrayList<>();
@ -78,15 +73,11 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String loginFullName = tinyDb.getString("userFullname"); final String loginFullName = tinyDb.getString("userFullname");
@ -96,11 +87,6 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
final String repoName = parts[1]; final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
// if gitea is 1.12 or higher use the new limit
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
assigneesList = findViewById(R.id.newIssueAssigneesList); assigneesList = findViewById(R.id.newIssueAssigneesList);
newIssueLabels = findViewById(R.id.newIssueLabels); newIssueLabels = findViewById(R.id.newIssueLabels);
@ -110,10 +96,6 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
newIssueDescription = findViewById(R.id.newIssueDescription); newIssueDescription = findViewById(R.id.newIssueDescription);
labelsIdHolder = findViewById(R.id.labelsIdHolder); labelsIdHolder = findViewById(R.id.labelsIdHolder);
newIssueTitle.requestFocus();
assert imm != null;
imm.showSoftInput(newIssueTitle, InputMethodManager.SHOW_IMPLICIT);
defaultMentionAdapter = new MentionArrayAdapter<>(this); defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList(); loadCollaboratorsList();
@ -128,7 +110,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner); newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner);
newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP); newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit); getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid); getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName); getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName);
@ -153,8 +135,8 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private void processNewIssue() { private void processNewIssue() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -175,21 +157,21 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (newIssueTitleForm.equals("")) { if (newIssueTitleForm.equals("")) {
Toasty.info(ctx, getString(R.string.issueTitleEmpty)); Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty));
return; return;
} }
/*if (newIssueDescriptionForm.equals("")) { /*if (newIssueDescriptionForm.equals("")) {
Toasty.info(ctx, getString(R.string.issueDescriptionEmpty)); Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty));
return; return;
}*/ }*/
@ -228,7 +210,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
public void loadCollaboratorsList() { public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -239,9 +221,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
final String repoName = parts[1]; final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -283,9 +265,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
Call<JsonElement> call3; Call<JsonElement> call3;
call3 = RetrofitClient call3 = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, createNewIssueJson); .createNewIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createNewIssueJson);
call3.enqueue(new Callback<JsonElement>() { call3.enqueue(new Callback<JsonElement>() {
@ -296,10 +278,10 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
if(response2.code() == 201) { if(response2.code() == 201) {
//Log.i("isSuccessful1", String.valueOf(response2.body())); //Log.i("isSuccessful1", String.valueOf(response2.body()));
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
Toasty.info(ctx, getString(R.string.issueCreated)); Toasty.info(getApplicationContext(), getString(R.string.issueCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -317,7 +299,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
} }
else { else {
Toasty.info(ctx, getString(R.string.issueCreatedError)); Toasty.info(getApplicationContext(), getString(R.string.issueCreatedError));
enableProcessButton(); enableProcessButton();
//Log.i("isSuccessful2", String.valueOf(response2.body())); //Log.i("isSuccessful2", String.valueOf(response2.body()));
@ -343,13 +325,13 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
}; };
} }
private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) { private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
String msState = "open"; String msState = "open";
Call<List<Milestones>> call = RetrofitClient Call<List<Milestones>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState); .getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState);
call.enqueue(new Callback<List<Milestones>>() { call.enqueue(new Callback<List<Milestones>>() {
@ -378,7 +360,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
} }
} }
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreateIssueActivity.this, ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, milestonesList); R.layout.spinner_item, milestonesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
@ -401,9 +383,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, String loginFullName) { private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, String loginFullName) {
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
listOfAssignees.add(new MultiSelectModel(-1, loginFullName)); listOfAssignees.add(new MultiSelectModel(-1, loginFullName));
@ -444,7 +426,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
.multiSelectList(listOfAssignees) .multiSelectList(listOfAssignees)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() { .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override @Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) { public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
assigneesList.setText(dataString); assigneesList.setText(dataString);
@ -473,9 +455,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
Call<List<Labels>> call = RetrofitClient Call<List<Labels>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getlabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); .getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Labels>>() { call.enqueue(new Callback<List<Labels>>() {
@ -507,7 +489,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
.multiSelectList(listOfLabels) .multiSelectList(listOfLabels)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() { .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override @Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) { public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
newIssueLabels.setText(dataString.trim()); newIssueLabels.setText(dataString.trim());
labelsIdHolder.setText(selectedIds.toString()); labelsIdHolder.setText(selectedIds.toString());
@ -541,7 +523,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog"); multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog");
} }
else { else {
Toasty.info(ctx, getResources().getString(R.string.noAssigneesFound)); Toasty.info(getApplicationContext(), getResources().getString(R.string.noAssigneesFound));
} }
} }
else if (v == newIssueLabels) { else if (v == newIssueLabels) {
@ -549,7 +531,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels"); multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels");
} }
else { else {
Toasty.info(ctx, getResources().getString(R.string.noLabelsFound)); Toasty.info(getApplicationContext(), getResources().getString(R.string.noLabelsFound));
} }
} }
else if (v == newIssueDueDate) { else if (v == newIssueDueDate) {

View File

@ -1,34 +1,33 @@
package org.mian.gitnex.activities; 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.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.pes.androidmaterialcolorpickerdialog.ColorPicker; import com.pes.androidmaterialcolorpickerdialog.ColorPicker;
import com.pes.androidmaterialcolorpickerdialog.ColorPickerCallback; import com.pes.androidmaterialcolorpickerdialog.ColorPickerCallback;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.CreateLabel; import org.mian.gitnex.models.CreateLabel;
import org.mian.gitnex.models.Labels; 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.LabelsViewModel;
import java.util.Objects; import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -41,7 +40,6 @@ public class CreateLabelActivity extends BaseActivity {
private EditText labelName; private EditText labelName;
private Button createLabelButton; private Button createLabelButton;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -50,13 +48,9 @@ public class CreateLabelActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -67,23 +61,19 @@ public class CreateLabelActivity extends BaseActivity {
if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("delete")) { 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(instanceUrl, instanceToken, repoOwner, repoName, Integer.valueOf(Objects.requireNonNull(getIntent().getStringExtra("labelId"))), loginUid);
finish(); finish();
return; return;
} }
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
colorPicker = findViewById(R.id.colorPicker); colorPicker = findViewById(R.id.colorPicker);
labelName = findViewById(R.id.labelName); labelName = findViewById(R.id.labelName);
createLabelButton = findViewById(R.id.createLabelButton); createLabelButton = findViewById(R.id.createLabelButton);
labelName.requestFocus();
assert imm != null;
imm.showSoftInput(labelName, InputMethodManager.SHOW_IMPLICIT);
final ColorPicker cp = new ColorPicker(CreateLabelActivity.this, 235, 113, 33); final ColorPicker cp = new ColorPicker(CreateLabelActivity.this, 235, 113, 33);
initCloseListener(); initCloseListener();
@ -153,8 +143,8 @@ public class CreateLabelActivity extends BaseActivity {
private void processUpdateLabel() { private void processUpdateLabel() {
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
@ -176,21 +166,21 @@ public class CreateLabelActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(updateLabelName.equals("")) { if(updateLabelName.equals("")) {
Toasty.info(ctx, getString(R.string.labelEmptyError)); Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError));
return; return;
} }
if(!appUtil.checkStrings(updateLabelName)) { if(!appUtil.checkStrings(updateLabelName)) {
Toasty.info(ctx, getString(R.string.labelNameError)); Toasty.info(getApplicationContext(), getString(R.string.labelNameError));
return; return;
} }
@ -202,9 +192,9 @@ public class CreateLabelActivity extends BaseActivity {
private void processCreateLabel() { private void processCreateLabel() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -216,7 +206,7 @@ public class CreateLabelActivity extends BaseActivity {
String newLabelName = labelName.getText().toString(); String newLabelName = labelName.getText().toString();
String newLabelColor; String newLabelColor;
if(tinyDb.getString("labelColor").isEmpty()) { if(tinyDb.getString("labelColor").isEmpty()) {
newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(ctx, R.color.releasePre))); newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(getApplicationContext(), R.color.releasePre)));
} }
else { else {
newLabelColor = tinyDb.getString("labelColor"); newLabelColor = tinyDb.getString("labelColor");
@ -224,21 +214,21 @@ public class CreateLabelActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newLabelName.equals("")) { if(newLabelName.equals("")) {
Toasty.info(ctx, getString(R.string.labelEmptyError)); Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError));
return; return;
} }
if(!appUtil.checkStrings(newLabelName)) { if(!appUtil.checkStrings(newLabelName)) {
Toasty.info(ctx, getString(R.string.labelNameError)); Toasty.info(getApplicationContext(), getString(R.string.labelNameError));
return; return;
} }
@ -251,14 +241,14 @@ public class CreateLabelActivity extends BaseActivity {
private void createNewLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String newLabelName, String newLabelColor, String loginUid) { private void createNewLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String newLabelName, String newLabelColor, String loginUid) {
CreateLabel createLabelFunc = new CreateLabel(newLabelName, newLabelColor); CreateLabel createLabelFunc = new CreateLabel(newLabelName, newLabelColor);
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<CreateLabel> call; Call<CreateLabel> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, createLabelFunc); .createLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createLabelFunc);
call.enqueue(new Callback<CreateLabel>() { call.enqueue(new Callback<CreateLabel>() {
@ -267,7 +257,7 @@ public class CreateLabelActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.info(ctx, getString(R.string.labelCreated)); Toasty.info(getApplicationContext(), getString(R.string.labelCreated));
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putBoolean("labelsRefresh", true); tinyDb.putBoolean("labelsRefresh", true);
finish(); finish();
@ -286,7 +276,7 @@ public class CreateLabelActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
Toasty.info(ctx, getString(R.string.labelGeneralError)); Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
} }
@ -305,14 +295,14 @@ public class CreateLabelActivity extends BaseActivity {
private void patchLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId, String loginUid) { private void patchLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId, String loginUid) {
CreateLabel createLabelFunc = new CreateLabel(updateLabelName, updateLabelColor); CreateLabel createLabelFunc = new CreateLabel(updateLabelName, updateLabelColor);
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<CreateLabel> call; Call<CreateLabel> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.patchLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc); .patchLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc);
call.enqueue(new Callback<CreateLabel>() { call.enqueue(new Callback<CreateLabel>() {
@ -322,7 +312,7 @@ public class CreateLabelActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 200) { if(response.code() == 200) {
Toasty.info(ctx, getString(R.string.labelUpdated)); Toasty.info(getApplicationContext(), getString(R.string.labelUpdated));
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putBoolean("labelsRefresh", true); tinyDb.putBoolean("labelsRefresh", true);
tinyDb.putString("labelColorDefault", ""); tinyDb.putString("labelColorDefault", "");
@ -348,7 +338,7 @@ public class CreateLabelActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putString("labelColorDefault", ""); tinyDb.putString("labelColorDefault", "");
Toasty.info(ctx, getString(R.string.labelGeneralError)); Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
} }
@ -383,9 +373,9 @@ public class CreateLabelActivity extends BaseActivity {
Call<Labels> call; Call<Labels> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.deleteLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, labelId); .deleteLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId);
call.enqueue(new Callback<Labels>() { call.enqueue(new Callback<Labels>() {
@ -395,8 +385,8 @@ public class CreateLabelActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 204) { if(response.code() == 204) {
Toasty.info(ctx, getString(R.string.labelDeleteText)); Toasty.info(getApplicationContext(), getString(R.string.labelDeleteText));
LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, ctx); LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, getApplicationContext());
getIntent().removeExtra("labelAction"); getIntent().removeExtra("labelAction");
getIntent().removeExtra("labelId"); getIntent().removeExtra("labelId");
@ -412,7 +402,7 @@ public class CreateLabelActivity extends BaseActivity {
} }
else { else {
Toasty.info(ctx, getString(R.string.labelDeleteErrorText)); Toasty.info(getApplicationContext(), getString(R.string.labelDeleteErrorText));
} }
@ -446,4 +436,4 @@ public class CreateLabelActivity extends BaseActivity {
} }
} }

View File

@ -1,26 +1,25 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.util.Patterns; import android.util.Patterns;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.NonNull;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import retrofit2.Call; import org.mian.gitnex.util.AppUtil;
import retrofit2.Callback; import org.mian.gitnex.util.TinyDB;
/** /**
* Author M M Arif * Author M M Arif
@ -35,7 +34,6 @@ public class CreateNewUserActivity extends BaseActivity {
private EditText userPassword; private EditText userPassword;
private Button createUserButton; private Button createUserButton;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -46,11 +44,8 @@ public class CreateNewUserActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
createUserButton = findViewById(R.id.createUserButton); createUserButton = findViewById(R.id.createUserButton);
@ -59,10 +54,6 @@ public class CreateNewUserActivity extends BaseActivity {
userEmail = findViewById(R.id.userEmail); userEmail = findViewById(R.id.userEmail);
userPassword = findViewById(R.id.userPassword); userPassword = findViewById(R.id.userPassword);
fullName.requestFocus();
assert imm != null;
imm.showSoftInput(fullName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -80,9 +71,9 @@ public class CreateNewUserActivity extends BaseActivity {
private void processCreateNewUser() { private void processCreateNewUser() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -94,41 +85,41 @@ public class CreateNewUserActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) { if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) {
Toasty.info(ctx, getString(R.string.emptyFields)); Toasty.info(getApplicationContext(), getString(R.string.emptyFields));
return; return;
} }
if(!appUtil.checkStrings(newFullName)) { if(!appUtil.checkStrings(newFullName)) {
Toasty.info(ctx, getString(R.string.userInvalidFullName)); Toasty.info(getApplicationContext(), getString(R.string.userInvalidFullName));
return; return;
} }
if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) { if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) {
Toasty.info(ctx, getString(R.string.userInvalidUserName)); Toasty.info(getApplicationContext(), getString(R.string.userInvalidUserName));
return; return;
} }
if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
Toasty.info(ctx, getString(R.string.userInvalidEmail)); Toasty.info(getApplicationContext(), getString(R.string.userInvalidEmail));
return; return;
} }
disableProcessButton(); disableProcessButton();
createNewUser(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newFullName, newUserName, newUserEmail, newUserPassword); createNewUser(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newFullName, newUserName, newUserEmail, newUserPassword);
} }
@ -139,7 +130,7 @@ public class CreateNewUserActivity extends BaseActivity {
Call<UserInfo> call; Call<UserInfo> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewUser(instanceToken, createUser); .createNewUser(instanceToken, createUser);
@ -150,7 +141,7 @@ public class CreateNewUserActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.info(ctx, getString(R.string.userCreatedText)); Toasty.info(getApplicationContext(), getString(R.string.userCreatedText));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -185,7 +176,7 @@ public class CreateNewUserActivity extends BaseActivity {
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.genericError)); Toasty.info(getApplicationContext(), getString(R.string.genericError));
} }

View File

@ -1,12 +1,14 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import android.content.Context; import android.content.Context;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
@ -14,20 +16,17 @@ import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner; import android.widget.Spinner;
import androidx.annotation.NonNull;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.Releases; 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.ArrayList;
import java.util.List; import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -45,7 +44,6 @@ public class CreateReleaseActivity extends BaseActivity {
private CheckBox releaseDraft; private CheckBox releaseDraft;
private Button createNewRelease; private Button createNewRelease;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
List<Branches> branchesList = new ArrayList<>(); List<Branches> branchesList = new ArrayList<>();
@ -58,13 +56,10 @@ public class CreateReleaseActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -80,16 +75,12 @@ public class CreateReleaseActivity extends BaseActivity {
releaseType = findViewById(R.id.releaseType); releaseType = findViewById(R.id.releaseType);
releaseDraft = findViewById(R.id.releaseDraft); releaseDraft = findViewById(R.id.releaseDraft);
releaseTagName.requestFocus();
assert imm != null;
imm.showSoftInput(releaseTagName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
releaseBranch = findViewById(R.id.releaseBranch); releaseBranch = findViewById(R.id.releaseBranch);
releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP); releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getBranches(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); getBranches(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
@ -125,9 +116,9 @@ public class CreateReleaseActivity extends BaseActivity {
private void processNewRelease() { private void processNewRelease() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -145,27 +136,27 @@ public class CreateReleaseActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newReleaseTagName.equals("")) { if(newReleaseTagName.equals("")) {
Toasty.info(ctx, getString(R.string.tagNameErrorEmpty)); Toasty.info(getApplicationContext(), getString(R.string.tagNameErrorEmpty));
return; return;
} }
if(newReleaseTitle.equals("")) { if(newReleaseTitle.equals("")) {
Toasty.info(ctx, getString(R.string.titleErrorEmpty)); Toasty.info(getApplicationContext(), getString(R.string.titleErrorEmpty));
return; return;
} }
disableProcessButton(); disableProcessButton();
createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, newReleaseBranch, newReleaseType, newReleaseDraft); createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, newReleaseBranch, newReleaseType, newReleaseDraft);
} }
@ -176,7 +167,7 @@ public class CreateReleaseActivity extends BaseActivity {
Call<Releases> call; Call<Releases> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewRelease(token, repoOwner, repoName, createReleaseJson); .createNewRelease(token, repoOwner, repoName, createReleaseJson);
@ -187,9 +178,9 @@ public class CreateReleaseActivity extends BaseActivity {
if (response.code() == 201) { if (response.code() == 201) {
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putBoolean("updateReleases", true); tinyDb.putBoolean("updateReleases", true);
Toasty.info(ctx, getString(R.string.releaseCreatedText)); Toasty.info(getApplicationContext(), getString(R.string.releaseCreatedText));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -236,7 +227,7 @@ public class CreateReleaseActivity extends BaseActivity {
private void getBranches(String instanceUrl, String instanceToken, final String repoOwner, final String repoName) { private void getBranches(String instanceUrl, String instanceToken, final String repoOwner, final String repoName) {
Call<List<Branches>> call = RetrofitClient Call<List<Branches>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getBranches(instanceToken, repoOwner, repoName); .getBranches(instanceToken, repoOwner, repoName);
@ -262,7 +253,7 @@ public class CreateReleaseActivity extends BaseActivity {
} }
} }
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateReleaseActivity.this, ArrayAdapter<Branches> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, branchesList); R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);

View File

@ -1,30 +1,29 @@
package org.mian.gitnex.activities; 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.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Teams; 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.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import retrofit2.Call; import android.util.Log;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -33,7 +32,6 @@ import retrofit2.Callback;
public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClickListener { public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClickListener {
final Context ctx = CreateTeamByOrgActivity.this; final Context ctx = CreateTeamByOrgActivity.this;
private Context appCtx;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TextView teamName; private TextView teamName;
private TextView teamDesc; private TextView teamDesc;
@ -74,13 +72,9 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
teamName = findViewById(R.id.teamName); teamName = findViewById(R.id.teamName);
@ -91,10 +85,6 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
teamAccessControlsArray = findViewById(R.id.teamAccessControlsArray); teamAccessControlsArray = findViewById(R.id.teamAccessControlsArray);
createTeamButton = findViewById(R.id.createTeamButton); createTeamButton = findViewById(R.id.createTeamButton);
teamName.requestFocus();
assert imm != null;
imm.showSoftInput(teamName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -250,13 +240,13 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
private void processCreateTeam() { private void processCreateTeam() {
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String orgName = tinyDb.getString("orgName");; final String orgName = tinyDb.getString("orgName");;
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
String newTeamName = teamName.getText().toString(); String newTeamName = teamName.getText().toString();
String newTeamDesc = teamDesc.getText().toString(); String newTeamDesc = teamDesc.getText().toString();
String newTeamPermission = teamPermission.getText().toString().toLowerCase(); String newTeamPermission = teamPermission.getText().toString().toLowerCase();
@ -264,21 +254,21 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (newTeamName.equals("")) { if (newTeamName.equals("")) {
Toasty.info(ctx, getString(R.string.teamNameEmpty)); Toasty.info(getApplicationContext(), getString(R.string.teamNameEmpty));
return; return;
} }
if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) { if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
Toasty.info(ctx, getString(R.string.teamNameError)); Toasty.info(getApplicationContext(), getString(R.string.teamNameError));
return; return;
} }
@ -286,12 +276,12 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(!newTeamDesc.equals("")) { if(!newTeamDesc.equals("")) {
if(!appUtil.checkStrings(newTeamDesc)) { if(!appUtil.checkStrings(newTeamDesc)) {
Toasty.info(ctx, getString(R.string.teamDescError)); Toasty.info(getApplicationContext(), getString(R.string.teamDescError));
return; return;
} }
if(newTeamDesc.length() > 100) { if(newTeamDesc.length() > 100) {
Toasty.info(ctx, getString(R.string.teamDescLimit)); Toasty.info(getApplicationContext(), getString(R.string.teamDescLimit));
return; return;
} }
@ -299,7 +289,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if (newTeamPermission.equals("")) { if (newTeamPermission.equals("")) {
Toasty.info(ctx, getString(R.string.teamPermissionEmpty)); Toasty.info(getApplicationContext(), getString(R.string.teamPermissionEmpty));
return; return;
} }
@ -321,9 +311,9 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
Call<Teams> call3; Call<Teams> call3;
call3 = RetrofitClient call3 = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createTeamsByOrg(Authorization.returnAuthentication(ctx, loginUid, instanceToken), orgName, createNewTeamJson); .createTeamsByOrg(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), orgName, createNewTeamJson);
call3.enqueue(new Callback<Teams>() { call3.enqueue(new Callback<Teams>() {
@ -333,10 +323,10 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(response2.isSuccessful()) { if(response2.isSuccessful()) {
if(response2.code() == 201) { if(response2.code() == 201) {
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putBoolean("resumeTeams", true); tinyDb.putBoolean("resumeTeams", true);
Toasty.info(ctx, getString(R.string.teamCreated)); Toasty.info(getApplicationContext(), getString(R.string.teamCreated));
finish(); finish();
} }
@ -344,7 +334,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
} }
else if(response2.code() == 404) { else if(response2.code() == 404) {
Toasty.info(ctx, getString(R.string.apiNotFound)); Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
} }
else if(response2.code() == 401) { else if(response2.code() == 401) {
@ -357,7 +347,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
} }
else { else {
Toasty.info(ctx, getString(R.string.teamCreatedError)); Toasty.info(getApplicationContext(), getString(R.string.teamCreatedError));
} }

View File

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

View File

@ -1,5 +1,9 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.content.Context; import android.content.Context;
@ -8,7 +12,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.DatePicker; import android.widget.DatePicker;
@ -16,7 +19,6 @@ import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.hendraanggrian.appcompat.socialview.Mention; import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter; import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
@ -24,24 +26,19 @@ import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -50,9 +47,7 @@ import retrofit2.Response;
public class EditIssueActivity extends BaseActivity implements View.OnClickListener { public class EditIssueActivity extends BaseActivity implements View.OnClickListener {
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private EditText editIssueTitle; private EditText editIssueTitle;
private SocialAutoCompleteTextView editIssueDescription; private SocialAutoCompleteTextView editIssueDescription;
@ -74,11 +69,8 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -96,15 +88,6 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
editIssueDescription = findViewById(R.id.editIssueDescription); editIssueDescription = findViewById(R.id.editIssueDescription);
editIssueDueDate = findViewById(R.id.editIssueDueDate); editIssueDueDate = findViewById(R.id.editIssueDueDate);
// if gitea is 1.12 or higher use the new limit
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
editIssueTitle.requestFocus();
assert imm != null;
imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT);
defaultMentionAdapter = new MentionArrayAdapter<>(this); defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList(); loadCollaboratorsList();
@ -121,7 +104,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
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))); toolbar_title.setText(getString(R.string.editPrNavHeader, String.valueOf(issueIndex)));
} }
else { else {
@ -130,14 +113,14 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
disableProcessButton(); disableProcessButton();
getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit); getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex);
} }
public void loadCollaboratorsList() { public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -148,9 +131,9 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
final String repoName = parts[1]; final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -196,8 +179,8 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
private void processEditIssue() { private void processEditIssue() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -217,21 +200,21 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (editIssueTitleForm.equals("")) { if (editIssueTitleForm.equals("")) {
Toasty.info(ctx, getString(R.string.issueTitleEmpty)); Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty));
return; return;
} }
/*if (editIssueDescriptionForm.equals("")) { /*if (editIssueDescriptionForm.equals("")) {
Toasty.info(ctx, getString(R.string.issueDescriptionEmpty)); Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty));
return; return;
}*/ }*/
@ -250,14 +233,14 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int editIssueMilestoneId) { private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int editIssueMilestoneId) {
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
CreateIssue issueData = new CreateIssue(title, description, dueDate, editIssueMilestoneId); CreateIssue issueData = new CreateIssue(title, description, dueDate, editIssueMilestoneId);
Call<JsonElement> call = RetrofitClient Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.patchIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData); .patchIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData);
call.enqueue(new Callback<JsonElement>() { call.enqueue(new Callback<JsonElement>() {
@ -266,11 +249,11 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if(response.code() == 201) { if(response.code() == 201) {
if(tinyDb.getString("issueType").equalsIgnoreCase("Pull")) { if(tinyDb.getString("issueType").equals("pr")) {
Toasty.info(ctx, getString(R.string.editPrSuccessMessage)); Toasty.info(getApplicationContext(), getString(R.string.editPrSuccessMessage));
} }
else { else {
Toasty.info(ctx, getString(R.string.editIssueSuccessMessage)); Toasty.info(getApplicationContext(), getString(R.string.editIssueSuccessMessage));
} }
tinyDb.putBoolean("issueEdited", true); tinyDb.putBoolean("issueEdited", true);
@ -290,7 +273,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.genericError)); Toasty.info(getApplicationContext(), getString(R.string.genericError));
} }
@ -336,12 +319,12 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex, int resultLimit) { private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex) {
Call<Issues> call = RetrofitClient Call<Issues> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); .getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
call.enqueue(new Callback<Issues>() { call.enqueue(new Callback<Issues>() {
@ -363,9 +346,9 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if(response.body().getId() > 0) { if(response.body().getId() > 0) {
Call<List<Milestones>> call_ = RetrofitClient Call<List<Milestones>> call_ = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState); .getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState);
final int finalMsId = msId; final int finalMsId = msId;
@ -398,7 +381,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
} }
ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(EditIssueActivity.this, ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, milestonesList); R.layout.spinner_item, milestonesList);
adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item);
@ -442,7 +425,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
else { else {
Toasty.info(ctx, getString(R.string.genericError)); Toasty.info(getApplicationContext(), getString(R.string.genericError));
} }

View File

@ -1,26 +1,26 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.apache.commons.io.FilenameUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.adapters.FilesDiffAdapter; import org.mian.gitnex.adapters.FilesDiffAdapter;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ParseDiff;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.FileDiffView; import org.mian.gitnex.models.FileDiffView;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
@ -32,150 +32,188 @@ import retrofit2.Callback;
public class FileDiffActivity extends BaseActivity { public class FileDiffActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TextView toolbarTitle; private TextView toolbar_title;
private ListView mListView; private RecyclerView mRecyclerView;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId(){
return R.layout.activity_file_diff;
}
return R.layout.activity_file_diff; @Override
} public void onCreate(Bundle savedInstanceState) {
@Override super.onCreate(savedInstanceState);
public void onCreate(Bundle savedInstanceState) { Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
super.onCreate(savedInstanceState); final TinyDB tinyDb = new TinyDB(getApplicationContext());
appCtx = 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 = findViewById(R.id.toolbar); ImageView closeActivity = findViewById(R.id.close);
setSupportActionBar(toolbar); toolbar_title = findViewById(R.id.toolbar_title);
mRecyclerView = findViewById(R.id.recyclerView);
mProgressBar = findViewById(R.id.progress_bar);
final TinyDB tinyDb = new TinyDB(appCtx); mRecyclerView.setHasFixedSize(true);
String repoFullName = tinyDb.getString("repoFullName"); mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
ImageView closeActivity = findViewById(R.id.close); toolbar_title.setText(R.string.processingText);
toolbarTitle = findViewById(R.id.toolbar_title); initCloseListener();
mListView = findViewById(R.id.listView); closeActivity.setOnClickListener(onClickListener);
mProgressBar = findViewById(R.id.progress_bar);
mListView.setDivider(null); mProgressBar.setVisibility(View.VISIBLE);
toolbarTitle.setText(R.string.processingText); String fileDiffName = tinyDb.getString("issueNumber")+".diff";
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
mProgressBar.setVisibility(View.VISIBLE); getFileContents(tinyDb.getString("instanceUrlWithProtocol"), repoOwner, repoName, fileDiffName);
String pullIndex = tinyDb.getString("issueNumber"); }
boolean apiCall = true; private void getFileContents(String instanceUrl, String owner, String repo, String filename) {
String instanceUrl = tinyDb.getString("instanceUrl");
// fallback for old gitea instances Call<ResponseBody> call = RetrofitClient
if(new Version(tinyDb.getString("giteaVersion")).less("1.13.0")) { .getInstance(instanceUrl, getApplicationContext())
apiCall = false; .getApiInterface()
instanceUrl = tinyDb.getString("instanceUrlWithProtocol"); .getFileDiffContents(owner, repo, filename);
}
getPullDiffContent(instanceUrl, repoOwner, repoName, pullIndex, instanceToken, apiCall); call.enqueue(new Callback<ResponseBody>() {
} @Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
private void getPullDiffContent(String instanceUrl, String owner, String repo, String pullIndex, String token, boolean apiCall) { if (response.code() == 200) {
Call<ResponseBody> call; try {
if(apiCall) { assert response.body() != null;
call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getPullDiffContent(token, owner, repo, pullIndex);
}
else {
call = RetrofitClient.getInstance(instanceUrl, ctx).getWebInterface().getPullDiffContent(owner, repo, pullIndex);
}
call.enqueue(new Callback<ResponseBody>() { AppUtil appUtil = new AppUtil();
List<FileDiffView> fileContentsArray = new ArrayList<>();
@Override String[] lines = response.body().string().split("diff");
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
if(response.code() == 200) { if(lines.length > 0) {
try { for (int i = 1; i < lines.length; i++) {
assert response.body() != null;
AppUtil appUtil = new AppUtil(); if(lines[i].contains("@@ -")) {
List<FileDiffView> fileContentsArray = ParseDiff.getFileDiffViewArray(response.body().string());
int filesCount = fileContentsArray.size(); String[] level2nd = lines[i].split("@@ -"); // main content part of single diff view
if(filesCount > 1) {
toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount)));
}
else {
toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount)));
}
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, fileContentsArray); String[] fileName_ = level2nd[0].split("\\+\\+\\+ b/"); // filename part
mListView.setAdapter(adapter); String fileNameFinal = fileName_[1];
mProgressBar.setVisibility(View.GONE); String[] fileContents_ = level2nd[1].split("@@"); // file info / content part
String fileInfoFinal = fileContents_[0];
String fileContentsFinal = (fileContents_[1]);
} if(level2nd.length > 2) {
catch(IOException e) { for (int j = 2; j < level2nd.length; j++) {
e.printStackTrace(); fileContentsFinal += (level2nd[j]);
} }
}
} String fileExtension = FilenameUtils.getExtension(fileNameFinal);
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)); String fileContentsFinalWithBlankLines = fileContentsFinal.replaceAll( ".*@@.*", "" );
String fileContentsFinalWithoutBlankLines = fileContentsFinal.replaceAll( ".*@@.*(\r?\n|\r)?", "" );
fileContentsFinalWithoutBlankLines = fileContentsFinalWithoutBlankLines.replaceAll( ".*\\ No newline at end of file.*(\r?\n|\r)?", "" );
} fileContentsArray.add(new FileDiffView(fileNameFinal, appUtil.imageExtension(fileExtension), fileInfoFinal, fileContentsFinalWithoutBlankLines));
else if(response.code() == 403) { }
else {
Toasty.info(ctx, ctx.getString(R.string.authorizeError)); String[] getFileName = lines[i].split("--git a/");
} String[] getFileName_ = getFileName[1].split("b/");
else if(response.code() == 404) { String getFileNameFinal = getFileName_[0].trim();
Toasty.info(ctx, ctx.getString(R.string.apiNotFound)); 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);
} String fileExtension = FilenameUtils.getExtension(getFileNameFinal);
else {
Toasty.info(ctx, getString(R.string.labelGeneralError)); if(appUtil.imageExtension(FilenameUtils.getExtension(getFileNameFinal))) {
} fileContentsArray.add(new FileDiffView(getFileNameFinal, appUtil.imageExtension(fileExtension), "", binaryFileFinal));
}
} }
@Override }
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); }
}
});
} 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)));
}
private void initCloseListener() { FilesDiffAdapter adapter = new FilesDiffAdapter(fileContentsArray, getApplicationContext());
mRecyclerView.setAdapter(adapter);
onClickListener = new View.OnClickListener() { mProgressBar.setVisibility(View.GONE);
@Override } catch (IOException e) {
public void onClick(View view) { e.printStackTrace();
}
getIntent().removeExtra("singleFileName"); }
finish(); 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();
}
};
}
} }

View File

@ -1,13 +1,14 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.pm.PackageManager;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
@ -21,25 +22,26 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.github.barteksc.pdfviewer.PDFView; import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.util.FitPolicy; import com.github.barteksc.pdfviewer.util.FitPolicy;
import com.github.chrisbanes.photoview.PhotoView; import com.github.chrisbanes.photoview.PhotoView;
import org.apache.commons.io.FileUtils; import com.pddstudio.highlightjs.HighlightJsView;
import com.pddstudio.highlightjs.models.Theme;
import org.apache.commons.io.FilenameUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetFileViewerFragment; import org.mian.gitnex.fragments.BottomSheetFileViewerFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.highlightjs.HighlightJsView;
import org.mian.gitnex.helpers.highlightjs.models.Theme;
import org.mian.gitnex.models.Files; import org.mian.gitnex.models.Files;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Objects; import java.util.Objects;
@ -52,331 +54,340 @@ import retrofit2.Callback;
public class FileViewActivity extends BaseActivity implements BottomSheetFileViewerFragment.BottomSheetListener { public class FileViewActivity extends BaseActivity implements BottomSheetFileViewerFragment.BottomSheetListener {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TextView singleFileContents; private TextView singleFileContents;
private LinearLayout singleFileContentsFrame; private LinearLayout singleFileContentsFrame;
private HighlightJsView singleCodeContents; private HighlightJsView singleCodeContents;
private PhotoView imageView; private PhotoView imageView;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private ProgressBar mProgressBar;
private ProgressBar mProgressBar; private byte[] imageData;
private byte[] imageData; private PDFView pdfView;
private PDFView pdfView; private LinearLayout pdfViewFrame;
private LinearLayout pdfViewFrame; private byte[] decodedPdf;
private byte[] decodedPdf; private Boolean pdfNightMode;
private Boolean pdfNightMode; private static final int PERMISSION_REQUEST_CODE = 1;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId(){
return R.layout.activity_file_view;
}
return R.layout.activity_file_view; @Override
} public void onCreate(Bundle savedInstanceState) {
@Override super.onCreate(savedInstanceState);
public void onCreate(Bundle savedInstanceState) { Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
super.onCreate(savedInstanceState); final TinyDB tinyDb = new TinyDB(getApplicationContext());
appCtx = 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 = findViewById(R.id.toolbar); ImageView closeActivity = findViewById(R.id.close);
setSupportActionBar(toolbar); singleFileContents = findViewById(R.id.singleFileContents);
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);
final TinyDB tinyDb = new TinyDB(appCtx); String singleFileName = getIntent().getStringExtra("singleFileName");
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");
ImageView closeActivity = findViewById(R.id.close); TextView toolbar_title = findViewById(R.id.toolbar_title);
singleFileContents = findViewById(R.id.singleFileContents); toolbar_title.setMovementMethod(new ScrollingMovementMethod());
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"); initCloseListener();
closeActivity.setOnClickListener(onClickListener);
tinyDb.putString("downloadFileContents", "");
TextView toolbar_title = findViewById(R.id.toolbar_title); try {
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
singleFileName = URLDecoder.decode(singleFileName, "UTF-8");
singleFileName = singleFileName.replaceAll("//", "/");
singleFileName = singleFileName.startsWith("/") ? singleFileName.substring(1) : singleFileName;
}
catch (UnsupportedEncodingException e) {
initCloseListener(); assert singleFileName != null;
closeActivity.setOnClickListener(onClickListener); Log.i("singleFileName", singleFileName);
tinyDb.putString("downloadFileContents", ""); }
toolbar_title.setText(singleFileName);
try { getSingleFileContents(instanceUrl, instanceToken, repoOwner, repoName, singleFileName);
}
singleFileName = URLDecoder.decode(singleFileName, "UTF-8"); private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) {
singleFileName = singleFileName.replaceAll("//", "/");
singleFileName = singleFileName.startsWith("/") ? singleFileName.substring(1) : singleFileName;
} final TinyDB tinyDb = new TinyDB(getApplicationContext());
catch(UnsupportedEncodingException e) {
assert singleFileName != null; Call<Files> call = RetrofitClient
Log.i("singleFileName", singleFileName); .getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getSingleFileContents(token, owner, repo, filename);
} call.enqueue(new Callback<Files>() {
toolbar_title.setText(singleFileName); @Override
public void onResponse(@NonNull Call<Files> call, @NonNull retrofit2.Response<Files> response) {
getSingleFileContents(instanceUrl, instanceToken, repoOwner, repoName, singleFileName, repoBranch); if (response.code() == 200) {
} AppUtil appUtil = new AppUtil();
assert response.body() != null;
private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename, String ref) { if(!response.body().getContent().equals("")) {
final TinyDB tinyDb = new TinyDB(appCtx); String fileExtension = FilenameUtils.getExtension(filename);
mProgressBar.setVisibility(View.GONE);
Call<Files> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getSingleFileContents(token, owner, repo, filename, ref); // download file meta
tinyDb.putString("downloadFileName", filename);
tinyDb.putString("downloadFileContents", response.body().getContent());
call.enqueue(new Callback<Files>() { if(appUtil.imageExtension(fileExtension)) { // file is image
@Override singleFileContentsFrame.setVisibility(View.GONE);
public void onResponse(@NonNull Call<Files> call, @NonNull retrofit2.Response<Files> response) { singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
if(response.code() == 200) { imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT);
Drawable imageDrawable = new BitmapDrawable(getResources(), BitmapFactory.decodeByteArray(imageData, 0, imageData.length));
imageView.setImageDrawable(imageDrawable);
AppUtil appUtil = new AppUtil(); }
assert response.body() != null; else if (appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode
if(!response.body().getContent().equals("")) { imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.VISIBLE);
String fileExtension = FileUtils.getExtension(filename); singleCodeContents.setTheme(Theme.GRUVBOX_DARK);
mProgressBar.setVisibility(View.GONE); singleCodeContents.setShowLineNumbers(true);
singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent()));
// download file meta }
tinyDb.putString("downloadFileName", filename); else if (appUtil.pdfExtension(fileExtension)) { // file is pdf
tinyDb.putString("downloadFileContents", response.body().getContent());
if(appUtil.imageExtension(fileExtension)) { // file is image imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.VISIBLE);
singleFileContentsFrame.setVisibility(View.GONE); pdfNightMode = tinyDb.getBoolean("enablePdfMode");
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT); decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT);
Drawable imageDrawable = new BitmapDrawable(getResources(), BitmapFactory.decodeByteArray(imageData, 0, imageData.length)); pdfView.fromBytes(decodedPdf)
imageView.setImageDrawable(imageDrawable); .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();
} }
else if(appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode else if (appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.VISIBLE); singleFileContentsFrame.setVisibility(View.VISIBLE);
switch(tinyDb.getInt("fileviewerSourceCodeThemeId")) { singleFileContents.setText(getResources().getString(R.string.excludeFilesInFileviewer));
case 1: singleFileContents.setGravity(Gravity.CENTER);
singleCodeContents.setTheme(Theme.ARDUINO_LIGHT); singleFileContents.setTypeface(null, Typeface.BOLD);
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);
}
singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent())); }
else { // file type not known - plain text view
} imageView.setVisibility(View.GONE);
else if(appUtil.pdfExtension(fileExtension)) { // file is pdf singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE);
imageView.setVisibility(View.GONE); singleFileContents.setText(appUtil.decodeBase64(response.body().getContent()));
singleFileContentsFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.VISIBLE);
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(); else {
singleFileContents.setText("");
mProgressBar.setVisibility(View.GONE);
}
} }
else if(appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded else if(response.code() == 401) {
imageView.setVisibility(View.GONE); AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
singleCodeContents.setVisibility(View.GONE); getResources().getString(R.string.alertDialogTokenRevokedMessage),
pdfViewFrame.setVisibility(View.GONE); getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
singleFileContentsFrame.setVisibility(View.VISIBLE); getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
singleFileContents.setText(getResources().getString(R.string.excludeFilesInFileviewer)); }
singleFileContents.setGravity(Gravity.CENTER); else if(response.code() == 403) {
singleFileContents.setTypeface(null, Typeface.BOLD);
} Toasty.info(ctx, ctx.getString(R.string.authorizeError));
else { // file type not known - plain text view
imageView.setVisibility(View.GONE); }
singleCodeContents.setVisibility(View.GONE); else if(response.code() == 404) {
pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
singleFileContents.setText(appUtil.decodeBase64(response.body().getContent())); }
else {
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
}
} }
} @Override
else { public void onFailure(@NonNull Call<Files> call, @NonNull Throwable t) {
singleFileContents.setText(""); Log.e("onFailure", t.toString());
mProgressBar.setVisibility(View.GONE); }
} });
} }
else if(response.code() == 401) {
@Override
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
} inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
else if(response.code() == 403) { return true;
}
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
@Override
} public boolean onOptionsItemSelected(MenuItem item) {
else if(response.code() == 404) {
int id = item.getItemId();
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
switch (id) {
} case android.R.id.home:
else { finish();
return true;
Toasty.info(ctx, getString(R.string.labelGeneralError)); case R.id.genericMenu:
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
} bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet");
return true;
} default:
return super.onOptionsItemSelected(item);
@Override }
public void onFailure(@NonNull Call<Files> call, @NonNull Throwable t) {
}
Log.e("onFailure", t.toString());
} @Override
}); public void onButtonClicked(String text) {
} switch (text) {
case "downloadFile":
@Override
public boolean onCreateOptionsMenu(Menu menu) { if (Build.VERSION.SDK_INT >= 23)
{
MenuInflater inflater = getMenuInflater(); if (checkPermission())
inflater.inflate(R.menu.generic_nav_dotted_menu, menu); {
return true; requestFileDownload();
} }
else {
@Override requestPermission();
public boolean onOptionsItemSelected(MenuItem item) { }
}
int id = item.getItemId(); else
{
switch(id) { requestFileDownload();
case android.R.id.home: }
finish(); break;
return true;
case R.id.genericMenu: }
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet"); }
return true;
default: private void requestFileDownload() {
return super.onOptionsItemSelected(item);
} final TinyDB tinyDb = new TinyDB(getApplicationContext());
} if(!tinyDb.getString("downloadFileContents").isEmpty()) {
@Override File outputFileName = new File(tinyDb.getString("downloadFileName"));
public void onButtonClicked(String text) { final File downloadFilePath = new File(Environment.getExternalStorageDirectory().getPath() + "/Download/" + outputFileName.getName());
if("downloadFile".equals(text)) { byte[] pdfAsBytes = Base64.decode(tinyDb.getString("downloadFileContents"), 0);
FileOutputStream fileOutputStream = null;
requestFileDownload();
try {
}
fileOutputStream = new FileOutputStream(downloadFilePath, false);
} Objects.requireNonNull(fileOutputStream).write(pdfAsBytes);
fileOutputStream.flush();
private void requestFileDownload() { fileOutputStream.close();
Toasty.info(getApplicationContext(), getString(R.string.downloadFileSaved));
final TinyDB tinyDb = new TinyDB(appCtx);
}
if(!tinyDb.getString("downloadFileContents").isEmpty()) { catch (IOException e) {
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
int CREATE_REQUEST_CODE = 40; }
File outputFileName = new File(tinyDb.getString("downloadFileName")); }
else {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); Toasty.error(getApplicationContext(), getString(R.string.waitLoadingDownloadFile));
}
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*"); }
intent.putExtra(Intent.EXTRA_TITLE, outputFileName.getName());
private boolean checkPermission() {
startActivityForResult(intent, CREATE_REQUEST_CODE); int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED;
} }
else {
Toasty.error(ctx, getString(R.string.waitLoadingDownloadFile)); private void requestPermission() {
} ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
@Override
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { switch (requestCode) {
case PERMISSION_REQUEST_CODE:
super.onActivityResult(requestCode, resultCode, data); if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i("PermissionsCheck", "Permission Granted");
final TinyDB tinyDb = new TinyDB(appCtx); }
else {
if (requestCode == 40 && resultCode == RESULT_OK) { Log.e("PermissionsCheck", "Permission Denied");
}
try { break;
}
assert data != null; }
Uri uri = data.getData();
private void initCloseListener() {
assert uri != null; onClickListener = new View.OnClickListener() {
OutputStream outputStream = getContentResolver().openOutputStream(uri); @Override
public void onClick(View view) {
byte[] dataAsBytes = Base64.decode(tinyDb.getString("downloadFileContents"), 0); getIntent().removeExtra("singleFileName");
finish();
assert outputStream != null; }
outputStream.write(dataAsBytes); };
outputStream.close(); }
Toasty.info(ctx, getString(R.string.downloadFileSaved)); }
}
catch (IOException e) {
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
}
}
}
private void initCloseListener() {
onClickListener = 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

View File

@ -1,30 +1,27 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import androidx.annotation.NonNull;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import android.widget.Button;
import com.google.gson.JsonElement; import android.widget.ImageView;
import android.widget.TextView;
import com.hendraanggrian.appcompat.socialview.Mention; import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter; import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityMergePullRequestBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.MergePullRequest; import org.mian.gitnex.models.MergePullRequest;
import org.mian.gitnex.models.MergePullRequestSpinner; import org.mian.gitnex.util.AppUtil;
import java.util.ArrayList; import org.mian.gitnex.util.TinyDB;
import java.util.List; import java.util.List;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
@ -37,351 +34,228 @@ import retrofit2.Response;
public class MergePullRequestActivity extends BaseActivity { public class MergePullRequestActivity extends BaseActivity {
private View.OnClickListener onClickListener; public ImageView closeActivity;
final Context ctx = this; private View.OnClickListener onClickListener;
private Context appCtx;
private ActivityMergePullRequestBinding viewBinding;
private ArrayAdapter<Mention> defaultMentionAdapter; final Context ctx = this;
private String Do;
@Override private SocialAutoCompleteTextView mergePR;
protected int getLayoutResourceId() { private ArrayAdapter<Mention> defaultMentionAdapter;
private Button mergeButton;
return R.layout.activity_merge_pull_request; @Override
} protected int getLayoutResourceId(){
return R.layout.activity_merge_pull_request;
}
@SuppressLint("SetTextI18n") @Override
@Override public void onCreate(Bundle savedInstanceState) {
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
appCtx = getApplicationContext(); TinyDB tinyDb = new TinyDB(getApplicationContext());
viewBinding = ActivityMergePullRequestBinding.inflate(getLayoutInflater()); mergePR = findViewById(R.id.mergePR);
View view = viewBinding.getRoot(); mergePR.setShowSoftInputOnFocus(true);
setContentView(view);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); defaultMentionAdapter = new MentionArrayAdapter<>(this);
TinyDB tinyDb = new TinyDB(appCtx); loadCollaboratorsList();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); mergePR.setMentionAdapter(defaultMentionAdapter);
viewBinding.mergeTitle.requestFocus(); closeActivity = findViewById(R.id.close);
assert imm != null; TextView toolbar_title = findViewById(R.id.toolbar_title);
imm.showSoftInput(viewBinding.mergeTitle, InputMethodManager.SHOW_IMPLICIT);
setMergeAdapter(); if(!tinyDb.getString("issueTitle").isEmpty()) {
toolbar_title.setText(tinyDb.getString("issueTitle"));
}
viewBinding.mergeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { initCloseListener();
closeActivity.setOnClickListener(onClickListener);
@Override mergeButton = findViewById(R.id.mergeButton);
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
MergePullRequestSpinner mergeId = (MergePullRequestSpinner) parent.getSelectedItem(); if(!connToInternet) {
Do = mergeId.getId();
} disableProcessButton();
@Override } else {
public void onNothingSelected(AdapterView<?> parent) {
} mergeButton.setOnClickListener(mergePullRequest);
}); }
defaultMentionAdapter = new MentionArrayAdapter<>(this); }
loadCollaboratorsList();
viewBinding.mergeDescription.setMentionAdapter(defaultMentionAdapter); public void loadCollaboratorsList() {
if(!tinyDb.getString("issueTitle").isEmpty()) { final TinyDB tinyDb = new TinyDB(getApplicationContext());
viewBinding.toolbarTitle.setText(tinyDb.getString("issueTitle"));
viewBinding.mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber") + ")");
}
initCloseListener(); final String instanceUrl = tinyDb.getString("instanceUrl");
viewBinding.close.setOnClickListener(onClickListener); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
// if gitea version is greater/equal(1.12.0) than user installed version (installed.higherOrEqual(compareVer)) Call<List<Collaborators>> call = RetrofitClient
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { .getInstance(instanceUrl, getApplicationContext())
viewBinding.deleteBranch.setVisibility(View.VISIBLE); .getApiInterface()
} .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
if(tinyDb.getString("prMergeable").equals("false")) { call.enqueue(new Callback<List<Collaborators>>() {
disableProcessButton();
viewBinding.mergeInfoDisabledMessage.setVisibility(View.VISIBLE);
}
else {
viewBinding.mergeInfoDisabledMessage.setVisibility(View.GONE);
}
if(tinyDb.getString("prIsFork").equals("true")) { @Override
viewBinding.deleteBranchForkInfo.setVisibility(View.VISIBLE); public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
}
else {
viewBinding.deleteBranchForkInfo.setVisibility(View.GONE);
}
if(!connToInternet) { if (response.isSuccessful()) {
disableProcessButton(); 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 { else {
viewBinding.mergeButton.setOnClickListener(mergePullRequest); Log.i("onResponse", String.valueOf(response.code()));
} }
} }
private void setMergeAdapter() { @Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.toString());
}
TinyDB tinyDb = new TinyDB(appCtx); });
}
ArrayList<MergePullRequestSpinner> mergeList = new ArrayList<>(); private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
}
mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge))); private View.OnClickListener mergePullRequest = new View.OnClickListener() {
mergeList.add(new MergePullRequestSpinner("rebase", getResources().getString(R.string.mergeOptionRebase))); public void onClick(View v) {
mergeList.add(new MergePullRequestSpinner("rebase-merge", getResources().getString(R.string.mergeOptionRebaseCommit))); processMergePullRequest();
// 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); private void processMergePullRequest() {
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
viewBinding.mergeSpinner.setAdapter(adapter);
} String mergePRDT = mergePR.getText().toString();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
public void loadCollaboratorsList() { if(!connToInternet) {
final TinyDB tinyDb = new TinyDB(appCtx); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return;
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, ctx).getApiInterface().getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); disableProcessButton();
String doWhat = "merge";
mergeFunction(doWhat, mergePRDT);
call.enqueue(new Callback<List<Collaborators>>() { }
@Override private void mergeFunction(String doWhat, String mergePRDT) {
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
if(response.isSuccessful()) { final TinyDB tinyDb = new TinyDB(getApplicationContext());
assert response.body() != null; final String instanceUrl = tinyDb.getString("instanceUrl");
String fullName = ""; final String loginUid = tinyDb.getString("loginUid");
for(int i = 0; i < response.body().size(); i++) { final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(!response.body().get(i).getFull_name().equals("")) { String repoFullName = tinyDb.getString("repoFullName");
fullName = response.body().get(i).getFull_name(); String[] parts = repoFullName.split("/");
} final String repoOwner = parts[0];
defaultMentionAdapter.add(new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url())); final String repoName = parts[1];
} final int prIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
} MergePullRequest mergePR = new MergePullRequest(doWhat, mergePRDT, null);
else {
Log.i("onResponse", String.valueOf(response.code())); Call<ResponseBody> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.mergePullRequest(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR);
} call.enqueue(new Callback<ResponseBody>() {
} @Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
@Override if(response.code() == 200) {
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.toString()); Toasty.info(getApplicationContext(), getString(R.string.mergePRSuccessMsg));
} tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true);
finish();
}); }
} else if(response.code() == 401) {
private void initCloseListener() { enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
onClickListener = view -> finish(); }
} else if(response.code() == 404) {
private View.OnClickListener mergePullRequest = v -> processMergePullRequest(); enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.mergePR404ErrorMsg));
private void processMergePullRequest() { }
else {
String mergePRDesc = viewBinding.mergeDescription.getText().toString(); enableProcessButton();
String mergePRTitle = viewBinding.mergeTitle.getText().toString(); Toasty.info(getApplicationContext(), getString(R.string.genericError));
boolean deleteBranch = viewBinding.deleteBranch.isChecked();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); }
if(!connToInternet) { }
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); @Override
return; public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
enableProcessButton();
}
} });
disableProcessButton(); }
mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch);
} private void disableProcessButton() {
private void mergeFunction(String Do, String mergePRDT, String mergeTitle, boolean deleteBranch) { mergeButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
mergeButton.setBackground(shape);
final TinyDB tinyDb = new TinyDB(appCtx); }
final String instanceUrl = tinyDb.getString("instanceUrl"); private void enableProcessButton() {
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"));
MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle); mergeButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
mergeButton.setBackground(shape);
Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().mergePullRequest(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR); }
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
if(response.code() == 200) {
if(deleteBranch) {
if(tinyDb.getString("prIsFork").equals("true")) {
String repoFullName = tinyDb.getString("prForkFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
deleteBranchFunction(repoOwner, repoName);
Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true);
finish();
}
else {
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
deleteBranchFunction(repoOwner, repoName);
Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true);
finish();
}
}
else {
Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true);
finish();
}
}
else if(response.code() == 401) {
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(ctx, getString(R.string.mergePR404ErrorMsg));
}
else {
enableProcessButton();
Toasty.info(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
enableProcessButton();
}
});
}
private void deleteBranchFunction(String repoOwner, String repoName) {
TinyDB tinyDb = new TinyDB(appCtx);
String instanceUrl = tinyDb.getString("instanceUrl");
String loginUid = tinyDb.getString("loginUid");
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String branchName = tinyDb.getString("prHeadBranch");
Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.deleteBranch(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 204) {
Log.i("deleteBranch", "Branch deleted successfully");
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
enableProcessButton();
}
});
}
private void disableProcessButton() {
viewBinding.mergeButton.setEnabled(false);
viewBinding.mergeButton.setBackground(getResources().getDrawable(R.drawable.shape_buttons_disabled));
}
private void enableProcessButton() {
viewBinding.mergeButton.setEnabled(true);
viewBinding.mergeButton.setBackground(getResources().getDrawable(R.drawable.shape_buttons));
}
} }

View File

@ -6,25 +6,23 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.NewFile; 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.ArrayList;
import java.util.List; import java.util.List;
import retrofit2.Call; import retrofit2.Call;
@ -34,7 +32,7 @@ import retrofit2.Callback;
* Author M M Arif * Author M M Arif
*/ */
public class CreateFileActivity extends BaseActivity { public class NewFileActivity extends BaseActivity {
public ImageView closeActivity; public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -46,7 +44,6 @@ public class CreateFileActivity extends BaseActivity {
private EditText newFileCommitMessage; private EditText newFileCommitMessage;
private Spinner newFileBranchesSpinner; private Spinner newFileBranchesSpinner;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
List<Branches> branchesList = new ArrayList<>(); List<Branches> branchesList = new ArrayList<>();
@ -59,13 +56,10 @@ public class CreateFileActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
@ -79,12 +73,6 @@ public class CreateFileActivity extends BaseActivity {
newFileContent = findViewById(R.id.newFileContent); newFileContent = findViewById(R.id.newFileContent);
newFileBranchName = findViewById(R.id.newFileBranchName); newFileBranchName = findViewById(R.id.newFileBranchName);
newFileCommitMessage = findViewById(R.id.newFileCommitMessage); newFileCommitMessage = findViewById(R.id.newFileCommitMessage);
TextView branchNameId = findViewById(R.id.branchNameId);
TextView branchNameHintText = findViewById(R.id.branchNameHintText);
newFileName.requestFocus();
assert imm != null;
imm.showSoftInput(newFileName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -104,18 +92,13 @@ public class CreateFileActivity extends BaseActivity {
View arg1, int arg2, long arg3) View arg1, int arg2, long arg3)
{ {
Branches bModelValue = (Branches) newFileBranchesSpinner.getSelectedItem(); Branches bModelValue = (Branches) newFileBranchesSpinner.getSelectedItem();
Log.i("bModelSelected", bModelValue.toString());
if(bModelValue.toString().equals("No branch")) { if(bModelValue.toString().equals("No branch")) {
newFileBranchName.setEnabled(true); newFileBranchName.setEnabled(true);
newFileBranchName.setVisibility(View.VISIBLE);
branchNameId.setVisibility(View.VISIBLE);
branchNameHintText.setVisibility(View.VISIBLE);
} }
else { else {
newFileBranchName.setEnabled(false); newFileBranchName.setEnabled(false);
newFileBranchName.setVisibility(View.GONE);
branchNameId.setVisibility(View.GONE);
branchNameHintText.setVisibility(View.GONE);
newFileBranchName.setText(""); newFileBranchName.setText("");
} }
@ -142,13 +125,17 @@ public class CreateFileActivity extends BaseActivity {
} }
private View.OnClickListener createFileListener = v -> processNewFile(); private View.OnClickListener createFileListener = new View.OnClickListener() {
public void onClick(View v) {
processNewFile();
}
};
private void processNewFile() { private void processNewFile() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -166,14 +153,14 @@ public class CreateFileActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) { if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) {
Toasty.info(ctx, getString(R.string.newFileRequiredFields)); Toasty.info(getApplicationContext(), getString(R.string.newFileRequiredFields));
return; return;
} }
@ -181,13 +168,13 @@ public class CreateFileActivity extends BaseActivity {
if(currentBranch.toString().equals("No branch")) { if(currentBranch.toString().equals("No branch")) {
if(newFileBranchName_.equals("")) { if(newFileBranchName_.equals("")) {
Toasty.info(ctx, getString(R.string.newFileRequiredFieldNewBranchName)); Toasty.info(getApplicationContext(), getString(R.string.newFileRequiredFieldNewBranchName));
return; return;
} }
else { else {
if(!appUtil.checkStringsWithDash(newFileBranchName_)) { if(!appUtil.checkStringsWithDash(newFileBranchName_)) {
Toasty.info(ctx, getString(R.string.newFileInvalidBranchName)); Toasty.info(getApplicationContext(), getString(R.string.newFileInvalidBranchName));
return; return;
} }
@ -197,13 +184,13 @@ public class CreateFileActivity extends BaseActivity {
if(appUtil.charactersLength(newFileCommitMessage_) > 255) { if(appUtil.charactersLength(newFileCommitMessage_) > 255) {
Toasty.info(ctx, getString(R.string.newFileCommitMessageError)); Toasty.info(getApplicationContext(), getString(R.string.newFileCommitMessageError));
} }
else { else {
disableProcessButton(); disableProcessButton();
createNewFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newFileName_, appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString()); createNewFile(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newFileName_, appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString());
} }
@ -220,7 +207,7 @@ public class CreateFileActivity extends BaseActivity {
} }
Call<JsonElement> call = RetrofitClient Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr); .createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr);
@ -232,7 +219,7 @@ public class CreateFileActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.newFileSuccessMessage)); Toasty.info(getApplicationContext(), getString(R.string.newFileSuccessMessage));
finish(); finish();
} }
@ -249,11 +236,11 @@ public class CreateFileActivity extends BaseActivity {
if(response.code() == 404) { if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.apiNotFound)); Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.orgCreatedError)); Toasty.info(getApplicationContext(), getString(R.string.orgCreatedError));
} }
} }
@ -272,9 +259,9 @@ public class CreateFileActivity extends BaseActivity {
private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
Call<List<Branches>> call = RetrofitClient Call<List<Branches>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getBranches(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); .getBranches(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Branches>>() { call.enqueue(new Callback<List<Branches>>() {
@ -299,7 +286,7 @@ public class CreateFileActivity extends BaseActivity {
} }
} }
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateFileActivity.this, ArrayAdapter<Branches> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, branchesList); R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
@ -320,7 +307,12 @@ public class CreateFileActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> finish(); onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
} }
private void disableProcessButton() { private void disableProcessButton() {

View File

@ -1,35 +1,34 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.DatePicker; import android.widget.DatePicker;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.NonNull;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.Calendar; import java.util.Calendar;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class CreateMilestoneActivity extends BaseActivity implements View.OnClickListener { public class NewMilestoneActivity extends BaseActivity implements View.OnClickListener {
private EditText milestoneDueDate; private EditText milestoneDueDate;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -37,7 +36,6 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
private EditText milestoneDescription; private EditText milestoneDescription;
private Button createNewMilestoneButton; private Button createNewMilestoneButton;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -46,13 +44,9 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
milestoneDueDate = findViewById(R.id.milestoneDueDate); milestoneDueDate = findViewById(R.id.milestoneDueDate);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
@ -60,10 +54,6 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
milestoneTitle = findViewById(R.id.milestoneTitle); milestoneTitle = findViewById(R.id.milestoneTitle);
milestoneDescription = findViewById(R.id.milestoneDescription); milestoneDescription = findViewById(R.id.milestoneDescription);
milestoneTitle.requestFocus();
assert imm != null;
imm.showSoftInput(milestoneTitle, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
milestoneDueDate.setOnClickListener(this); milestoneDueDate.setOnClickListener(this);
@ -92,9 +82,9 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
private void processNewMilestone() { private void processNewMilestone() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
@ -110,14 +100,14 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newMilestoneTitle.equals("")) { if(newMilestoneTitle.equals("")) {
Toasty.info(ctx, getString(R.string.milestoneNameErrorEmpty)); Toasty.info(getApplicationContext(), getString(R.string.milestoneNameErrorEmpty));
return; return;
} }
@ -125,7 +115,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(!newMilestoneDescription.equals("")) { if(!newMilestoneDescription.equals("")) {
if (appUtil.charactersLength(newMilestoneDescription) > 255) { if (appUtil.charactersLength(newMilestoneDescription) > 255) {
Toasty.info(ctx, getString(R.string.milestoneDescError)); Toasty.info(getApplicationContext(), getString(R.string.milestoneDescError));
return; return;
} }
@ -134,14 +124,14 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
String finalMilestoneDueDate = null; String finalMilestoneDueDate = null;
if(!newMilestoneDueDate.isEmpty()) { if(!newMilestoneDueDate.isEmpty()) {
finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate))); finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate)));
} else if (new Version(tinyDb.getString("giteaVersion")).less("1.10.0")) { } else if (VersionCheck.compareVersion("1.10.0", tinyDb.getString("giteaVersion")) > 1) {
// if Gitea version is less than 1.10.0 DueDate is required // if Gitea version is less than 1.10.0 DueDate is required
Toasty.info(ctx, getString(R.string.milestoneDateEmpty)); Toasty.info(getApplicationContext(), getString(R.string.milestoneDateEmpty));
return; return;
} }
disableProcessButton(); disableProcessButton();
createNewMilestone(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate); createNewMilestone(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate);
} }
@ -152,7 +142,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
Call<Milestones> call; Call<Milestones> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createMilestone(token, repoOwner, repoName, createMilestone); .createMilestone(token, repoOwner, repoName, createMilestone);
@ -164,9 +154,9 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 201) { if(response.code() == 201) {
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putBoolean("milestoneCreated", true); tinyDb.putBoolean("milestoneCreated", true);
Toasty.info(ctx, getString(R.string.milestoneCreated)); Toasty.info(getApplicationContext(), getString(R.string.milestoneCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -184,7 +174,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.milestoneCreatedError)); Toasty.info(getApplicationContext(), getString(R.string.milestoneCreatedError));
} }

View File

@ -3,21 +3,20 @@ package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.NonNull;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserOrganizations; import org.mian.gitnex.models.UserOrganizations;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -25,7 +24,7 @@ import retrofit2.Callback;
* Author M M Arif * Author M M Arif
*/ */
public class CreateOrganizationActivity extends BaseActivity { public class NewOrganizationActivity extends BaseActivity {
public ImageView closeActivity; public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -34,7 +33,6 @@ public class CreateOrganizationActivity extends BaseActivity {
private EditText orgName; private EditText orgName;
private EditText orgDesc; private EditText orgDesc;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -43,22 +41,14 @@ public class CreateOrganizationActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
closeActivity = findViewById(R.id.close); closeActivity = findViewById(R.id.close);
orgName = findViewById(R.id.newOrganizationName); orgName = findViewById(R.id.newOrganizationName);
orgDesc = findViewById(R.id.newOrganizationDescription); orgDesc = findViewById(R.id.newOrganizationDescription);
orgName.requestFocus();
assert imm != null;
imm.showSoftInput(orgName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -97,9 +87,9 @@ public class CreateOrganizationActivity extends BaseActivity {
private void processNewOrganization() { private void processNewOrganization() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -109,7 +99,7 @@ public class CreateOrganizationActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
@ -117,7 +107,7 @@ public class CreateOrganizationActivity extends BaseActivity {
if(!newOrgDesc.equals("")) { if(!newOrgDesc.equals("")) {
if (appUtil.charactersLength(newOrgDesc) > 255) { if (appUtil.charactersLength(newOrgDesc) > 255) {
Toasty.info(ctx, getString(R.string.orgDescError)); Toasty.info(getApplicationContext(), getString(R.string.orgDescError));
return; return;
} }
@ -125,18 +115,18 @@ public class CreateOrganizationActivity extends BaseActivity {
if(newOrgName.equals("")) { if(newOrgName.equals("")) {
Toasty.info(ctx, getString(R.string.orgNameErrorEmpty)); Toasty.info(getApplicationContext(), getString(R.string.orgNameErrorEmpty));
} }
else if(!appUtil.checkStrings(newOrgName)) { else if(!appUtil.checkStrings(newOrgName)) {
Toasty.info(ctx, getString(R.string.orgNameErrorInvalid)); Toasty.info(getApplicationContext(), getString(R.string.orgNameErrorInvalid));
} }
else { else {
disableProcessButton(); disableProcessButton();
createNewOrganization(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newOrgName, newOrgDesc); createNewOrganization(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newOrgName, newOrgDesc);
} }
@ -147,7 +137,7 @@ public class CreateOrganizationActivity extends BaseActivity {
UserOrganizations createOrganization = new UserOrganizations(orgName, null, orgDesc, null, null); UserOrganizations createOrganization = new UserOrganizations(orgName, null, orgDesc, null, null);
Call<UserOrganizations> call = RetrofitClient Call<UserOrganizations> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewOrganization(token, createOrganization); .createNewOrganization(token, createOrganization);
@ -158,10 +148,10 @@ public class CreateOrganizationActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putBoolean("orgCreated", true); tinyDb.putBoolean("orgCreated", true);
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.orgCreated)); Toasty.info(getApplicationContext(), getString(R.string.orgCreated));
finish(); finish();
} }
@ -177,24 +167,24 @@ public class CreateOrganizationActivity extends BaseActivity {
else if(response.code() == 409) { else if(response.code() == 409) {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.orgExistsError)); Toasty.info(getApplicationContext(), getString(R.string.orgExistsError));
} }
else if(response.code() == 422) { else if(response.code() == 422) {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.orgExistsError)); Toasty.info(getApplicationContext(), getString(R.string.orgExistsError));
} }
else { else {
if(response.code() == 404) { if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.apiNotFound)); Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.orgCreatedError)); Toasty.info(getApplicationContext(), getString(R.string.orgCreatedError));
} }
} }

View File

@ -4,9 +4,9 @@ import android.content.Context;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
@ -14,20 +14,17 @@ import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner; import android.widget.Spinner;
import androidx.annotation.NonNull;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.OrgOwner; import org.mian.gitnex.models.OrgOwner;
import org.mian.gitnex.models.OrganizationRepository; 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.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -35,7 +32,7 @@ import retrofit2.Callback;
* Author M M Arif * Author M M Arif
*/ */
public class CreateRepoActivity extends BaseActivity { public class NewRepoActivity extends BaseActivity {
public ImageView closeActivity; public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -45,50 +42,37 @@ public class CreateRepoActivity extends BaseActivity {
private EditText repoDesc; private EditText repoDesc;
private CheckBox repoAccess; private CheckBox repoAccess;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
List<OrgOwner> organizationsList = new ArrayList<>(); List<OrgOwner> orgsList = 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 @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_new_repo; return R.layout.activity_new_repo;
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(ctx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String userLogin = tinyDb.getString("userLogin"); final String userLogin = tinyDb.getString("userLogin");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
closeActivity = findViewById(R.id.close); closeActivity = findViewById(R.id.close);
repoName = findViewById(R.id.newRepoName); repoName = findViewById(R.id.newRepoName);
repoDesc = findViewById(R.id.newRepoDescription); repoDesc = findViewById(R.id.newRepoDescription);
repoAccess = findViewById(R.id.newRepoPrivate); repoAccess = findViewById(R.id.newRepoPrivate);
repoName.requestFocus();
assert imm != null;
imm.showSoftInput(repoName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
spinner = findViewById(R.id.ownerSpinner); spinner = findViewById(R.id.ownerSpinner);
spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP); spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getOrganizations(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), userLogin); getOrgs(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), userLogin);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
@ -114,6 +98,7 @@ public class CreateRepoActivity extends BaseActivity {
createRepo.setOnClickListener(createRepoListener); createRepo.setOnClickListener(createRepoListener);
} }
} }
private View.OnClickListener createRepoListener = new View.OnClickListener() { private View.OnClickListener createRepoListener = new View.OnClickListener() {
@ -124,9 +109,9 @@ public class CreateRepoActivity extends BaseActivity {
private void processNewRepo() { private void processNewRepo() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -138,7 +123,7 @@ public class CreateRepoActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
@ -146,7 +131,7 @@ public class CreateRepoActivity extends BaseActivity {
if(!newRepoDesc.equals("")) { if(!newRepoDesc.equals("")) {
if (appUtil.charactersLength(newRepoDesc) > 255) { if (appUtil.charactersLength(newRepoDesc) > 255) {
Toasty.info(ctx, getString(R.string.repoDescError)); Toasty.info(getApplicationContext(), getString(R.string.repoDescError));
return; return;
} }
@ -154,30 +139,22 @@ public class CreateRepoActivity extends BaseActivity {
if(newRepoName.equals("")) { if(newRepoName.equals("")) {
Toasty.info(ctx, getString(R.string.repoNameErrorEmpty)); Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorEmpty));
} }
else if(!appUtil.checkStrings(newRepoName)) { else if(!appUtil.checkStrings(newRepoName)) {
Toasty.info(ctx, getString(R.string.repoNameErrorInvalid)); Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorInvalid));
}
else if (reservedRepoNames.contains(newRepoName)) {
Toasty.info(ctx, getString(R.string.repoNameErrorReservedName));
}
else if (reservedRepoPatterns.matcher(newRepoName).find()) {
Toasty.info(ctx, getString(R.string.repoNameErrorReservedPatterns));
} }
else { else {
//Log.i("repoOwner", String.valueOf(repoOwner));
disableProcessButton(); disableProcessButton();
createNewRepository(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess); createNewRepository(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, 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 instanceUrl, final String token, String loginUid, String repoName, String repoDesc, String repoOwner, boolean isPrivate) {
@ -188,7 +165,7 @@ public class CreateRepoActivity extends BaseActivity {
if(repoOwner.equals(loginUid)) { if(repoOwner.equals(loginUid)) {
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewUserRepository(token, createRepository); .createNewUserRepository(token, createRepository);
@ -196,7 +173,7 @@ public class CreateRepoActivity extends BaseActivity {
else { else {
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewUserOrgRepository(token, repoOwner, createRepository); .createNewUserOrgRepository(token, repoOwner, createRepository);
@ -209,9 +186,9 @@ public class CreateRepoActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putBoolean("repoCreated", true); tinyDb.putBoolean("repoCreated", true);
Toasty.info(ctx, getString(R.string.repoCreated)); Toasty.info(getApplicationContext(), getString(R.string.repoCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
} }
@ -227,13 +204,13 @@ public class CreateRepoActivity extends BaseActivity {
else if(response.code() == 409) { else if(response.code() == 409) {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.repoExistsError)); Toasty.info(getApplicationContext(), getString(R.string.repoExistsError));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.repoCreatedError)); Toasty.info(getApplicationContext(), getString(R.string.repoCreatedError));
} }
@ -245,14 +222,13 @@ public class CreateRepoActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
} }
}); });
} }
private void getOrganizations(String instanceUrl, String instanceToken, final String userLogin) { private void getOrgs(String instanceUrl, String instanceToken, final String userLogin) {
TinyDB tinyDb = new TinyDB(appCtx);
Call<List<OrgOwner>> call = RetrofitClient Call<List<OrgOwner>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getOrgOwners(instanceToken); .getOrgOwners(instanceToken);
@ -264,39 +240,26 @@ public class CreateRepoActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 200) { if(response.code() == 200) {
int organizationId = 0; List<OrgOwner> orgsList_ = response.body();
List<OrgOwner> organizationsList_ = response.body(); orgsList.add(new OrgOwner(userLogin));
assert orgsList_ != null;
if(orgsList_.size() > 0) {
for (int i = 0; i < orgsList_.size(); i++) {
organizationsList.add(new OrgOwner(userLogin));
assert organizationsList_ != null;
if(organizationsList_.size() > 0) {
for (int i = 0; i < organizationsList_.size(); i++) {
if(!tinyDb.getString("organizationId").isEmpty()) {
if (Integer.parseInt(tinyDb.getString("organizationId")) == organizationsList_.get(i).getId()) {
organizationId = i + 1;
}
}
OrgOwner data = new OrgOwner( OrgOwner data = new OrgOwner(
organizationsList_.get(i).getUsername() orgsList_.get(i).getUsername()
); );
organizationsList.add(data); orgsList.add(data);
} }
} }
ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(CreateRepoActivity.this, ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, organizationsList); R.layout.spinner_item, orgsList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
spinner.setAdapter(adapter); spinner.setAdapter(adapter);
if (tinyDb.getBoolean("organizationAction") & organizationId != 0) {
spinner.setSelection(organizationId);
tinyDb.putBoolean("organizationAction", false);
}
enableProcessButton(); enableProcessButton();
} }
@ -319,6 +282,7 @@ public class CreateRepoActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
} }
}); });
} }
private void initCloseListener() { private void initCloseListener() {

View File

@ -1,17 +1,10 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import org.mian.gitnex.R; import org.mian.gitnex.util.TinyDB;
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 * Author M M Arif
@ -19,33 +12,23 @@ import io.mikael.urlbuilder.UrlBuilder;
public class OpenRepoInBrowserActivity extends AppCompatActivity { public class OpenRepoInBrowserActivity extends AppCompatActivity {
private Context appCtx;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
try { TinyDB tinyDb = new TinyDB(getApplicationContext());
String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw");
if (!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol");
}
URI instanceUrl = new URI(tinyDb.getString("instanceUrlWithProtocol")); String repoFullNameBrowser = getIntent().getStringExtra("repoFullNameBrowser");
Uri url = Uri.parse(instanceUrlWithProtocol + "/" + repoFullNameBrowser);
String browserPath = PathsHelper.join(instanceUrl.getPath(), getIntent().getStringExtra("repoFullNameBrowser")); Intent i = new Intent(Intent.ACTION_VIEW, url);
startActivity(i);
String browserUrl = UrlBuilder.fromUri(instanceUrl) finish();
.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));
}
} }

View File

@ -1,6 +1,12 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; 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.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
@ -10,30 +16,20 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.fragments.BottomSheetOrganizationFragment;
import org.mian.gitnex.fragments.MembersByOrgFragment; import org.mian.gitnex.fragments.MembersByOrgFragment;
import org.mian.gitnex.fragments.OrgBottomSheetFragment;
import org.mian.gitnex.fragments.OrganizationInfoFragment; import org.mian.gitnex.fragments.OrganizationInfoFragment;
import org.mian.gitnex.fragments.RepositoriesByOrgFragment; import org.mian.gitnex.fragments.RepositoriesByOrgFragment;
import org.mian.gitnex.fragments.TeamsByOrgFragment; import org.mian.gitnex.fragments.TeamsByOrgFragment;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.Objects; import java.util.Objects;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class OrganizationDetailActivity extends BaseActivity implements BottomSheetOrganizationFragment.BottomSheetListener { public class OrgDetailActivity extends BaseActivity implements OrgBottomSheetFragment.BottomSheetListener {
final Context ctx = this;
private Context appCtx;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -42,11 +38,9 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
String orgName = tinyDb.getString("orgName"); String orgName = tinyDb.getString("orgName");
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
@ -56,7 +50,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
Objects.requireNonNull(getSupportActionBar()).setTitle(orgName); Objects.requireNonNull(getSupportActionBar()).setTitle(orgName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
OrganizationDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrganizationDetailActivity.SectionsPagerAdapter(getSupportFragmentManager()); OrgDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrgDetailActivity.SectionsPagerAdapter(getSupportFragmentManager());
ViewPager mViewPager = findViewById(R.id.container); ViewPager mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setAdapter(mSectionsPagerAdapter);
@ -64,20 +58,24 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
TabLayout tabLayout = findViewById(R.id.tabs); TabLayout tabLayout = findViewById(R.id.tabs);
Typeface myTypeface; Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
switch(tinyDb.getInt("customFontId", -1)) { myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
case 0: }
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
break;
case 2: myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default: }
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf"); else if (tinyDb.getInt("customFontId") == 2) {
break;
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
} }
@ -120,7 +118,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
finish(); finish();
return true; return true;
case R.id.repoMenu: case R.id.repoMenu:
BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment(); OrgBottomSheetFragment bottomSheet = new OrgBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet");
return true; return true;
default: default:
@ -132,15 +130,9 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@Override @Override
public void onButtonClicked(String text) { public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(appCtx);
switch (text) { switch (text) {
case "repository":
tinyDb.putBoolean("organizationAction", true);
startActivity(new Intent(OrganizationDetailActivity.this, CreateRepoActivity.class));
break;
case "team": case "team":
startActivity(new Intent(OrganizationDetailActivity.this, CreateTeamByOrgActivity.class)); startActivity(new Intent(OrgDetailActivity.this, CreateTeamByOrgActivity.class));
break; break;
} }
//Log.i("clicked", text); //Log.i("clicked", text);
@ -150,16 +142,16 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
public class SectionsPagerAdapter extends FragmentPagerAdapter { public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) { SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); super(fm);
} }
@NonNull @NonNull
@Override @Override
public Fragment getItem(int position) { public Fragment getItem(int position) {
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
String orgName; String orgName;
if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) { if(getIntent().getStringExtra("orgName") != null || !getIntent().getStringExtra("orgName").equals("")) {
orgName = getIntent().getStringExtra("orgName"); orgName = getIntent().getStringExtra("orgName");
} }
else { else {

View File

@ -0,0 +1,106 @@
package org.mian.gitnex.activities;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.view.View;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.TeamMembersByOrgAdapter;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.TeamMembersByOrgViewModel;
import java.util.List;
import java.util.Objects;
/**
* Author M M Arif
*/
public class OrgTeamMembersActivity extends BaseActivity {
private TextView noDataMembers;
private View.OnClickListener onClickListener;
private TeamMembersByOrgAdapter adapter;
private GridView mGridView;
@Override
protected int getLayoutResourceId(){
return R.layout.activity_org_team_members;
}
@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");
ImageView closeActivity = findViewById(R.id.close);
TextView toolbarTitle = findViewById(R.id.toolbar_title);
noDataMembers = findViewById(R.id.noDataMembers);
mGridView = findViewById(R.id.gridView);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
if(getIntent().getStringExtra("teamTitle") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamTitle")).equals("")) {
toolbarTitle.setText(getIntent().getStringExtra("teamTitle"));
}
else {
toolbarTitle.setText(R.string.orgTeamMembers);
}
String teamId;
if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")){
teamId = getIntent().getStringExtra("teamId");
}
else {
teamId = "0";
}
getIntent().getStringExtra("teamId");
//Log.i("teamId", getIntent().getStringExtra("teamId"));
assert teamId != null;
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), Integer.valueOf(teamId));
}
private void fetchDataAsync(String instanceUrl, 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);
}
}
});
}
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
}
}

View File

@ -1,165 +0,0 @@
package org.mian.gitnex.activities;
import android.content.Context;
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.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.fragments.BottomSheetOrganizationTeamsFragment;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.viewmodels.TeamMembersByOrgViewModel;
import java.util.Objects;
/**
* Author M M Arif
*/
public class OrganizationTeamMembersActivity extends BaseActivity implements BottomSheetOrganizationTeamsFragment.BottomSheetListener {
private TextView noDataMembers;
private View.OnClickListener onClickListener;
private TeamMembersByOrgAdapter adapter;
private GridView mGridView;
final Context ctx = this;
private Context appCtx;
private String teamId;
@Override
protected int getLayoutResourceId(){
return R.layout.activity_org_team_members;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
ImageView closeActivity = findViewById(R.id.close);
TextView toolbarTitle = findViewById(R.id.toolbar_title);
noDataMembers = findViewById(R.id.noDataMembers);
mGridView = findViewById(R.id.gridView);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
if(getIntent().getStringExtra("teamTitle") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamTitle")).equals("")) {
toolbarTitle.setText(getIntent().getStringExtra("teamTitle"));
}
else {
toolbarTitle.setText(R.string.orgTeamMembers);
}
if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")){
teamId = getIntent().getStringExtra("teamId");
}
else {
teamId = "0";
}
assert teamId != null;
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), Integer.parseInt(teamId));
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("teamActionFlag")) {
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), Integer.parseInt(teamId));
tinyDb.putBoolean("teamActionFlag", false);
}
}
private void fetchDataAsync(String instanceUrl, String instanceToken, int teamId) {
TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class);
teamMembersModel.getMembersByOrgList(instanceUrl, 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);
}
});
}
@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();
switch(id) {
case android.R.id.home:
finish();
return true;
case R.id.genericMenu:
BottomSheetOrganizationTeamsFragment bottomSheet = new BottomSheetOrganizationTeamsFragment();
bottomSheet.show(getSupportFragmentManager(), "orgTeamsBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(appCtx);
if("newMember".equals(text)) {
Intent intent = new Intent(OrganizationTeamMembersActivity.this, AddNewTeamMemberActivity.class);
intent.putExtra("teamId", teamId);
startActivity(intent);
}
}
private void initCloseListener() {
onClickListener = view -> finish();
}
}

View File

@ -1,30 +1,29 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.util.Patterns; import android.util.Patterns;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.AddEmail; 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.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -35,7 +34,6 @@ public class ProfileEmailActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private EditText userEmail; private EditText userEmail;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private Button addEmailButton; private Button addEmailButton;
@Override @Override
@ -45,22 +43,14 @@ public class ProfileEmailActivity extends BaseActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
userEmail = findViewById(R.id.userEmail); userEmail = findViewById(R.id.userEmail);
addEmailButton = findViewById(R.id.addEmailButton); addEmailButton = findViewById(R.id.addEmailButton);
userEmail.requestFocus();
assert imm != null;
imm.showSoftInput(userEmail, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -84,8 +74,8 @@ public class ProfileEmailActivity extends BaseActivity {
private void processAddNewEmail() { private void processAddNewEmail() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -94,20 +84,20 @@ public class ProfileEmailActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newUserEmail.equals("")) { if(newUserEmail.equals("")) {
Toasty.info(ctx, getString(R.string.emailErrorEmpty)); Toasty.info(getApplicationContext(), getString(R.string.emailErrorEmpty));
return; return;
} }
else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
Toasty.info(ctx, getString(R.string.emailErrorInvalid)); Toasty.info(getApplicationContext(), getString(R.string.emailErrorInvalid));
return; return;
} }
@ -115,19 +105,19 @@ public class ProfileEmailActivity extends BaseActivity {
List<String> newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(","))); List<String> newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(",")));
disableProcessButton(); disableProcessButton();
addNewEmail(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newEmailList); addNewEmail(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newEmailList);
} }
private void addNewEmail(final String instanceUrl, final String token, List<String> newUserEmail) { private void addNewEmail(final String instanceUrl, final String token, List<String> newUserEmail) {
AddEmail addEmailFunc = new AddEmail(newUserEmail); AddEmail addEmailFunc = new AddEmail(newUserEmail);
final TinyDB tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<JsonElement> call; Call<JsonElement> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.addNewEmail(token, addEmailFunc); .addNewEmail(token, addEmailFunc);
@ -138,7 +128,7 @@ public class ProfileEmailActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.info(ctx, getString(R.string.emailAddedText)); Toasty.info(getApplicationContext(), getString(R.string.emailAddedText));
tinyDb.putBoolean("emailsRefresh", true); tinyDb.putBoolean("emailsRefresh", true);
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -174,7 +164,7 @@ public class ProfileEmailActivity extends BaseActivity {
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.labelGeneralError)); Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
} }

View File

@ -1,42 +1,32 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import com.hendraanggrian.appcompat.socialview.Mention; import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter; import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView; import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.IssueActions; import org.mian.gitnex.actions.IssueActions;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.List; import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -44,374 +34,250 @@ import retrofit2.Response;
public class ReplyToIssueActivity extends BaseActivity { public class ReplyToIssueActivity extends BaseActivity {
public ImageView closeActivity; public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
private Context appCtx;
private TextView draftSaved; private SocialAutoCompleteTextView addComment;
private SocialAutoCompleteTextView addComment; private ArrayAdapter<Mention> defaultMentionAdapter;
private ArrayAdapter<Mention> defaultMentionAdapter; private Button replyButton;
private Button replyButton;
private String TAG = StaticGlobalVariables.replyToIssueActivity;
private long draftId;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_reply_to_issue; return R.layout.activity_reply_to_issue;
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(getApplicationContext());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); addComment = findViewById(R.id.addComment);
TinyDB tinyDb = new TinyDB(appCtx); addComment.setShowSoftInputOnFocus(true);
draftSaved = findViewById(R.id.draftSaved); defaultMentionAdapter = new MentionArrayAdapter<>(this);
addComment = findViewById(R.id.addComment); loadCollaboratorsList();
addComment.setShowSoftInputOnFocus(true);
defaultMentionAdapter = new MentionArrayAdapter<>(ctx); addComment.setMentionAdapter(defaultMentionAdapter);
loadCollaboratorsList();
addComment.setMentionAdapter(defaultMentionAdapter); closeActivity = findViewById(R.id.close);
TextView toolbar_title = findViewById(R.id.toolbar_title);
closeActivity = findViewById(R.id.close); if(!tinyDb.getString("issueTitle").isEmpty()) {
TextView toolbar_title = findViewById(R.id.toolbar_title); toolbar_title.setText(tinyDb.getString("issueTitle"));
}
addComment.requestFocus(); initCloseListener();
assert imm != null; closeActivity.setOnClickListener(onClickListener);
imm.showSoftInput(addComment, InputMethodManager.SHOW_IMPLICIT);
if(!tinyDb.getString("issueTitle").isEmpty()) { replyButton = findViewById(R.id.replyButton);
toolbar_title.setText(tinyDb.getString("issueTitle"));
}
initCloseListener(); if(getIntent().getStringExtra("commentAction") != null && getIntent().getStringExtra("commentAction").equals("edit")) {
closeActivity.setOnClickListener(onClickListener);
replyButton = findViewById(R.id.replyButton); addComment.setText(getIntent().getStringExtra("commentBody"));
final String commentId = getIntent().getStringExtra("commentId");
if(getIntent().getStringExtra("commentBody") != null) { toolbar_title.setText(getResources().getString(R.string.editCommentTitle));
replyButton.setText(getResources().getString(R.string.editCommentButtonText));
addComment.setText(getIntent().getStringExtra("commentBody")); replyButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
disableProcessButton();
IssueActions.editIssueComment(ctx, Integer.valueOf(commentId), addComment.getText().toString());
}
if(getIntent().getBooleanExtra("cursorToEnd", false)) { });
addComment.setSelection(addComment.length());
}
} return;
if(getIntent().getStringExtra("draftTitle") != null) { }
toolbar_title.setText(getIntent().getStringExtra("draftTitle")); if(!connToInternet) {
} disableProcessButton();
if(getIntent().getStringExtra("commentAction") != null && getIntent().getStringExtra("commentAction").equals("edit")) { } else {
final String commentId = getIntent().getStringExtra("commentId"); replyButton.setOnClickListener(replyToIssue);
toolbar_title.setText(getResources().getString(R.string.editCommentTitle)); }
replyButton.setText(getResources().getString(R.string.editCommentButtonText));
addComment.addTextChangedListener(new TextWatcher() { }
public void afterTextChanged(Editable s) { public void loadCollaboratorsList() {
} final TinyDB tinyDb = new TinyDB(getApplicationContext());
public void beforeTextChanged(CharSequence s, int start, int count, int after) { 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);
public void onTextChanged(CharSequence s, int start, int before, int count) { call.enqueue(new Callback<List<Collaborators>>() {
saveDraft(addComment.getText().toString()); @Override
draftSaved.setVisibility(View.VISIBLE); 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()));
}
replyButton.setOnClickListener(v -> { } else {
disableProcessButton(); Log.i("onResponse", String.valueOf(response.code()));
assert commentId != null;
IssueActions.editIssueComment(ctx, Integer.parseInt(commentId), addComment.getText().toString());
}); }
return; }
} @Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.getMessage());
}
addComment.addTextChangedListener(new TextWatcher() { });
}
public void afterTextChanged(Editable s) { 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();
}
};
public void beforeTextChanged(CharSequence s, int start, int count, int after) { private void processNewCommentReply() {
} String newReplyDT = addComment.getText().toString();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
public void onTextChanged(CharSequence s, int start, int before, int count) { if(!connToInternet) {
saveDraft(addComment.getText().toString()); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
draftSaved.setVisibility(View.VISIBLE); return;
} }
}); if(newReplyDT.equals("")) {
if(!connToInternet) { Toasty.info(getApplicationContext(), getString(R.string.commentEmptyError));
disableProcessButton(); }
else {
} disableProcessButton();
else { replyComment(newReplyDT);
replyButton.setOnClickListener(replyToIssue); }
} }
} private void replyComment(String newReplyDT) {
private void saveDraft(String draftText) { final TinyDB tinyDb = new TinyDB(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];
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
int repositoryId = (int) tinyDb.getLong("repositoryId", 0); Issues issueComment = new Issues(newReplyDT);
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
int issueNumber = Integer.parseInt(tinyDb.getString("issueNumber"));
DraftsApi draftsApi = new DraftsApi(appCtx); Call<Issues> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.replyCommentToIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment);
int countDraft = draftsApi.checkDraft(issueNumber, repositoryId); call.enqueue(new Callback<Issues>() {
if(countDraft == 0) { @Override
draftId = draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, draftText, StaticGlobalVariables.draftTypeComment); public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
}
else {
DraftsApi.updateDraftByIssueIdAsyncTask(draftText, issueNumber, repositoryId);
}
} if(response.code() == 201) {
public void loadCollaboratorsList() { Toasty.info(getApplicationContext(), getString(R.string.commentSuccess));
tinyDb.putBoolean("commentPosted", true);
tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("resumePullRequests", true);
finish();
final TinyDB tinyDb = new TinyDB(appCtx); }
else if(response.code() == 401) {
final String instanceUrl = tinyDb.getString("instanceUrl"); enableProcessButton();
final String loginUid = tinyDb.getString("loginUid"); AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); getResources().getString(R.string.alertDialogTokenRevokedMessage),
String repoFullName = tinyDb.getString("repoFullName"); getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
String[] parts = repoFullName.split("/"); getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient }
.getInstance(instanceUrl, ctx) else {
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.commentError));
@Override }
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
if (response.isSuccessful()) { }
assert response.body() != null; @Override
String fullName = ""; public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
for(int i = 0; i < response.body().size(); i++) { Log.e("onFailure", t.toString());
if(!response.body().get(i).getFull_name().equals("")) { enableProcessButton();
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(TAG, String.valueOf(response.code())); private void disableProcessButton() {
} replyButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
replyButton.setBackground(shape);
} }
@Override private void enableProcessButton() {
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString()); replyButton.setEnabled(true);
} GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
replyButton.setBackground(shape);
}); }
}
private void initCloseListener() {
onClickListener = view -> finish();
}
private View.OnClickListener replyToIssue = v -> processNewCommentReply();
private void processNewCommentReply() {
String newReplyDT = addComment.getText().toString();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if(!connToInternet) {
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if(newReplyDT.equals("")) {
Toasty.info(ctx, getString(R.string.commentEmptyError));
}
else {
disableProcessButton();
replyComment(newReplyDT);
}
}
private void replyComment(String newReplyDT) {
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
Issues issueComment = new Issues(newReplyDT);
Call<Issues> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.replyCommentToIssue(Authorization.returnAuthentication(ctx, 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(ctx, getString(R.string.commentSuccess));
tinyDb.putBoolean("commentPosted", true);
tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("resumePullRequests", true);
// delete draft comment
if(tinyDb.getBoolean("draftsCommentsDeletionEnabled")) {
int repositoryId = (int) tinyDb.getLong("repositoryId", 0);
int issueNumber = Integer.parseInt(tinyDb.getString("issueNumber"));
DraftsApi draftsApi = new DraftsApi(appCtx);
draftId = draftsApi.getDraftIdAsync(issueNumber, repositoryId);
draftsApi.deleteSingleDraft((int) draftId);
}
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(ctx, getString(R.string.commentError));
}
}
@Override
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
enableProcessButton();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.reply_to_issue, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.replyToIssueMenu:
Intent fragmentIntent = new Intent(ReplyToIssueActivity.this, MainActivity.class);
fragmentIntent.putExtra("launchFragment", "drafts");
ReplyToIssueActivity.this.startActivity(fragmentIntent);
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
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);
}
} }

View File

@ -1,12 +1,19 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import com.google.android.material.tabs.TabLayout;
import com.google.gson.JsonElement;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import retrofit2.Call;
import retrofit2.Callback;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -16,22 +23,10 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetIssuesFilterFragment;
import org.mian.gitnex.fragments.BottomSheetMilestonesFilterFragment;
import org.mian.gitnex.fragments.BottomSheetPullRequestFilterFragment;
import org.mian.gitnex.fragments.BottomSheetRepoFragment;
import org.mian.gitnex.fragments.BranchesFragment; import org.mian.gitnex.fragments.BranchesFragment;
import org.mian.gitnex.fragments.ClosedIssuesFragment;
import org.mian.gitnex.fragments.CollaboratorsFragment; import org.mian.gitnex.fragments.CollaboratorsFragment;
import org.mian.gitnex.fragments.FilesFragment; import org.mian.gitnex.fragments.FilesFragment;
import org.mian.gitnex.fragments.IssuesFragment; import org.mian.gitnex.fragments.IssuesFragment;
@ -39,609 +34,354 @@ import org.mian.gitnex.fragments.LabelsFragment;
import org.mian.gitnex.fragments.MilestonesFragment; import org.mian.gitnex.fragments.MilestonesFragment;
import org.mian.gitnex.fragments.PullRequestsFragment; import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.fragments.ReleasesFragment; import org.mian.gitnex.fragments.ReleasesFragment;
import org.mian.gitnex.fragments.RepoBottomSheetFragment;
import org.mian.gitnex.fragments.RepoInfoFragment; import org.mian.gitnex.fragments.RepoInfoFragment;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.models.WatchRepository;
import java.util.ArrayList; import org.mian.gitnex.util.AppUtil;
import java.util.List; import org.mian.gitnex.util.TinyDB;
import java.util.Objects; import java.util.Objects;
import retrofit2.Call; import android.net.Uri;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoFragment.BottomSheetListener, BottomSheetIssuesFilterFragment.BottomSheetListener, public class RepoDetailActivity extends BaseActivity implements RepoBottomSheetFragment.BottomSheetListener {
BottomSheetPullRequestFilterFragment.BottomSheetListener, BottomSheetMilestonesFilterFragment.BottomSheetListener {
private TextView textViewBadgeIssue; private TextView textViewBadge;
private TextView textViewBadgePull;
private TextView textViewBadgeRelease;
private FragmentRefreshListener fragmentRefreshListener; @Override
private FragmentRefreshListenerPr fragmentRefreshListenerPr; protected int getLayoutResourceId(){
private FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone; return R.layout.activity_repo_detail;
private FragmentRefreshListenerFiles fragmentRefreshListenerFiles; }
private final Context ctx = this; @Override
private Context appCtx; public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
private TinyDB tinyDB; TinyDB tinyDb = new TinyDB(getApplicationContext());
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoName1 = parts[1];
private String instanceUrl; final String instanceUrl = tinyDb.getString("instanceUrl");
private String loginUid; final String repoOwner = parts[0];
private String instanceToken; final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
private String repositoryOwner; String appLocale = tinyDb.getString("locale");
private String repositoryName; AppUtil.setAppLocale(getResources(), appLocale);
private int tabsCount; Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
@Override setSupportActionBar(toolbar);
protected int getLayoutResourceId() { Objects.requireNonNull(getSupportActionBar()).setTitle(repoName1);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
return R.layout.activity_repo_detail; SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
}
@Override ViewPager mViewPager = findViewById(R.id.container);
public void onCreate(Bundle savedInstanceState) { mViewPager.setAdapter(mSectionsPagerAdapter);
super.onCreate(savedInstanceState); TabLayout tabLayout = findViewById(R.id.tabs);
appCtx = getApplicationContext();
tinyDB = new TinyDB(appCtx); Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
String[] repoNameParts = tinyDB.getString("repoFullName").split("/"); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
repositoryOwner = repoNameParts[0];
repositoryName = repoNameParts[1];
Toolbar toolbar = findViewById(R.id.toolbar); }
else if (tinyDb.getInt("customFontId") == 1) {
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/manroperegular.ttf");
toolbarTitle.setText(repositoryName);
setSupportActionBar(toolbar); }
Objects.requireNonNull(getSupportActionBar()).setTitle(repositoryName); else if (tinyDb.getInt("customFontId") == 2) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
instanceUrl = tinyDB.getString("instanceUrl"); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
loginUid = tinyDB.getString("loginUid");
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
tinyDB.putString("repoIssuesState", "open"); }
tinyDB.putString("repoPrState", "open"); else {
tinyDB.putString("milestoneState", "open");
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
}
toolbarTitle.setTypeface(myTypeface);
toolbarTitle.setText(repoName1);
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildCount = vgTab.getChildCount();
for (int i = 0; i < tabChildCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(myTypeface);
}
}
}
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
if(tinyDb.getBoolean("enableCounterIssueBadge")) {
@SuppressLint("InflateParams") View tabHeader = LayoutInflater.from(this).inflate(R.layout.badge, null);
textViewBadge = tabHeader.findViewById(R.id.counterBadge);
if(!tinyDb.getString("issuesCounter").isEmpty()) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
}
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader);
TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2);
ColorStateList textColor = tabLayout.getTabTextColors();
assert tabOpenIssues != null;
TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeText);
openIssueTabView.setTextColor(textColor);
}
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("enableCounterIssueBadge")) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.repo_dotted_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
finish();
return true;
case R.id.repoMenu:
RepoBottomSheetFragment bottomSheet = new RepoBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onButtonClicked(String text) {
switch (text) {
case "label":
startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class));
break;
case "newIssue":
startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class));
break;
case "newMilestone":
startActivity(new Intent(RepoDetailActivity.this, NewMilestoneActivity.class));
break;
case "addCollaborator":
startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class));
break;
case "createRelease":
startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
break;
case "openWebRepo":
TinyDB tinyDb = new TinyDB(getApplicationContext());
String repoFullName = tinyDb.getString("repoFullName");
String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw");
if(!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol");
}
Uri url = Uri.parse(instanceUrlWithProtocol + "/" + repoFullName);
Intent i = new Intent(Intent.ACTION_VIEW, url);
startActivity(i);
break;
case "newFile":
startActivity(new Intent(RepoDetailActivity.this, NewFileActivity.class));
break;
}
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
Fragment fragment = null;
switch (position) {
case 0: // information
return RepoInfoFragment.newInstance(repoOwner, repoName);
case 1: // files
return FilesFragment.newInstance(repoOwner, repoName);
case 2: // issues
fragment = new IssuesFragment();
break;
case 3: // closed issues
fragment = new ClosedIssuesFragment();
break;
case 4: // pull requests
fragment = new PullRequestsFragment();
break;
case 5: // milestones
return MilestonesFragment.newInstance(repoOwner, repoName);
case 6: // labels
return LabelsFragment.newInstance(repoOwner, repoName);
case 7: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 8: // releases
return ReleasesFragment.newInstance(repoOwner, repoName);
case 9: // collaborators
return CollaboratorsFragment.newInstance(repoOwner, repoName);
}
return fragment;
}
@Override
public int getCount() {
return 10;
}
}
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) {
Call<UserRepositories> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserRepository(token, owner, repo);
call.enqueue(new Callback<UserRepositories>() {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
UserRepositories repoInfo = response.body();
if (response.isSuccessful()) {
if (response.code() == 200) {
assert repoInfo != null;
textViewBadge.setText(repoInfo.getOpen_issues_count());
}
}
else {
Log.e("onFailure", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
Typeface myTypeface; private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
switch(tinyDB.getInt("customFontId", -1)) { Call<JsonElement> call;
case 0: call = RetrofitClient
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf"); .getInstance(instanceUrl, getApplicationContext())
break; .getApiInterface()
.checkRepoStarStatus(instanceToken, owner, repo);
case 2: call.enqueue(new Callback<JsonElement>() {
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default: @Override
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf"); public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
break;
} TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putInt("repositoryStarStatus", response.code());
toolbarTitle.setTypeface(myTypeface); }
TabLayout tabLayout = findViewById(R.id.tabs); @Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
ViewGroup viewGroup = (ViewGroup) tabLayout.getChildAt(0); }
tabsCount = viewGroup.getChildCount();
for(int j = 0; j < tabsCount; j++) { private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
ViewGroup vgTab = (ViewGroup) viewGroup.getChildAt(j); Call<WatchRepository> call;
int tabChildCount = vgTab.getChildCount();
for(int i = 0; i < tabChildCount; i++) { call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.checkRepoWatchStatus(instanceToken, owner, repo);
View tabViewChild = vgTab.getChildAt(i); call.enqueue(new Callback<WatchRepository>() {
if(tabViewChild instanceof TextView) { @Override
((TextView) tabViewChild).setTypeface(myTypeface); public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
}
}
}
// Only show collaborators tab, if you have permission to TinyDB tinyDb = new TinyDB(getApplicationContext());
View collaboratorTab = viewGroup.getChildAt(8);
if(tinyDB.getBoolean("isRepoAdmin") || new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { if(response.code() == 200) {
assert response.body() != null;
if(response.body().getSubscribed()) {
tinyDb.putBoolean("repositoryWatchStatus", true);
}
}
else {
tinyDb.putBoolean("repositoryWatchStatus", false);
}
collaboratorTab.setVisibility(View.VISIBLE); }
}
else {
tabsCount--; @Override
collaboratorTab.setVisibility(View.GONE); public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
} }
ViewPager mViewPager = findViewById(R.id.container);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
if(tinyDB.getBoolean("enableCounterBadges")) {
@SuppressLint("InflateParams") View tabHeader2 = LayoutInflater.from(this).inflate(R.layout.badge_issue, null);
textViewBadgeIssue = tabHeader2.findViewById(R.id.counterBadgeIssue);
@SuppressLint("InflateParams") View tabHeader4 = LayoutInflater.from(this).inflate(R.layout.badge_pull, null);
textViewBadgePull = tabHeader4.findViewById(R.id.counterBadgePull);
@SuppressLint("InflateParams") View tabHeader6 = LayoutInflater.from(this).inflate(R.layout.badge_release, null);
textViewBadgeRelease = tabHeader6.findViewById(R.id.counterBadgeRelease);
textViewBadgeIssue.setVisibility(View.GONE);
textViewBadgePull.setVisibility(View.GONE);
textViewBadgeRelease.setVisibility(View.GONE);
getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
ColorStateList textColor = tabLayout.getTabTextColors();
// Issue count
if(textViewBadgeIssue.getText() != "") {
TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2);
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2);
assert tabOpenIssues != null; // FIXME This should be cleaned up
TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeIssueText);
openIssueTabView.setTextColor(textColor);
}
// Pull request count
if(textViewBadgePull.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(3)).setCustomView(tabHeader4);
TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(3);
assert tabOpenPulls != null; // FIXME This should be cleaned up
TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText);
openPullTabView.setTextColor(textColor);
}
// Release count
if(new Version("1.11.4").less(tinyDB.getString("giteaVersion"))) {
if(textViewBadgeRelease.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5);
assert tabOpenRelease != null; // FIXME This should be cleaned up
TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText);
openReleaseTabView.setTextColor(textColor);
}
}
}
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
}
@Override
public void onResume() {
super.onResume();
if(tinyDB.getBoolean("enableCounterIssueBadge")) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.repo_dotted_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case android.R.id.home:
finish();
return true;
case R.id.repoMenu:
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment();
bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet");
return true;
case R.id.filter:
BottomSheetIssuesFilterFragment filterBottomSheet = new BottomSheetIssuesFilterFragment();
filterBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuBottomSheet");
return true;
case R.id.filterPr:
BottomSheetPullRequestFilterFragment filterPrBottomSheet = new BottomSheetPullRequestFilterFragment();
filterPrBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuPrBottomSheet");
return true;
case R.id.filterMilestone:
BottomSheetMilestonesFilterFragment filterMilestoneBottomSheet = new BottomSheetMilestonesFilterFragment();
filterMilestoneBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuMilestoneBottomSheet");
return true;
case R.id.switchBranches:
chooseBranch();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onButtonClicked(String text) {
switch(text) {
case "label":
startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class));
break;
case "newIssue":
startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class));
break;
case "newMilestone":
startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class));
break;
case "addCollaborator":
startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class));
break;
case "chooseBranch":
chooseBranch();
break;
case "createRelease":
startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
break;
case "openWebRepo":
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(tinyDB.getString("repoHtmlUrl")));
startActivity(i);
break;
case "shareRepo":
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, tinyDB.getString("repoHtmlUrl"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, tinyDB.getString("repoHtmlUrl"));
startActivity(Intent.createChooser(sharingIntent, tinyDB.getString("repoHtmlUrl")));
break;
case "newFile":
startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class));
break;
case "openIssues":
if(getFragmentRefreshListener() != null) {
getFragmentRefreshListener().onRefresh("open");
}
break;
case "closedIssues":
if(getFragmentRefreshListener() != null) {
getFragmentRefreshListener().onRefresh("closed");
}
break;
case "openPr":
if(getFragmentRefreshListenerPr() != null) {
getFragmentRefreshListenerPr().onRefresh("open");
}
break;
case "closedPr":
if(getFragmentRefreshListenerPr() != null) {
getFragmentRefreshListenerPr().onRefresh("closed");
}
break;
case "openMilestone":
if(getFragmentRefreshListenerMilestone() != null) {
getFragmentRefreshListenerMilestone().onRefresh("open");
}
break;
case "closedMilestone":
if(getFragmentRefreshListenerMilestone() != null) {
getFragmentRefreshListenerMilestone().onRefresh("closed");
}
break;
}
}
private void chooseBranch() {
Call<List<Branches>> call = RetrofitClient.getInstance(instanceUrl, ctx)
.getApiInterface()
.getBranches(instanceToken, repositoryOwner, repositoryName);
call.enqueue(new Callback<List<Branches>>() {
@Override
public void onResponse(@NonNull Call<List<Branches>> call, @NonNull Response<List<Branches>> response) {
if(response.code() == 200) {
List<String> branchesList = new ArrayList<>();
int selectedBranch = 0;
assert response.body() != null;
for(int i = 0; i < response.body().size(); i++) {
Branches branches = response.body().get(i);
branchesList.add(branches.getName());
if(tinyDB.getString("repoBranch").equals(branches.getName())) {
selectedBranch = i;
}
}
AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx);
pBuilder.setTitle(R.string.pageTitleChooseBranch);
pBuilder.setSingleChoiceItems(branchesList.toArray(new String[0]), selectedBranch, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
tinyDB.putString("repoBranch", branchesList.get(i));
if(getFragmentRefreshListenerFiles() != null) {
getFragmentRefreshListenerFiles().onRefresh(branchesList.get(i));
}
dialogInterface.dismiss();
}
});
pBuilder.create().show();
}
}
@Override
public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch(position) {
case 0: // Repository details
return RepoInfoFragment.newInstance(repositoryOwner, repositoryName);
case 1: // Files
return FilesFragment.newInstance(repositoryOwner, repositoryName, tinyDB.getString("repoBranch"));
case 2: // Issues
fragment = new IssuesFragment();
break;
case 3: // Pull requests
fragment = new PullRequestsFragment();
break;
case 4: // Branches
return BranchesFragment.newInstance(repositoryOwner, repositoryName);
case 5: // Releases
return ReleasesFragment.newInstance(repositoryOwner, repositoryName);
case 6: // Milestones
fragment = new MilestonesFragment();
break;
case 7: // Labels
return LabelsFragment.newInstance(repositoryOwner, repositoryName);
case 8: // Collaborators
return CollaboratorsFragment.newInstance(repositoryOwner, repositoryName);
}
assert fragment != null;
return fragment;
}
@Override
public int getCount() {
return tabsCount;
}
}
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) {
Call<UserRepositories> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserRepository(token, owner, repo);
call.enqueue(new Callback<UserRepositories>() {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
UserRepositories repoInfo = response.body();
if(response.code() == 200) {
if(tinyDB.getBoolean("enableCounterBadges")) {
assert repoInfo != null;
if(repoInfo.getOpen_issues_count() != null) {
textViewBadgeIssue.setVisibility(View.VISIBLE);
textViewBadgeIssue.setText(repoInfo.getOpen_issues_count());
}
if(repoInfo.getOpen_pull_count() != null) {
textViewBadgePull.setVisibility(View.VISIBLE);
textViewBadgePull.setText(repoInfo.getOpen_pull_count());
}
if(repoInfo.getRelease_count() != null) {
textViewBadgeRelease.setVisibility(View.VISIBLE);
textViewBadgeRelease.setText(repoInfo.getRelease_count());
}
}
}
else {
Log.e("onFailure", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
Call<JsonElement> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoStarStatus(instanceToken, owner, repo);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
tinyDB.putInt("repositoryStarStatus", response.code());
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoWatchStatus(instanceToken, owner, repo);
call.enqueue(new Callback<WatchInfo>() {
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.code() == 200) {
assert response.body() != null;
if(response.body().getSubscribed()) {
tinyDB.putBoolean("repositoryWatchStatus", true);
}
}
else {
tinyDB.putBoolean("repositoryWatchStatus", false);
}
}
@Override
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
// Issues interface
public FragmentRefreshListener getFragmentRefreshListener() { return fragmentRefreshListener; }
public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) { this.fragmentRefreshListener = fragmentRefreshListener; }
public interface FragmentRefreshListener { void onRefresh(String text); }
// Pull request interface
public FragmentRefreshListenerPr getFragmentRefreshListenerPr() { return fragmentRefreshListenerPr; }
public void setFragmentRefreshListenerPr(FragmentRefreshListenerPr fragmentRefreshListenerPr) { this.fragmentRefreshListenerPr = fragmentRefreshListenerPr; }
public interface FragmentRefreshListenerPr { void onRefresh(String text); }
// Milestones interface
public FragmentRefreshListenerMilestone getFragmentRefreshListenerMilestone() { return fragmentRefreshListenerMilestone; }
public void setFragmentRefreshListenerMilestone(FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone) { this.fragmentRefreshListenerMilestone = fragmentRefreshListenerMilestone; }
public interface FragmentRefreshListenerMilestone { void onRefresh(String text); }
// Files interface
public FragmentRefreshListenerFiles getFragmentRefreshListenerFiles() { return fragmentRefreshListenerFiles; }
public void setFragmentRefreshListenerFiles(FragmentRefreshListenerFiles fragmentRefreshListenerFiles) { this.fragmentRefreshListenerFiles = fragmentRefreshListenerFiles; }
public interface FragmentRefreshListenerFiles { void onRefresh(String text); }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,8 +11,8 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import java.util.ArrayList; import java.util.ArrayList;
@ -57,7 +57,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
@NonNull @NonNull
@Override @Override
public AdminGetUsersAdapter.UsersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public AdminGetUsersAdapter.UsersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_admin_users, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.admin_users_list, parent, false);
return new AdminGetUsersAdapter.UsersViewHolder(v); return new AdminGetUsersAdapter.UsersViewHolder(v);
} }
@ -98,7 +98,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
holder.userRole.setVisibility(View.GONE); 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); Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
} }
@Override @Override

View File

@ -1,20 +1,18 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.models.Branches;
import org.mian.gitnex.util.TinyDB;
import java.util.List;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.CommitsActivity;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.Branches;
import java.util.List;
import java.util.Objects;
/** /**
* Author M M Arif * Author M M Arif
@ -29,23 +27,14 @@ public class BranchesAdapter extends RecyclerView.Adapter<BranchesAdapter.Branch
private TextView branchNameTv; private TextView branchNameTv;
private TextView branchCommitAuthor; private TextView branchCommitAuthor;
private TextView branchCommitHash;
private BranchesViewHolder(View itemView) { private BranchesViewHolder(View itemView) {
super(itemView); super(itemView);
branchNameTv = itemView.findViewById(R.id.branchName); branchNameTv = itemView.findViewById(R.id.branchName);
branchCommitAuthor = itemView.findViewById(R.id.branchCommitAuthor); branchCommitAuthor = itemView.findViewById(R.id.branchCommitAuthor);
Button branchCommitHash = itemView.findViewById(R.id.branchCommitHash); 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);
}
});
} }
} }
@ -58,7 +47,7 @@ public class BranchesAdapter extends RecyclerView.Adapter<BranchesAdapter.Branch
@NonNull @NonNull
@Override @Override
public BranchesAdapter.BranchesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public BranchesAdapter.BranchesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_branches, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.branches_list, parent, false);
return new BranchesAdapter.BranchesViewHolder(v); return new BranchesAdapter.BranchesViewHolder(v);
} }
@ -78,6 +67,10 @@ public class BranchesAdapter extends RecyclerView.Adapter<BranchesAdapter.Branch
holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getUsername())); holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getUsername()));
} }
holder.branchCommitHash.setText(
Html.fromHtml("<a href='" + currentItem.getCommit().getUrl() + "'>" + mCtx.getResources().getString(R.string.commitLinkBranchesTab) + "</a> "));
holder.branchCommitHash.setMovementMethod(LinkMovementMethod.getInstance());
} }
@Override @Override

View File

@ -0,0 +1,291 @@
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.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
* Author M M Arif
*/
public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private Context context;
private final int TYPE_LOAD = 0;
private List<Issues> issuesList;
private List<Issues> issuesListFull;
private ClosedIssuesAdapter.OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public ClosedIssuesAdapter(Context context, List<Issues> issuesListMain) {
this.context = context;
this.issuesList = issuesListMain;
issuesListFull = new ArrayList<>(issuesList);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD){
return new ClosedIssuesAdapter.IssuesHolder(inflater.inflate(R.layout.repo_detail_issues_list, parent,false));
}
else {
return new ClosedIssuesAdapter.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) {
((ClosedIssuesAdapter.IssuesHolder)holder).bindData(issuesList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(issuesList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return issuesList.size();
}
class IssuesHolder extends RecyclerView.ViewHolder {
private TextView issueNumber;
private ImageView issueAssigneeAvatar;
private TextView issueTitle;
private TextView issueCreatedTime;
private TextView issueCommentsCount;
private RelativeLayout relativeLayoutFrame;
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);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
relativeLayoutFrame = itemView.findViewById(R.id.relativeLayoutFrame);
issueTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
}
});
frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
}
});
}
@SuppressLint("SetTextI18n")
void bindData(Issues issuesModel){
final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
/*if(issuesModel.getPull_request() != null) {
if (issuesModel.getPull_request().isMerged()) {
relativeLayoutFrame.setVisibility(View.GONE);
relativeLayoutFrame.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
}
}*/
if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
}
if (issuesModel.getUser().getAvatar_url() != null) {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} else {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
}
String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
issueNumber.setText(String.valueOf(issuesModel.getNumber()));
issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
}
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(ClosedIssuesAdapter.OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
@Override
public Filter getFilter() {
return issuesFilter;
}
private Filter issuesFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Issues> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(issuesList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Issues item : issuesList) {
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getBody().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
issuesList.clear();
issuesList.addAll((List) results.values);
notifyDataSetChanged();
}
};
}

View File

@ -8,8 +8,8 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import java.util.List; import java.util.List;
@ -61,7 +61,7 @@ public class CollaboratorsAdapter extends BaseAdapter {
ViewHolder viewHolder = null; ViewHolder viewHolder = null;
if (finalView == null) { if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_collaborators, null); finalView = LayoutInflater.from(mCtx).inflate(R.layout.collaborators_list, null);
viewHolder = new ViewHolder(finalView); viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder); finalView.setTag(viewHolder);
} }
@ -77,7 +77,7 @@ public class CollaboratorsAdapter extends BaseAdapter {
private void initData(ViewHolder viewHolder, int position) { private void initData(ViewHolder viewHolder, int position) {
Collaborators currentItem = collaboratorsList.get(position); 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); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.collaboratorAvatar);
if(!currentItem.getFull_name().equals("")) { if(!currentItem.getFull_name().equals("")) {
viewHolder.collaboratorName.setText(currentItem.getFull_name()); viewHolder.collaboratorName.setText(currentItem.getFull_name());

View File

@ -1,174 +0,0 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
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 androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.Commits;
import java.util.List;
import java.util.Locale;
/**
* Author M M Arif
*/
public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context ctx;
private final int TYPE_LOAD = 0;
private List<Commits> commitsList;
private CommitsAdapter.OnLoadMoreListener loadMoreListener;
private boolean isLoading = false;
private boolean isMoreDataAvailable = true;
public CommitsAdapter(Context ctx, List<Commits> commitsListMain) {
this.ctx = ctx;
this.commitsList = commitsListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(ctx);
if(viewType == TYPE_LOAD) {
return new CommitsHolder(inflater.inflate(R.layout.list_commits, parent, false));
}
else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((CommitsHolder) holder).bindData(commitsList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(commitsList.get(position).getSha() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return commitsList.size();
}
class CommitsHolder extends RecyclerView.ViewHolder {
TextView commitTitle;
TextView commitCommitter;
TextView commitDate;
Button commitHtmlUrl;
CommitsHolder(View itemView) {
super(itemView);
commitTitle = itemView.findViewById(R.id.commitTitleVw);
commitCommitter = itemView.findViewById(R.id.commitCommitterVw);
commitDate = itemView.findViewById(R.id.commitDateVw);
commitHtmlUrl = itemView.findViewById(R.id.commitHtmlUrlVw);
}
@SuppressLint("SetTextI18n")
void bindData(Commits commitsModel) {
final TinyDB tinyDb = new TinyDB(ctx);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
commitTitle.setText(commitsModel.getCommit().getMessage());
commitCommitter.setText(ctx.getString(R.string.commitCommittedBy, commitsModel.getCommit().getCommitter().getName()));
commitDate.setText(TimeHelper.formatTime(commitsModel.getCommit().getCommitter().getDate(), new Locale(locale), timeFormat, ctx));
if(timeFormat.equals("pretty")) {
commitDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(commitsModel.getCommit().getCommitter().getDate()), ctx));
}
commitHtmlUrl.setOnClickListener(v -> ctx.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();
}
}

View File

@ -1,138 +0,0 @@
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.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.database.models.DraftWithRepository;
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 Context mCtx;
class DraftsViewHolder extends RecyclerView.ViewHolder {
private TextView draftText;
private TextView repoInfo;
private TextView repoId;
private TextView draftId;
private TextView issueNumber;
private TextView issueType;
private TextView repoOwner;
private TextView repoName;
private DraftsViewHolder(View itemView) {
super(itemView);
draftText = itemView.findViewById(R.id.draftText);
repoInfo = itemView.findViewById(R.id.repoInfo);
repoId = itemView.findViewById(R.id.repoId);
draftId = itemView.findViewById(R.id.draftId);
issueNumber = itemView.findViewById(R.id.issueNumber);
issueType = itemView.findViewById(R.id.issueType);
repoOwner = itemView.findViewById(R.id.repoOwner);
repoName = itemView.findViewById(R.id.repoName);
ImageView deleteDraft = itemView.findViewById(R.id.deleteDraft);
deleteDraft.setOnClickListener(itemDelete -> {
int getDraftId = Integer.parseInt(draftId.getText().toString());
deleteDraft(getAdapterPosition());
DraftsApi draftsApi = new DraftsApi(mCtx);
draftsApi.deleteSingleDraft(getDraftId);
});
itemView.setOnClickListener(itemEdit -> {
Intent intent = new Intent(mCtx, ReplyToIssueActivity.class);
intent.putExtra("commentBody", draftText.getText().toString());
intent.putExtra("issueNumber", issueNumber.getText().toString());
intent.putExtra("repositoryId", repoId.getText().toString());
intent.putExtra("draftTitle", repoInfo.getText().toString());
TinyDB tinyDb = new TinyDB(mCtx);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putLong("repositoryId", Long.parseLong(repoId.getText().toString()));
//tinyDb.putString("issueType", issueType.getText().toString());
mCtx.startActivity(intent);
});
}
}
public DraftsAdapter(Context mCtx, List<DraftWithRepository> draftsListMain) {
this.mCtx = mCtx;
this.draftsList = draftsListMain;
}
private void deleteDraft(int position) {
draftsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, draftsList.size());
Toasty.info(mCtx, mCtx.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);
holder.repoId.setText(String.valueOf(currentItem.getRepositoryId()));
holder.draftId.setText(String.valueOf(currentItem.getDraftId()));
holder.issueNumber.setText(String.valueOf(currentItem.getIssueId()));
holder.issueType.setText(currentItem.getDraftType());
holder.repoOwner.setText(currentItem.getRepositoryOwner());
holder.repoName.setText(currentItem.getRepositoryName());
holder.draftText.setText(currentItem.getDraftText());
String issueNumber = "<font color='" + mCtx.getResources().getColor(R.color.lightGray) + "'>" + mCtx.getResources().getString(R.string.hash) + currentItem.getIssueId() + "</font>";
holder.repoInfo.setText(Html.fromHtml(issueNumber + " " + currentItem.getRepositoryOwner() + " / " + currentItem.getRepositoryName()));
}
@Override
public int getItemCount() {
return draftsList.size();
}
public void updateList(List<DraftWithRepository> list) {
draftsList = list;
notifyDataSetChanged();
}
}

View File

@ -1,38 +1,32 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.List; import java.util.List;
import retrofit2.Call; import java.util.Objects;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -41,253 +35,183 @@ import retrofit2.Callback;
public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepositoriesAdapter.ReposSearchViewHolder> { public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepositoriesAdapter.ReposSearchViewHolder> {
private List<UserRepositories> searchedReposList; private List<UserRepositories> searchedReposList;
private Context mCtx; private Context mCtx;
public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context mCtx) { public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context mCtx) {
this.mCtx = mCtx;
this.searchedReposList = dataList;
}
static class ReposSearchViewHolder extends RecyclerView.ViewHolder {
this.mCtx = mCtx; private ImageView image;
this.searchedReposList = dataList; private TextView mTextView1;
} private TextView mTextView2;
private TextView fullName;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
static class ReposSearchViewHolder extends RecyclerView.ViewHolder { private ReposSearchViewHolder(View itemView) {
super(itemView);
private ImageView image; mTextView1 = itemView.findViewById(R.id.repoName);
private TextView repoName; mTextView2 = itemView.findViewById(R.id.repoDescription);
private TextView repoDescription; image = itemView.findViewById(R.id.imageAvatar);
private TextView fullName; fullName = itemView.findViewById(R.id.repoFullName);
private CheckBox isRepoAdmin; repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
private ImageView repoPrivatePublic; repoStars = itemView.findViewById(R.id.repoStars);
private TextView repoStars; repoForks = itemView.findViewById(R.id.repoForks);
private TextView repoForks; repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
private TextView repoOpenIssuesCount; ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private ReposSearchViewHolder(View itemView) { itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
super(itemView); Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName);
repoName = itemView.findViewById(R.id.repoName); Intent intent = new Intent(context, RepoDetailActivity.class);
repoDescription = itemView.findViewById(R.id.repoDescription); intent.putExtra("repoFullName", repoFullName.getText().toString());
image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
itemView.setOnClickListener(v -> { TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
context.startActivity(intent);
Context context = v.getContext(); }
TextView repoFullName = v.findViewById(R.id.repoFullName); });
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", repoFullName.getText().toString());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString());
String[] parts = fullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
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");
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchInfo watch = new WatchInfo();
Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchInfo>() {
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
}
}
@Override
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(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(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
});
}
}
@NonNull
@Override
public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
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) {
UserRepositories currentItem = searchedReposList.get(position);
holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
if(currentItem.getAvatar_url() != null) {
if(!currentItem.getAvatar_url().equals("")) {
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);
}
else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
holder.repoName.setText(currentItem.getName());
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
}
holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
}
else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return searchedReposList.size();
}
reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
PopupMenu popupMenu = new PopupMenu(context, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
Objects.requireNonNull(menuHelper).getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
} catch (Exception e) {
popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.repoStargazers:
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
break;
case R.id.repoWatchers:
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
break;
case R.id.repoOpenInBrowser:
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
break;
}
return false;
}
});
popupMenu.show();
}
});
}
}
@NonNull
@Override
public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repos_list, parent, false);
return new ExploreRepositoriesAdapter.ReposSearchViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull final ExploreRepositoriesAdapter.ReposSearchViewHolder holder, int position) {
final UserRepositories currentItem = searchedReposList.get(position);
holder.mTextView2.setVisibility(View.GONE);
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE);
holder.mTextView2.setText(currentItem.getDescription());
}
holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
}
else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
}
@Override
public int getItemCount() {
return searchedReposList.size();
}
} }

View File

@ -11,7 +11,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Files; import org.mian.gitnex.models.Files;
import java.util.ArrayList; import java.util.ArrayList;
@ -39,7 +38,6 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
private ImageView fileTypeImage; private ImageView fileTypeImage;
private TextView fileName; private TextView fileName;
private TextView fileType; private TextView fileType;
private TextView fileInfo;
private FilesViewHolder(View itemView) { private FilesViewHolder(View itemView) {
@ -47,24 +45,26 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
fileName = itemView.findViewById(R.id.fileName); fileName = itemView.findViewById(R.id.fileName);
fileTypeImage = itemView.findViewById(R.id.fileImage); fileTypeImage = itemView.findViewById(R.id.fileImage);
fileType = itemView.findViewById(R.id.fileType); fileType = itemView.findViewById(R.id.fileType);
fileInfo = itemView.findViewById(R.id.fileInfo);
//ImageView filesDropdownMenu = itemView.findViewById(R.id.filesDropdownMenu); //ImageView filesDropdownMenu = itemView.findViewById(R.id.filesDropdownMenu);
fileName.setOnClickListener(v -> { fileName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
if(fileType.getText().toString().equals("file")) { if(fileType.getText().toString().equals("file")) {
filesListener.onClickFile(fileName.getText().toString()); filesListener.onClickFile(fileName.getText().toString());
} }
else if(fileType.getText().toString().equals("dir")) { else if(fileType.getText().toString().equals("dir")) {
filesListener.onClickDir(fileName.getText().toString()); filesListener.onClickDir(fileName.getText().toString());
} }
else { else {
Toasty.info(context, context.getString(R.string.filesGenericError)); Toasty.info(context, context.getString(R.string.filesGenericError));
} }
}
}); });
@ -144,7 +144,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
@NonNull @NonNull
@Override @Override
public FilesAdapter.FilesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public FilesAdapter.FilesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_files, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.files_list, parent, false);
return new FilesAdapter.FilesViewHolder(v); return new FilesAdapter.FilesViewHolder(v);
} }
@ -157,16 +157,13 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
holder.fileName.setText(currentItem.getName()); holder.fileName.setText(currentItem.getName());
if(currentItem.getType().equals("file")) { if(currentItem.getType().equals("file")) {
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_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")) { else if(currentItem.getType().equals("dir")) {
holder.fileInfo.setVisibility(View.GONE); holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_folder_24));
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_directory));
} }
else { else {
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_question)); holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_question_mark_24));
} }
} }

View File

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

View File

@ -1,40 +1,41 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.text.Spanned; import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import com.squareup.picasso.Picasso;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.gson.JsonElement;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity; import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.models.IssueComments;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.ClickListener;
import org.ocpsoft.prettytime.PrettyTime;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin; import io.noties.markwon.core.CorePlugin;
@ -43,6 +44,7 @@ import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.AsyncDrawable;
import io.noties.markwon.image.DefaultMediaDecoder; import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem; import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.ImagesPlugin;
@ -50,8 +52,6 @@ import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder; import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder; import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -59,340 +59,232 @@ import retrofit2.Callback;
public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> { public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> {
private List<IssueComments> issuesComments; private List<IssueComments> issuesComments;
private Context mCtx; private Context mCtx;
public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) { static class IssueCommentViewHolder extends RecyclerView.ViewHolder {
this.mCtx = mCtx; private TextView issueNumber;
this.issuesComments = issuesCommentsMain; private TextView commendId;
private ImageView issueCommenterAvatar;
} private TextView issueComment;
private TextView issueCommentDate;
class IssueCommentViewHolder extends RecyclerView.ViewHolder { private ImageView commentsOptionsMenu;
private TextView commendBodyRaw;
private TextView issueNumber; private TextView commentModified;
private TextView commendId;
private ImageView issueCommenterAvatar; private IssueCommentViewHolder(View itemView) {
private TextView issueComment; super(itemView);
private TextView issueCommentDate;
private TextView commendBodyRaw; issueNumber = itemView.findViewById(R.id.issueNumber);
private TextView commentModified; commendId = itemView.findViewById(R.id.commendId);
private TextView commenterUsername; issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar);
private TextView htmlUrl; issueComment = itemView.findViewById(R.id.issueComment);
issueCommentDate = itemView.findViewById(R.id.issueCommentDate);
private IssueCommentViewHolder(View itemView) { commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu);
commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw);
super(itemView); commentModified = itemView.findViewById(R.id.commentModified);
issueNumber = itemView.findViewById(R.id.issueNumber); commentsOptionsMenu.setOnClickListener(new View.OnClickListener() {
commendId = itemView.findViewById(R.id.commendId); @Override
issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar); public void onClick(View v) {
issueComment = itemView.findViewById(R.id.issueComment);
issueCommentDate = itemView.findViewById(R.id.issueCommentDate); final Context context = v.getContext();
ImageView commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu); //Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw);
commentModified = itemView.findViewById(R.id.commentModified); PopupMenu popupMenu = new PopupMenu(context, v);
commenterUsername = itemView.findViewById(R.id.commenterUsername); popupMenu.inflate(R.menu.issue_comment_menu);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
Object menuHelper;
commentsOptionsMenu.setOnClickListener(v -> { Class[] argTypes;
try {
final Context ctx = v.getContext();
final TinyDB tinyDb = new TinyDB(ctx); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
final String loginUid = tinyDb.getString("loginUid"); fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
@SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_issue_comments, null); argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit); argTypes).invoke(menuHelper, true);
TextView commentShare = view.findViewById(R.id.issueCommentShare);
TextView commentMenuQuote = view.findViewById(R.id.commentMenuQuote); } catch (Exception e) {
TextView commentMenuCopy = view.findViewById(R.id.commentMenuCopy);
TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete); popupMenu.show();
return;
if(!loginUid.contentEquals(commenterUsername.getText())) {
commentMenuEdit.setVisibility(View.GONE); }
commentMenuDelete.setVisibility(View.GONE);
} popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
if(issueComment.getText().toString().isEmpty()) { public boolean onMenuItemClick(MenuItem item) {
commentMenuCopy.setVisibility(View.GONE); switch (item.getItemId()) {
} case R.id.commentMenuEdit:
BottomSheetDialog dialog = new BottomSheetDialog(ctx); Intent intent = new Intent(context, ReplyToIssueActivity.class);
dialog.setContentView(view); intent.putExtra("commentId", commendId.getText());
dialog.show(); intent.putExtra("commentAction", "edit");
intent.putExtra("commentBody", commendBodyRaw.getText());
commentMenuEdit.setOnClickListener(ediComment -> { context.startActivity(intent);
break;
Intent intent = new Intent(ctx, ReplyToIssueActivity.class);
intent.putExtra("commentId", commendId.getText()); case R.id.commentMenuDelete:
intent.putExtra("commentAction", "edit");
intent.putExtra("commentBody", commendBodyRaw.getText()); break;
ctx.startActivity(intent);
dialog.dismiss(); }
return false;
}); }
});
commentShare.setOnClickListener(ediComment -> {
popupMenu.show();
// get comment Url
CharSequence commentUrl = htmlUrl.getText(); }
});
// share issue comment
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); }
sharingIntent.setType("text/plain"); }
String intentHeader = tinyDb.getString("issueNumber") + ctx.getResources().getString(R.string.hash) + "issuecomment-" + commendId.getText() + " " + tinyDb.getString("issueTitle");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, intentHeader); public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, commentUrl); this.mCtx = mCtx;
ctx.startActivity(Intent.createChooser(sharingIntent, intentHeader)); this.issuesComments = issuesCommentsMain;
}
dialog.dismiss();
@NonNull
}); @Override
public IssueCommentsAdapter.IssueCommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
commentMenuQuote.setOnClickListener(v1 -> { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.issue_comments, parent, false);
return new IssueCommentsAdapter.IssueCommentViewHolder(v);
StringBuilder stringBuilder = new StringBuilder(); }
String commenterName = commenterUsername.getText().toString();
@SuppressLint("SetTextI18n")
if(!commenterName.equals(tinyDb.getString("userLogin"))) { @Override
public void onBindViewHolder(@NonNull IssueCommentsAdapter.IssueCommentViewHolder holder, int position) {
stringBuilder.append("@").append(commenterName).append("\n\n");
} final TinyDB tinyDb = new TinyDB(mCtx);
final String locale = tinyDb.getString("locale");
String[] lines = commendBodyRaw.getText().toString().split("\\R"); final String timeFormat = tinyDb.getString("dateFormat");
final String loginUid = tinyDb.getString("loginUid");
for(String line : lines) {
IssueComments currentItem = issuesComments.get(position);
stringBuilder.append(">").append(line).append("\n");
} if(!loginUid.equals(currentItem.getUser().getUsername())) {
holder.commentsOptionsMenu.setVisibility(View.INVISIBLE);
stringBuilder.append("\n"); }
holder.commendId.setText(String.valueOf(currentItem.getId()));
Intent intent = new Intent(ctx, ReplyToIssueActivity.class); holder.commendBodyRaw.setText(currentItem.getBody());
intent.putExtra("commentBody", stringBuilder.toString());
intent.putExtra("cursorToEnd", true); if (!currentItem.getUser().getFull_name().equals("")) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getFull_name(), mCtx));
} else {
dialog.dismiss(); holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getLogin(), mCtx));
ctx.startActivity(intent); }
}); if (currentItem.getUser().getAvatar_url() != null) {
Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);
commentMenuCopy.setOnClickListener(view1 -> { } else {
Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE); }
assert clipboard != null;
String cleanIssueComments = currentItem.getBody().trim();
ClipData clip = ClipData.newPlainText("Comment on issue #" + issueNumber.getText().toString(), issueComment.getText().toString());
clipboard.setPrimaryClip(clip); final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create())
dialog.dismiss(); .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
Toasty.info(ctx, ctx.getString(R.string.copyIssueCommentToastMsg)); @Override
public void configureImages(@NonNull ImagesPlugin plugin) {
}); plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
commentMenuDelete.setOnClickListener(deleteComment -> { @Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
deleteIssueComment(ctx, Integer.parseInt(commendId.getText().toString()), getAdapterPosition());
dialog.dismiss(); 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);
}
private void updateAdapter(int position) {
@NonNull
issuesComments.remove(position); @Override
notifyItemRemoved(position); public Collection<String> supportedSchemes() {
notifyItemRangeChanged(position, issuesComments.size()); return Collections.singleton("drawable");
}
} });
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
private void deleteIssueComment(final Context ctx, final int commentId, int position) { @Nullable
@Override
final TinyDB tinyDb = new TinyDB(ctx); public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
final String instanceUrl = tinyDb.getString("instanceUrl"); return null;
final String loginUid = tinyDb.getString("loginUid"); }
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); });
String[] repoFullName = tinyDb.getString("repoFullName").split("/"); plugin.addMediaDecoder(GifMediaDecoder.create(false));
if (repoFullName.length != 2) { plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
return; plugin.addMediaDecoder(SvgMediaDecoder.create());
} plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
final String repoOwner = repoFullName[0]; plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
final String repoName = repoFullName[1]; }
}))
Call<JsonElement> call; .usePlugin(new AbstractMarkwonPlugin() {
@Override
call = RetrofitClient public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
.getInstance(instanceUrl, ctx) builder
.getApiInterface() .codeTextColor(tinyDb.getInt("codeBlockColor"))
.deleteComment(instanceToken, repoOwner, repoName, commentId); .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue));
call.enqueue(new Callback<JsonElement>() { }
})
@Override .usePlugin(TablePlugin.create(mCtx))
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) { .usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create())
if(response.code() == 204) { .usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
updateAdapter(position); .build();
Toasty.info(ctx, ctx.getResources().getString(R.string.deleteCommentSuccess));
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
} markwon.setParsedMarkdown(holder.issueComment, UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments));
else if(response.code() == 401) {
String edited;
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), if(!currentItem.getUpdated_at().equals(currentItem.getCreated_at())) {
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), edited = mCtx.getResources().getString(R.string.colorfulBulletSpan) + mCtx.getResources().getString(R.string.modifiedText);
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); holder.commentModified.setVisibility(View.VISIBLE);
holder.commentModified.setText(edited);
} holder.commentModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), mCtx));
else if(response.code() == 403) { }
else {
Toasty.info(ctx, ctx.getString(R.string.authorizeError)); holder.commentModified.setVisibility(View.INVISIBLE);
}
}
else if(response.code() == 404) { switch (timeFormat) {
case "pretty": {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound)); PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(currentItem.getCreated_at());
} holder.issueCommentDate.setText(createdTime);
else { holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx));
break;
Toasty.info(ctx, ctx.getString(R.string.genericError)); }
case "normal": {
} DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(currentItem.getCreated_at());
} holder.issueCommentDate.setText(createdTime);
break;
@Override }
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
} break;
}
}); }
} }
@NonNull @Override
@Override public int getItemCount() {
public IssueCommentsAdapter.IssueCommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return issuesComments.size();
}
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");
IssueComments currentItem = issuesComments.get(position);
holder.htmlUrl.setText(currentItem.getHtml_url());
holder.commenterUsername.setText(currentItem.getUser().getUsername());
holder.commendId.setText(String.valueOf(currentItem.getId()));
holder.commendBodyRaw.setText(currentItem.getBody());
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(mCtx).get().load(currentItem.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);
String cleanIssueComments = currentItem.getBody().trim();
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)).usePlugin(CorePlugin.create()).usePlugin(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(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 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);
}
holder.issueCommentDate.setText(TimeHelper.formatTime(currentItem.getCreated_at(), new Locale(locale), timeFormat, mCtx));
if(timeFormat.equals("pretty")) {
holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx));
}
}
@Override
public int getItemCount() {
return issuesComments.size();
}
} }

View File

@ -7,230 +7,285 @@ import android.text.Html;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import com.squareup.picasso.Picasso;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime; import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private Context context; private Context context;
private final int TYPE_LOAD = 0; private final int TYPE_LOAD = 0;
private List<Issues> issuesList; private List<Issues> issuesList;
private OnLoadMoreListener loadMoreListener; private List<Issues> issuesListFull;
private boolean isLoading = false, isMoreDataAvailable = true; private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public IssuesAdapter(Context context, List<Issues> issuesListMain) { public IssuesAdapter(Context context, List<Issues> issuesListMain) {
this.context = context; this.context = context;
this.issuesList = issuesListMain; this.issuesList = issuesListMain;
issuesListFull = new ArrayList<>(issuesList);
} }
@NonNull @NonNull
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context); LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) { if(viewType == TYPE_LOAD){
return new IssuesHolder(inflater.inflate(R.layout.list_issues, parent, false)); return new IssuesHolder(inflater.inflate(R.layout.repo_detail_issues_list, parent,false));
} }
else { else {
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false)); return new LoadHolder(inflater.inflate(R.layout.row_load,parent,false));
} }
} }
@Override @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) { if(position >= getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null) {
isLoading = true; isLoading = true;
loadMoreListener.onLoadMore(); loadMoreListener.onLoadMore();
} }
if(getItemViewType(position) == TYPE_LOAD) { if(getItemViewType(position) == TYPE_LOAD) {
((IssuesHolder) holder).bindData(issuesList.get(position)); ((IssuesHolder)holder).bindData(issuesList.get(position));
} }
} }
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
if(issuesList.get(position).getTitle() != null) { if(issuesList.get(position).getTitle() != null) {
return TYPE_LOAD; return TYPE_LOAD;
} }
else { else {
return 1; return 1;
} }
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return issuesList.size(); return issuesList.size();
} }
class IssuesHolder extends RecyclerView.ViewHolder { class IssuesHolder extends RecyclerView.ViewHolder {
private TextView issueNumber; private TextView issueNumber;
private ImageView issueAssigneeAvatar; private ImageView issueAssigneeAvatar;
private TextView issueTitle; private TextView issueTitle;
private TextView issueCreatedTime; private TextView issueCreatedTime;
private TextView issueCommentsCount; private TextView issueCommentsCount;
private RelativeLayout relativeLayoutFrame;
IssuesHolder(View itemView) { IssuesHolder(View itemView) {
super(itemView); super(itemView);
issueNumber = itemView.findViewById(R.id.issueNumber); issueNumber = itemView.findViewById(R.id.issueNumber);
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle); issueTitle = itemView.findViewById(R.id.issueTitle);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount); issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount); LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime); issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
relativeLayoutFrame = itemView.findViewById(R.id.relativeLayoutFrame);
issueTitle.setOnClickListener(v -> { issueTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
Intent intent = new Intent(context, IssueDetailActivity.class); Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText()); intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString()); tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "Issue"); tinyDb.putString("issueType", "issue");
context.startActivity(intent); context.startActivity(intent);
}); }
frameCommentsCount.setOnClickListener(v -> { });
frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
Intent intent = new Intent(context, IssueDetailActivity.class); Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText()); intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString()); tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "Issue"); tinyDb.putString("issueType", "issue");
context.startActivity(intent); context.startActivity(intent);
}); }
});
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
void bindData(Issues issuesModel) { void bindData(Issues issuesModel){
final TinyDB tinyDb = new TinyDB(context); final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale"); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
if(!issuesModel.getUser().getFull_name().equals("")) { /*if(issuesModel.getPull_request() != null) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context)); if (!issuesModel.getPull_request().isMerged()) {
} relativeLayoutFrame.setVisibility(View.GONE);
else { relativeLayoutFrame.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context)); }
} }*/
PicassoService.getInstance(context).get().load(issuesModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar); if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
}
String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>"; if (issuesModel.getUser().getAvatar_url() != null) {
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle())); Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} else {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
}
issueNumber.setText(String.valueOf(issuesModel.getNumber())); String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueCommentsCount.setText(String.valueOf(issuesModel.getComments())); issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
switch(timeFormat) { issueNumber.setText(String.valueOf(issuesModel.getNumber()));
case "pretty": { issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
}
} switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
}
} }
static class LoadHolder extends RecyclerView.ViewHolder { }
LoadHolder(View itemView) { static class LoadHolder extends RecyclerView.ViewHolder {
super(itemView); LoadHolder(View itemView) {
} super(itemView);
}
} }
public void setMoreDataAvailable(boolean moreDataAvailable) { public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable; isMoreDataAvailable = moreDataAvailable;
} }
public void notifyDataChanged() { public void notifyDataChanged() {
notifyDataSetChanged(); notifyDataSetChanged();
isLoading = false; isLoading = false;
} }
public interface OnLoadMoreListener { public interface OnLoadMoreListener {
void onLoadMore(); void onLoadMore();
} }
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) { public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener; this.loadMoreListener = loadMoreListener;
} }
public void updateList(List<Issues> list) { @Override
public Filter getFilter() {
return issuesFilter;
}
issuesList = list; private Filter issuesFilter = new Filter() {
notifyDataSetChanged(); @Override
} protected FilterResults performFiltering(CharSequence constraint) {
List<Issues> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(issuesList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Issues item : issuesList) {
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getBody().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
issuesList.clear();
issuesList.addAll((List) results.values);
notifyDataSetChanged();
}
};
} }

View File

@ -1,27 +1,29 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Color; import android.graphics.Color;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import com.amulyakhare.textdrawable.TextDrawable;
import androidx.cardview.widget.CardView;
import androidx.core.widget.ImageViewCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.CreateLabelActivity; import org.mian.gitnex.activities.CreateLabelActivity;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.ColorInverter; import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.models.Labels; import org.mian.gitnex.models.Labels;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
/** /**
* Author M M Arif * Author M M Arif
@ -38,61 +40,76 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
private TextView labelTitle; private TextView labelTitle;
private TextView labelId; private TextView labelId;
private TextView labelColor; private TextView labelColor;
private ImageView labelsView;
private CardView labelView;
private ImageView labelIcon;
private TextView labelName;
private LabelsViewHolder(View itemView) { private LabelsViewHolder(View itemView) {
super(itemView); super(itemView);
labelView = itemView.findViewById(R.id.labelView); labelsView = itemView.findViewById(R.id.labelsView);
labelIcon = itemView.findViewById(R.id.labelIcon);
labelName = itemView.findViewById(R.id.labelName);
ImageView labelsOptionsMenu = itemView.findViewById(R.id.labelsOptionsMenu); ImageView labelsOptionsMenu = itemView.findViewById(R.id.labelsOptionsMenu);
labelTitle = itemView.findViewById(R.id.labelTitle); labelTitle = itemView.findViewById(R.id.labelTitle);
labelId = itemView.findViewById(R.id.labelId); labelId = itemView.findViewById(R.id.labelId);
labelColor = itemView.findViewById(R.id.labelColor); labelColor = itemView.findViewById(R.id.labelColor);
labelsOptionsMenu.setOnClickListener(v -> { labelsOptionsMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext(); final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
@SuppressLint("InflateParams") PopupMenu popupMenu = new PopupMenu(context, v);
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_labels_in_list, null); popupMenu.inflate(R.menu.labels_menu);
TextView labelMenuEdit = view.findViewById(R.id.labelMenuEdit); Object menuHelper;
TextView labelMenuDelete = view.findViewById(R.id.labelMenuDelete); Class[] argTypes;
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); try {
bottomSheetHeader.setText(labelTitle.getText()); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
BottomSheetDialog dialog = new BottomSheetDialog(context); fMenuHelper.setAccessible(true);
dialog.setContentView(view); menuHelper = fMenuHelper.get(popupMenu);
dialog.show(); argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
labelMenuEdit.setOnClickListener(editLabel -> { } catch (Exception e) {
Intent intent = new Intent(context, CreateLabelActivity.class); popupMenu.show();
intent.putExtra("labelId", labelId.getText()); return;
intent.putExtra("labelTitle", labelTitle.getText());
intent.putExtra("labelColor", labelColor.getText());
intent.putExtra("labelAction", "edit");
context.startActivity(intent);
dialog.dismiss();
}); }
labelMenuDelete.setOnClickListener(deleteLabel -> { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.labelMenuEdit:
AlertDialogs.labelDeleteDialog(context, labelTitle.getText().toString(), labelId.getText().toString(), Intent intent = new Intent(context, CreateLabelActivity.class);
context.getResources().getString(R.string.labelDeleteTitle), intent.putExtra("labelId", labelId.getText());
context.getResources().getString(R.string.labelDeleteMessage), intent.putExtra("labelTitle", labelTitle.getText());
context.getResources().getString(R.string.labelDeletePositiveButton), intent.putExtra("labelColor", labelColor.getText());
context.getResources().getString(R.string.labelDeleteNegativeButton)); intent.putExtra("labelAction", "edit");
dialog.dismiss(); context.startActivity(intent);
break;
}); case R.id.labelMenuDelete:
AlertDialogs.labelDeleteDialog(context, labelTitle.getText().toString(), labelId.getText().toString(),
context.getResources().getString(R.string.labelDeleteTitle),
context.getResources().getString(R.string.labelDeleteMessage),
context.getResources().getString(R.string.labelDeletePositiveButton),
context.getResources().getString(R.string.labelDeleteNegativeButton));
break;
}
return false;
}
});
popupMenu.show();
}
}); });
} }
@ -106,7 +123,7 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
@NonNull @NonNull
@Override @Override
public LabelsAdapter.LabelsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public LabelsAdapter.LabelsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_labels, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.labels_list, parent, false);
return new LabelsAdapter.LabelsViewHolder(v); return new LabelsAdapter.LabelsViewHolder(v);
} }
@ -114,6 +131,7 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
public void onBindViewHolder(@NonNull LabelsAdapter.LabelsViewHolder holder, int position) { public void onBindViewHolder(@NonNull LabelsAdapter.LabelsViewHolder holder, int position) {
Labels currentItem = labelsList.get(position); Labels currentItem = labelsList.get(position);
int width = 33;
holder.labelTitle.setText(currentItem.getName()); holder.labelTitle.setText(currentItem.getName());
holder.labelId.setText(String.valueOf(currentItem.getId())); holder.labelId.setText(String.valueOf(currentItem.getId()));
@ -121,15 +139,32 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
String labelColor = currentItem.getColor(); String labelColor = currentItem.getColor();
String labelName = currentItem.getName(); String labelName = currentItem.getName();
int color = Color.parseColor("#" + labelColor); int color = Color.parseColor("#" + labelColor);
int contrastColor = new ColorInverter().getContrastColor(color);
ImageViewCompat.setImageTintList(holder.labelIcon, ColorStateList.valueOf(contrastColor)); TextDrawable drawable = TextDrawable.builder()
.beginConfig()
//.useFont(Typeface.DEFAULT)
.bold()
.textColor(new ColorInverter().getContrastColor(color))
.fontSize(36)
.width(LabelWidthCalculator.customWidth(getMaxLabelLength()))
.height(60)
.endConfig()
.buildRoundRect(labelName, color, 8);
holder.labelsView.setImageDrawable(drawable);
holder.labelName.setTextColor(contrastColor); }
holder.labelName.setText(labelName);
holder.labelView.setCardBackgroundColor(color); private int getMaxLabelLength() {
for(int i = 0; i < labelsList.size(); i++) {
Labels labelItem = labelsList.get(i);
labelsArray.add(labelItem.getName().length());
}
return Collections.max(labelsArray);
} }
@ -138,4 +173,4 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
return labelsList.size(); return labelsList.size();
} }
} }

View File

@ -10,8 +10,8 @@ import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import java.util.ArrayList; import java.util.ArrayList;
@ -67,7 +67,7 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
MembersByOrgAdapter.ViewHolder viewHolder = null; MembersByOrgAdapter.ViewHolder viewHolder = null;
if (finalView == null) { if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_members_by_org, null); finalView = LayoutInflater.from(mCtx).inflate(R.layout.members_by_org_list, null);
viewHolder = new MembersByOrgAdapter.ViewHolder(finalView); viewHolder = new MembersByOrgAdapter.ViewHolder(finalView);
finalView.setTag(viewHolder); finalView.setTag(viewHolder);
} }
@ -83,7 +83,7 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
private void initData(MembersByOrgAdapter.ViewHolder viewHolder, int position) { private void initData(MembersByOrgAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = membersList.get(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); Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(viewHolder.memberAvatar);
if(!currentItem.getFullname().equals("")) { if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname()); viewHolder.memberName.setText(currentItem.getFullname());

View File

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

View File

@ -11,14 +11,14 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; 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.annotation.NonNull;
import androidx.appcompat.widget.AppCompatCheckBox; import androidx.appcompat.widget.AppCompatCheckBox;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.models.MultiSelectModel;
import java.util.List;
/** /**
* Author com.github.abumoallim, modified by M M Arif * Author com.github.abumoallim, modified by M M Arif
@ -26,11 +26,11 @@ import java.util.List;
public class MutliSelectAdapter extends RecyclerView.Adapter<MutliSelectAdapter.MultiSelectDialogViewHolder> { public class MutliSelectAdapter extends RecyclerView.Adapter<MutliSelectAdapter.MultiSelectDialogViewHolder> {
private List<MultiSelectModel> mDataSet; private ArrayList<MultiSelectModel> mDataSet;
private String mSearchQuery = ""; private String mSearchQuery = "";
private Context mContext; private Context mContext;
public MutliSelectAdapter(List<MultiSelectModel> dataSet, Context context) { public MutliSelectAdapter(ArrayList<MultiSelectModel> dataSet, Context context) {
this.mDataSet = dataSet; this.mDataSet = dataSet;
this.mContext = context; this.mContext = context;
} }
@ -163,7 +163,7 @@ public class MutliSelectAdapter extends RecyclerView.Adapter<MutliSelectAdapter.
return mDataSet.size(); return mDataSet.size();
} }
public void setData(List<MultiSelectModel> data, String query, MutliSelectAdapter mutliSelectAdapter) { public void setData(ArrayList<MultiSelectModel> data, String query, MutliSelectAdapter mutliSelectAdapter) {
this.mDataSet = data; this.mDataSet = data;
this.mSearchQuery = query; this.mSearchQuery = query;
@ -187,4 +187,4 @@ public class MutliSelectAdapter extends RecyclerView.Adapter<MutliSelectAdapter.
} }
} }
} }

View File

@ -1,41 +1,34 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import retrofit2.Call; import androidx.annotation.NonNull;
import retrofit2.Callback; import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
/** /**
* Author M M Arif * Author M M Arif
@ -43,297 +36,221 @@ import retrofit2.Callback;
public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.MyReposViewHolder> implements Filterable { public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.MyReposViewHolder> implements Filterable {
private List<UserRepositories> reposList; private List<UserRepositories> reposList;
private Context mCtx; private Context mCtx;
private List<UserRepositories> reposListFull; private List<UserRepositories> reposListFull;
static class MyReposViewHolder extends RecyclerView.ViewHolder { static class MyReposViewHolder extends RecyclerView.ViewHolder {
private ImageView imageAvatar; private ImageView imageMy;
private TextView repoName; private TextView mTextView1My;
private TextView repoDescription; private TextView mTextView2My;
private TextView repoFullName; private TextView fullNameMy;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublicMy;
private TextView repoStars; private TextView repoStarsMy;
private TextView repoForks; private TextView repoForksMy;
private TextView repoOpenIssuesCount; private TextView repoOpenIssuesCountMy;
private TextView repoType; private TextView repoType;
private CheckBox isRepoAdmin;
private LinearLayout archiveRepo; private MyReposViewHolder(View itemView) {
private TextView repoBranch; super(itemView);
mTextView1My = itemView.findViewById(R.id.repoNameMy);
private MyReposViewHolder(View itemView) { mTextView2My = itemView.findViewById(R.id.repoDescriptionMy);
imageMy = itemView.findViewById(R.id.imageAvatarMy);
super(itemView); fullNameMy = itemView.findViewById(R.id.repoFullNameMy);
repoName = itemView.findViewById(R.id.repoName); repoPrivatePublicMy = itemView.findViewById(R.id.imageRepoTypeMy);
repoDescription = itemView.findViewById(R.id.repoDescription); repoStarsMy = itemView.findViewById(R.id.repoStarsMy);
imageAvatar = itemView.findViewById(R.id.imageAvatar); repoForksMy = itemView.findViewById(R.id.repoForksMy);
repoFullName = itemView.findViewById(R.id.repoFullName); repoOpenIssuesCountMy = itemView.findViewById(R.id.repoOpenIssuesCountMy);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoStars = itemView.findViewById(R.id.repoStars); repoType = itemView.findViewById(R.id.repoType);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount); itemView.setOnClickListener(new View.OnClickListener() {
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); @Override
repoType = itemView.findViewById(R.id.repoType); public void onClick(View v) {
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame); Context context = v.getContext();
repoBranch = itemView.findViewById(R.id.repoBranch);
Intent intent = new Intent(context, RepoDetailActivity.class);
itemView.setOnClickListener(v -> { intent.putExtra("repoFullName", fullNameMy.getText().toString());
Context context = v.getContext(); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullNameMy.getText().toString());
Intent intent = new Intent(context, RepoDetailActivity.class); tinyDb.putString("repoType", repoType.getText().toString());
intent.putExtra("repoFullName", repoFullName.getText().toString()); tinyDb.putBoolean("resumeIssues", true);
context.startActivity(intent);
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString()); }
tinyDb.putString("repoType", repoType.getText().toString()); });
//tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked()); reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
tinyDb.putString("repoBranch", repoBranch.getText().toString()); @Override
public void onClick(View v) {
String[] parts = repoFullName.getText().toString().split("/");
final String repoOwner = parts[0]; final Context context = v.getContext();
final String repoName = parts[1]; //Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId"); PopupMenu popupMenu = new PopupMenu(context, v);
RepositoriesApi repositoryData = new RepositoriesApi(context); popupMenu.inflate(R.menu.repo_dotted_list_menu);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId); Object menuHelper;
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName); Class[] argTypes;
try {
if(count == 0) {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName); fMenuHelper.setAccessible(true);
tinyDb.putLong("repositoryId", id); menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
} menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
else { argTypes).invoke(menuHelper, true);
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName); } catch (Exception e) {
tinyDb.putLong("repositoryId", data.getRepositoryId());
popupMenu.show();
} return;
//store if user is watching this repo }
{
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
final String instanceUrl = tinyDb.getString("instanceUrl"); @Override
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
WatchInfo watch = new WatchInfo(); case R.id.repoStargazers:
Call<WatchInfo> call; Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullNameMy.getText());
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); context.startActivity(intent);
break;
call.enqueue(new Callback<WatchInfo>() {
case R.id.repoWatchers:
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) { Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullNameMy.getText());
if(response.isSuccessful()) { context.startActivity(intentW);
break;
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed()); case R.id.repoOpenInBrowser:
} Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
else { intentOpenInBrowser.putExtra("repoFullNameBrowser", fullNameMy.getText());
context.startActivity(intentOpenInBrowser);
tinyDb.putBoolean("repoWatch", false); break;
if(response.code() != 404) { }
return false;
Toasty.info(context, context.getString(R.string.genericApiStatusError)); }
});
}
popupMenu.show();
}
}
} });
@Override }
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) { }
tinyDb.putBoolean("repoWatch", false); public MyReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
Toasty.info(context, context.getString(R.string.genericApiStatusError)); this.mCtx = mCtx;
this.reposList = reposListMain;
} reposListFull = new ArrayList<>(reposList);
}); }
} @NonNull
@Override
context.startActivity(intent); public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_repos_list, parent, false);
}); return new MyReposListAdapter.MyReposViewHolder(v);
}
reposDropdownMenu.setOnClickListener(v -> {
@Override
final Context context = v.getContext(); public void onBindViewHolder(@NonNull MyReposListAdapter.MyReposViewHolder holder, int position) {
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null); UserRepositories currentItem = reposList.get(position);
holder.mTextView2My.setVisibility(View.GONE);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers); ColorGenerator generator = ColorGenerator.MATERIAL;
TextView repoWatchers = view.findViewById(R.id.repoWatchers); int color = generator.getColor(currentItem.getName());
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
bottomSheetHeader.setText(String.format("%s / %s", repoFullName.getText().toString().split("/")[0], repoFullName.getText().toString().split("/")[1])); TextDrawable drawable = TextDrawable.builder()
BottomSheetDialog dialog = new BottomSheetDialog(context); .beginConfig()
dialog.setContentView(view); .useFont(Typeface.DEFAULT)
dialog.show(); .fontSize(18)
.toUpperCase()
repoOpenInBrowser.setOnClickListener(openInBrowser -> { .width(28)
.height(28)
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); .endConfig()
intentOpenInBrowser.putExtra("repoFullNameBrowser", repoFullName.getText()); .buildRoundRect(firstCharacter, color, 3);
context.startActivity(intentOpenInBrowser);
dialog.dismiss(); if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
}); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.imageMy);
} else {
repoStargazers.setOnClickListener(stargazers -> { holder.imageMy.setImageDrawable(drawable);
}
Intent intent = new Intent(context, RepoStargazersActivity.class); }
intent.putExtra("repoFullNameForStars", repoFullName.getText()); else {
context.startActivity(intent); holder.imageMy.setImageDrawable(drawable);
dialog.dismiss(); }
}); holder.mTextView1My.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) {
repoWatchers.setOnClickListener(watchers -> { holder.mTextView2My.setVisibility(View.VISIBLE);
holder.mTextView2My.setText(currentItem.getDescription());
Intent intentW = new Intent(context, RepoWatchersActivity.class); }
intentW.putExtra("repoFullNameForWatchers", repoFullName.getText()); holder.fullNameMy.setText(currentItem.getFullname());
context.startActivity(intentW); if(currentItem.getPrivateFlag()) {
dialog.dismiss(); 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());
public MyReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
}
this.mCtx = mCtx;
this.reposList = reposListMain; @Override
reposListFull = new ArrayList<>(reposList); public int getItemCount() {
} return reposList.size();
}
@NonNull
@Override @Override
public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public Filter getFilter() {
return myReposFilter;
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false); }
return new MyReposListAdapter.MyReposViewHolder(v);
} private Filter myReposFilter = new Filter() {
@Override
@Override protected FilterResults performFiltering(CharSequence constraint) {
public void onBindViewHolder(@NonNull MyReposListAdapter.MyReposViewHolder holder, int position) { List<UserRepositories> filteredList = new ArrayList<>();
UserRepositories currentItem = reposList.get(position); if (constraint == null || constraint.length() == 0) {
holder.repoDescription.setVisibility(View.GONE); filteredList.addAll(reposListFull);
holder.repoBranch.setText(currentItem.getDefault_branch()); } else {
String filterPattern = constraint.toString().toLowerCase().trim();
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); for (UserRepositories item : reposListFull) {
String firstCharacter = String.valueOf(currentItem.getName().charAt(0)); if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3); }
}
if(currentItem.getAvatar_url() != null) { }
if(!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.imageAvatar); FilterResults results = new FilterResults();
} results.values = filteredList;
else {
holder.imageAvatar.setImageDrawable(drawable); return results;
} }
}
else { @Override
holder.imageAvatar.setImageDrawable(drawable); protected void publishResults(CharSequence constraint, FilterResults results) {
} reposList.clear();
reposList.addAll((List) results.values);
holder.repoName.setText(currentItem.getName()); notifyDataSetChanged();
if(!currentItem.getDescription().equals("")) { }
holder.repoDescription.setVisibility(View.VISIBLE); };
holder.repoDescription.setText(currentItem.getDescription());
}
holder.repoFullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
}
else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return reposList.size();
}
@Override
public Filter getFilter() {
return myReposFilter;
}
private Filter myReposFilter = new Filter() {
@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();
}
};
} }

View File

@ -1,156 +0,0 @@
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.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.NotificationThread;
import java.util.List;
/**
* Author opyale
*/
public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.NotificationsViewHolder> {
private Context context;
private List<NotificationThread> notificationThreads;
private OnMoreClickedListener onMoreClickedListener;
private OnNotificationClickedListener onNotificationClickedListener;
private TinyDB tinyDb;
public NotificationsAdapter(Context context, List<NotificationThread> notificationThreads, OnMoreClickedListener onMoreClickedListener, OnNotificationClickedListener onNotificationClickedListener) {
this.tinyDb = new TinyDB(context);
this.context = context;
this.notificationThreads = notificationThreads;
this.onMoreClickedListener = onMoreClickedListener;
this.onNotificationClickedListener = onNotificationClickedListener;
}
static class NotificationsViewHolder extends RecyclerView.ViewHolder {
private LinearLayout frame;
private TextView subject;
private TextView repository;
private ImageView type;
private ImageView pinned;
private 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);
type = itemView.findViewById(R.id.type);
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='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources()
.getString(R.string.hash) + url.substring(url.lastIndexOf("/") + 1) + "</font>";
holder.subject.setText(Html.fromHtml(subjectId + " " + notificationThread.getSubject().getTitle()));
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.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_pull_request, null));
break;
case "Issue":
holder.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_issue, null));
break;
default:
holder.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_question, null));
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 = new RepositoriesApi(context);
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);
}
}

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -10,14 +11,12 @@ import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import com.squareup.picasso.Picasso;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OrganizationDetailActivity; import org.mian.gitnex.activities.OrgDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.UserOrganizations; import org.mian.gitnex.models.UserOrganizations;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -36,27 +35,23 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<Organizations
private ImageView image; private ImageView image;
private TextView mTextView1; private TextView mTextView1;
private TextView mTextView2; private TextView mTextView2;
private TextView organizationId;
private OrganizationsViewHolder(View itemView) { private OrganizationsViewHolder(View itemView) {
super(itemView); super(itemView);
mTextView1 = itemView.findViewById(R.id.orgUsername); mTextView1 = itemView.findViewById(R.id.orgUsername);
mTextView2 = itemView.findViewById(R.id.orgDescription); mTextView2 = itemView.findViewById(R.id.orgDescription);
image = itemView.findViewById(R.id.imageAvatar); image = itemView.findViewById(R.id.imageAvatar);
organizationId = itemView.findViewById(R.id.organizationId);
itemView.setOnClickListener(new View.OnClickListener() { itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
Intent intent = new Intent(context, OrganizationDetailActivity.class); Intent intent = new Intent(context, OrgDetailActivity.class);
intent.putExtra("orgName", mTextView1.getText().toString()); intent.putExtra("orgName", mTextView1.getText().toString());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("orgName", mTextView1.getText().toString()); tinyDb.putString("orgName", mTextView1.getText().toString());
tinyDb.putString("organizationId", organizationId.getText().toString());
tinyDb.putBoolean("organizationAction", true);
context.startActivity(intent); context.startActivity(intent);
} }
@ -74,19 +69,17 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter<Organizations
@NonNull @NonNull
@Override @Override
public OrganizationsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public OrganizationsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_organizations, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.organizations_list, parent, false);
return new OrganizationsViewHolder(v); return new OrganizationsViewHolder(v);
} }
@SuppressLint("SetTextI18n")
@Override @Override
public void onBindViewHolder(@NonNull OrganizationsViewHolder holder, int position) { public void onBindViewHolder(@NonNull OrganizationsViewHolder holder, int position) {
UserOrganizations currentItem = orgList.get(position); UserOrganizations currentItem = orgList.get(position);
holder.mTextView2.setVisibility(View.GONE); holder.mTextView2.setVisibility(View.GONE);
holder.organizationId.setText(Integer.toString(currentItem.getId()));
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); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
holder.mTextView1.setText(currentItem.getUsername()); holder.mTextView1.setText(currentItem.getUsername());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);

View File

@ -44,7 +44,7 @@ public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdap
@NonNull @NonNull
@Override @Override
public ProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_emails, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.profile_emails_list, parent, false);
return new ProfileEmailsAdapter.EmailsViewHolder(v); return new ProfileEmailsAdapter.EmailsViewHolder(v);
} }

View File

@ -6,8 +6,8 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import java.util.List; import java.util.List;
@ -47,7 +47,7 @@ public class ProfileFollowersAdapter extends RecyclerView.Adapter<ProfileFollowe
@NonNull @NonNull
@Override @Override
public ProfileFollowersAdapter.FollowersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ProfileFollowersAdapter.FollowersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_followers, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.profile_followers_list, parent, false);
return new ProfileFollowersAdapter.FollowersViewHolder(v); return new ProfileFollowersAdapter.FollowersViewHolder(v);
} }
@ -65,7 +65,7 @@ public class ProfileFollowersAdapter extends RecyclerView.Adapter<ProfileFollowe
holder.userName.setVisibility(View.GONE); holder.userName.setVisibility(View.GONE);
} }
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar); Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
} }
@Override @Override

View File

@ -6,8 +6,8 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import java.util.List; import java.util.List;
@ -47,7 +47,7 @@ public class ProfileFollowingAdapter extends RecyclerView.Adapter<ProfileFollowi
@NonNull @NonNull
@Override @Override
public ProfileFollowingAdapter.FollowingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ProfileFollowingAdapter.FollowingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_following, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.profile_following_list, parent, false);
return new ProfileFollowingAdapter.FollowingViewHolder(v); return new ProfileFollowingAdapter.FollowingViewHolder(v);
} }
@ -65,7 +65,7 @@ public class ProfileFollowingAdapter extends RecyclerView.Adapter<ProfileFollowi
holder.userName.setVisibility(View.GONE); holder.userName.setVisibility(View.GONE);
} }
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar); Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
} }
@Override @Override

View File

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

View File

@ -10,25 +10,19 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import com.amulyakhare.textdrawable.TextDrawable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
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.models.Releases; import org.mian.gitnex.models.Releases;
import org.mian.gitnex.util.TinyDB;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin; import io.noties.markwon.core.CorePlugin;
@ -37,6 +31,7 @@ import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.AsyncDrawable;
import io.noties.markwon.image.DefaultMediaDecoder; import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem; import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.ImagesPlugin;
@ -54,44 +49,25 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
private List<Releases> releasesList; private List<Releases> releasesList;
private Context mCtx; private Context mCtx;
static class ReleasesViewHolder extends RecyclerView.ViewHolder { static class ReleasesViewHolder extends RecyclerView.ViewHolder {
private TextView releaseType; private ImageView releaseType;
private TextView releaseName; private TextView releaseTitle;
private ImageView authorAvatar; private TextView releaseDescription;
private TextView authorName; private TextView releaseDownload;
private TextView releaseTag;
private TextView releaseCommitSha;
private TextView releaseDate;
private TextView releaseBodyContent;
private LinearLayout downloadFrame;
private RelativeLayout downloads;
private TextView releaseZipDownload; private TextView releaseZipDownload;
private TextView releaseTarDownload; private TextView releaseTarDownload;
private ImageView downloadDropdownIcon; private TextView releaseTag;
private RecyclerView downloadList;
private ReleasesViewHolder(View itemView) { private ReleasesViewHolder(View itemView) {
super(itemView); super(itemView);
releaseType = itemView.findViewById(R.id.releaseType); releaseType = itemView.findViewById(R.id.releaseType);
releaseName = itemView.findViewById(R.id.releaseName); releaseTitle = itemView.findViewById(R.id.releaseTitle);
authorAvatar = itemView.findViewById(R.id.authorAvatar); releaseDescription = itemView.findViewById(R.id.releaseDescription);
authorName = itemView.findViewById(R.id.authorName); releaseZipDownload = itemView.findViewById(R.id.releaseZipDownload);
releaseTag = itemView.findViewById(R.id.releaseTag); releaseTarDownload = itemView.findViewById(R.id.releaseTarDownload);
releaseCommitSha = itemView.findViewById(R.id.releaseCommitSha); releaseTag = itemView.findViewById(R.id.releaseTag);
releaseDate = itemView.findViewById(R.id.releaseDate);
releaseBodyContent = itemView.findViewById(R.id.releaseBodyContent);
downloadFrame = itemView.findViewById(R.id.downloadFrame);
downloads = itemView.findViewById(R.id.downloads);
releaseZipDownload = itemView.findViewById(R.id.releaseZipDownload);
releaseTarDownload = itemView.findViewById(R.id.releaseTarDownload);
downloadDropdownIcon = itemView.findViewById(R.id.downloadDropdownIcon);
downloadList = itemView.findViewById(R.id.downloadList);
downloadList.setHasFixedSize(true);
downloadList.setLayoutManager(new LinearLayoutManager(itemView.getContext()));
} }
} }
@ -104,7 +80,7 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
@NonNull @NonNull
@Override @Override
public ReleasesAdapter.ReleasesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ReleasesAdapter.ReleasesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_releases, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.releases_list, parent, false);
return new ReleasesAdapter.ReleasesViewHolder(v); return new ReleasesAdapter.ReleasesViewHolder(v);
} }
@ -112,74 +88,83 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) { public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) {
final TinyDB tinyDb = new TinyDB(mCtx); final TinyDB tinyDb = new TinyDB(mCtx);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
Releases currentItem = releasesList.get(position); Releases currentItem = releasesList.get(position);
holder.releaseName.setText(currentItem.getName()); holder.releaseTitle.setText(currentItem.getName());
if(currentItem.isPrerelease()) { if(!currentItem.getTag_name().equals("")) {
holder.releaseType.setBackgroundResource(R.drawable.shape_pre_release); holder.releaseTag.setText(mCtx.getResources().getString(R.string.releaseTag, currentItem.getTag_name()));
holder.releaseType.setText(R.string.releaseTypePre); }
} else {
else if(currentItem.isDraft()) { holder.releaseTag.setVisibility(View.GONE);
holder.releaseType.setVisibility(View.GONE); }
}
else {
holder.releaseType.setBackgroundResource(R.drawable.shape_stable_release);
holder.releaseType.setText(R.string.releaseTypeStable);
}
if(currentItem.getAuthor().getAvatar_url() != null) { if(currentItem.isPrerelease()) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAuthor().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.authorAvatar); TextDrawable drawable = TextDrawable.builder()
} .beginConfig()
//.useFont(Typeface.DEFAULT)
holder.authorName.setText(mCtx.getResources().getString(R.string.releasePublishedBy, currentItem.getAuthor().getUsername())); .textColor(mCtx.getResources().getColor(R.color.white))
.fontSize(34)
if(currentItem.getTag_name() != null) { .width(260)
holder.releaseTag.setText(currentItem.getTag_name()); .height(60)
} .endConfig()
.buildRoundRect(mCtx.getResources().getString(R.string.releaseTypePre), mCtx.getResources().getColor(R.color.releasePre), 8);
if(currentItem.getPublished_at() != null) { holder.releaseType.setImageDrawable(drawable);
holder.releaseDate.setText(TimeHelper.formatTime(currentItem.getPublished_at(), new Locale(locale), timeFormat, mCtx)); }
} else {
TextDrawable drawable = TextDrawable.builder()
if(timeFormat.equals("pretty")) { .beginConfig()
holder.releaseDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getPublished_at()), mCtx)); //.useFont(Typeface.DEFAULT)
} .textColor(mCtx.getResources().getColor(R.color.white))
.fontSize(34)
.width(260)
.height(60)
.endConfig()
.buildRoundRect(mCtx.getResources().getString(R.string.releaseTypeStable), mCtx.getResources().getColor(R.color.releaseStable), 8);
holder.releaseType.setImageDrawable(drawable);
}
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)) final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> { .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
plugin.addSchemeHandler(new SchemeHandler() { @Override
@NonNull public void configureImages(@NonNull ImagesPlugin plugin) {
@Override plugin.addSchemeHandler(new SchemeHandler() {
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { @NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = mCtx.getResources().getIdentifier( final int resourceId = mCtx.getResources().getIdentifier(
raw.substring("drawable://".length()), raw.substring("drawable://".length()),
"drawable", "drawable",
mCtx.getPackageName()); mCtx.getPackageName());
final Drawable drawable = mCtx.getDrawable(resourceId); final Drawable drawable = mCtx.getDrawable(resourceId);
assert drawable != null; assert drawable != null;
return ImageItem.withResult(drawable); return ImageItem.withResult(drawable);
} }
@NonNull @NonNull
@Override @Override
public Collection<String> supportedSchemes() { public Collection<String> supportedSchemes() {
return Collections.singleton("drawable"); return Collections.singleton("drawable");
} }
}); });
plugin.placeholderProvider(drawable -> null); plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
plugin.addMediaDecoder(GifMediaDecoder.create(false)); @Nullable
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources())); @Override
plugin.addMediaDecoder(SvgMediaDecoder.create()); public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources())); return null;
plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); }
});
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() { .usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
@ -200,29 +185,12 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody())); Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody()));
if(!currentItem.getBody().equals("")) { if(!currentItem.getBody().equals("")) {
markwon.setParsedMarkdown(holder.releaseBodyContent, bodyWithMD); markwon.setParsedMarkdown(holder.releaseDescription, bodyWithMD);
} }
else { else {
holder.releaseBodyContent.setText(R.string.noReleaseBodyContent); holder.releaseDescription.setVisibility(View.GONE);
} }
holder.downloadFrame.setOnClickListener(v -> {
if(holder.downloads.getVisibility() == View.GONE) {
holder.downloadDropdownIcon.setImageResource(R.drawable.ic_chevron_down);
holder.downloads.setVisibility(View.VISIBLE);
}
else {
holder.downloadDropdownIcon.setImageResource(R.drawable.ic_chevron_right);
holder.downloads.setVisibility(View.GONE);
}
});
holder.releaseZipDownload.setText( holder.releaseZipDownload.setText(
Html.fromHtml("<a href='" + currentItem.getZipball_url() + "'>" + mCtx.getResources().getString(R.string.zipArchiveDownloadReleasesTab) + "</a> ")); Html.fromHtml("<a href='" + currentItem.getZipball_url() + "'>" + mCtx.getResources().getString(R.string.zipArchiveDownloadReleasesTab) + "</a> "));
holder.releaseZipDownload.setMovementMethod(LinkMovementMethod.getInstance()); holder.releaseZipDownload.setMovementMethod(LinkMovementMethod.getInstance());
@ -231,9 +199,6 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
Html.fromHtml("<a href='" + currentItem.getTarball_url() + "'>" + mCtx.getResources().getString(R.string.tarArchiveDownloadReleasesTab) + "</a> ")); Html.fromHtml("<a href='" + currentItem.getTarball_url() + "'>" + mCtx.getResources().getString(R.string.tarArchiveDownloadReleasesTab) + "</a> "));
holder.releaseTarDownload.setMovementMethod(LinkMovementMethod.getInstance()); holder.releaseTarDownload.setMovementMethod(LinkMovementMethod.getInstance());
ReleasesDownloadsAdapter adapter = new ReleasesDownloadsAdapter(currentItem.getAssets());
holder.downloadList.setAdapter(adapter);
} }
@Override @Override

View File

@ -1,68 +0,0 @@
package org.mian.gitnex.adapters;
import android.text.Html;
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 org.mian.gitnex.models.Releases;
import java.util.List;
/**
* Author M M Arif
**/
public class ReleasesDownloadsAdapter extends RecyclerView.Adapter<ReleasesDownloadsAdapter.ReleasesDownloadsViewHolder> {
private List<Releases.assetsObject> releasesDownloadsList;
static class ReleasesDownloadsViewHolder extends RecyclerView.ViewHolder {
private TextView downloadName;
private ReleasesDownloadsViewHolder(View itemView) {
super(itemView);
downloadName = itemView.findViewById(R.id.downloadName);
}
}
ReleasesDownloadsAdapter(List<Releases.assetsObject> releasesDownloadsMain) {
this.releasesDownloadsList = releasesDownloadsMain;
}
@NonNull
@Override
public ReleasesDownloadsAdapter.ReleasesDownloadsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_releases_downloads, parent, false);
return new ReleasesDownloadsAdapter.ReleasesDownloadsViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ReleasesDownloadsAdapter.ReleasesDownloadsViewHolder holder, int position) {
Releases.assetsObject currentItem = releasesDownloadsList.get(position);
if(currentItem.getName() != null) {
holder.downloadName.setText(
Html.fromHtml("<a href='" + currentItem.getBrowser_download_url() + "'>" + currentItem.getName() + "</a> "));
holder.downloadName.setMovementMethod(LinkMovementMethod.getInstance());
}
}
@Override
public int getItemCount() {
return releasesDownloadsList.size();
}
}

View File

@ -9,11 +9,11 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import java.util.List; import java.util.List;
/** /**
@ -63,7 +63,7 @@ public class RepoStargazersAdapter extends BaseAdapter {
RepoStargazersAdapter.ViewHolder viewHolder; RepoStargazersAdapter.ViewHolder viewHolder;
if (finalView == null) { if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_repo_stargazers, null); finalView = LayoutInflater.from(mCtx).inflate(R.layout.repo_stargazers_list, null);
viewHolder = new ViewHolder(finalView); viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder); finalView.setTag(viewHolder);
} }
@ -79,24 +79,29 @@ public class RepoStargazersAdapter extends BaseAdapter {
private void initData(RepoStargazersAdapter.ViewHolder viewHolder, int position) { private void initData(RepoStargazersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = stargazersList.get(position); UserInfo currentItem = stargazersList.get(position);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar); Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
final TinyDB tinyDb = new TinyDB(mCtx); final TinyDB tinyDb = new TinyDB(mCtx);
Typeface myTypeface; Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) { if(tinyDb.getInt("customFontId") == 0) {
case 0: myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
break;
case 2: }
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
break;
default: myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
break; }
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
} }
@ -109,6 +114,13 @@ public class RepoStargazersAdapter extends BaseAdapter {
viewHolder.memberName.setTypeface(myTypeface); viewHolder.memberName.setTypeface(myTypeface);
} }
if(tinyDb.getInt("themeId") == 1) { //light
viewHolder.memberName.setTextColor(mCtx.getResources().getColor(R.color.lightThemeTextColor));
}
else { // dark
viewHolder.memberName.setTextColor(mCtx.getResources().getColor(R.color.white));
}
} }
} }

View File

@ -9,11 +9,11 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import java.util.List; import java.util.List;
/** /**
@ -63,7 +63,7 @@ public class RepoWatchersAdapter extends BaseAdapter {
RepoWatchersAdapter.ViewHolder viewHolder; RepoWatchersAdapter.ViewHolder viewHolder;
if (finalView == null) { if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_repo_watchers, null); finalView = LayoutInflater.from(mCtx).inflate(R.layout.repo_watchers_list, null);
viewHolder = new ViewHolder(finalView); viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder); finalView.setTag(viewHolder);
} }
@ -79,24 +79,29 @@ public class RepoWatchersAdapter extends BaseAdapter {
private void initData(RepoWatchersAdapter.ViewHolder viewHolder, int position) { private void initData(RepoWatchersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = watchersList.get(position); UserInfo currentItem = watchersList.get(position);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar); Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
final TinyDB tinyDb = new TinyDB(mCtx); final TinyDB tinyDb = new TinyDB(mCtx);
Typeface myTypeface; Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) { if(tinyDb.getInt("customFontId") == 0) {
case 0: myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
break;
case 2: }
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
break;
default: myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
break; }
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
} }
@ -109,6 +114,13 @@ public class RepoWatchersAdapter extends BaseAdapter {
viewHolder.memberName.setTypeface(myTypeface); viewHolder.memberName.setTypeface(myTypeface);
} }
if(tinyDb.getInt("themeId") == 1) { //light
viewHolder.memberName.setTextColor(mCtx.getResources().getColor(R.color.lightThemeTextColor));
}
else { // dark
viewHolder.memberName.setTextColor(mCtx.getResources().getColor(R.color.white));
}
} }
} }

View File

@ -1,41 +1,34 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -43,297 +36,226 @@ import retrofit2.Callback;
public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.ReposViewHolder> implements Filterable { public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.ReposViewHolder> implements Filterable {
private List<UserRepositories> reposList; private List<UserRepositories> reposList;
private Context mCtx; private Context mCtx;
private List<UserRepositories> reposListFull; private List<UserRepositories> reposListFull;
static class ReposViewHolder extends RecyclerView.ViewHolder { static class ReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image; private ImageView image;
private TextView repoName; private TextView mTextView1;
private TextView repoDescription; private TextView mTextView2;
private TextView fullName; private TextView fullName;
private CheckBox isRepoAdmin; private ImageView repoPrivatePublic;
private ImageView repoPrivatePublic; private TextView repoStars;
private TextView repoStars; private TextView repoForks;
private TextView repoForks; private TextView repoOpenIssuesCount;
private TextView repoOpenIssuesCount; private TextView repoType;
private TextView repoType;
private LinearLayout archiveRepo; private ReposViewHolder(View itemView) {
private TextView repoBranch;
super(itemView);
private ReposViewHolder(View itemView) { mTextView1 = itemView.findViewById(R.id.repoName);
mTextView2 = itemView.findViewById(R.id.repoDescription);
super(itemView); image = itemView.findViewById(R.id.imageAvatar);
repoName = itemView.findViewById(R.id.repoName); fullName = itemView.findViewById(R.id.repoFullName);
repoDescription = itemView.findViewById(R.id.repoDescription); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin); repoStars = itemView.findViewById(R.id.repoStars);
image = itemView.findViewById(R.id.imageAvatar); repoForks = itemView.findViewById(R.id.repoForks);
fullName = itemView.findViewById(R.id.repoFullName); repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoStars = itemView.findViewById(R.id.repoStars); repoType = itemView.findViewById(R.id.repoType);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount); itemView.setOnClickListener(new View.OnClickListener() {
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); @Override
repoType = itemView.findViewById(R.id.repoType); public void onClick(View v) {
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch); Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName);
itemView.setOnClickListener(v -> { TextView repoType_ = v.findViewById(R.id.repoType);
Context context = v.getContext(); Intent intent = new Intent(context, RepoDetailActivity.class);
TextView repoFullName = v.findViewById(R.id.repoFullName); intent.putExtra("repoFullName", repoFullName.getText().toString());
TextView repoType_ = v.findViewById(R.id.repoType);
TinyDB tinyDb = new TinyDB(context);
Intent intent = new Intent(context, RepoDetailActivity.class); tinyDb.putString("repoFullName", repoFullName.getText().toString());
intent.putExtra("repoFullName", repoFullName.getText().toString()); tinyDb.putString("repoType", repoType_.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
TinyDB tinyDb = new TinyDB(context); context.startActivity(intent);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putString("repoType", repoType_.getText().toString()); }
//tinyDb.putBoolean("resumeIssues", true); });
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString()); reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
String[] parts = repoFullName.getText().toString().split("/"); public void onClick(View v) {
final String repoOwner = parts[0];
final String repoName = parts[1]; final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context); PopupMenu popupMenu = new PopupMenu(context, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName); Object menuHelper;
Class[] argTypes;
if(count == 0) { try {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
tinyDb.putLong("repositoryId", id); fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
} argTypes = new Class[] { boolean.class };
else { assert menuHelper != null;
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName); argTypes).invoke(menuHelper, true);
tinyDb.putLong("repositoryId", data.getRepositoryId());
} catch (Exception e) {
}
popupMenu.show();
//store if user is watching this repo return;
{
}
final String instanceUrl = tinyDb.getString("instanceUrl");
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
WatchInfo watch = new WatchInfo(); public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
Call<WatchInfo> call; case R.id.repoStargazers:
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
call.enqueue(new Callback<WatchInfo>() { context.startActivity(intent);
break;
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) { case R.id.repoWatchers:
if(response.isSuccessful()) { Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
assert response.body() != null; context.startActivity(intentW);
tinyDb.putBoolean("repoWatch", response.body().getSubscribed()); break;
} else { case R.id.repoOpenInBrowser:
tinyDb.putBoolean("repoWatch", false); Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
if(response.code() != 404) { context.startActivity(intentOpenInBrowser);
break;
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
} return false;
}
} });
} popupMenu.show();
@Override }
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) { });
tinyDb.putBoolean("repoWatch", false); }
Toasty.info(context, context.getString(R.string.genericApiStatusError)); }
} public ReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
}); this.mCtx = mCtx;
this.reposList = reposListMain;
} reposListFull = new ArrayList<>(reposList);
}
context.startActivity(intent);
@NonNull
}); @Override
public ReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
reposDropdownMenu.setOnClickListener(v -> { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repos_list, parent, false);
return new ReposViewHolder(v);
final Context context = v.getContext(); }
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null); @Override
public void onBindViewHolder(@NonNull ReposViewHolder holder, int position) {
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers); UserRepositories currentItem = reposList.get(position);
TextView repoWatchers = view.findViewById(R.id.repoWatchers); holder.mTextView2.setVisibility(View.GONE);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
ColorGenerator generator = ColorGenerator.MATERIAL;
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1])); int color = generator.getColor(currentItem.getName());
BottomSheetDialog dialog = new BottomSheetDialog(context); String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
dialog.setContentView(view);
dialog.show(); TextDrawable drawable = TextDrawable.builder()
.beginConfig()
repoOpenInBrowser.setOnClickListener(openInBrowser -> { .useFont(Typeface.DEFAULT)
.fontSize(18)
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); .toUpperCase()
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText()); .width(28)
context.startActivity(intentOpenInBrowser); .height(28)
dialog.dismiss(); .endConfig()
.buildRoundRect(firstCharacter, color, 3);
});
if (currentItem.getAvatar_url() != null) {
repoStargazers.setOnClickListener(stargazers -> { if (!currentItem.getAvatar_url().equals("")) {
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
Intent intent = new Intent(context, RepoStargazersActivity.class); } else {
intent.putExtra("repoFullNameForStars", fullName.getText()); holder.image.setImageDrawable(drawable);
context.startActivity(intent); }
dialog.dismiss(); }
else {
}); holder.image.setImageDrawable(drawable);
}
repoWatchers.setOnClickListener(watchers -> {
holder.mTextView1.setText(currentItem.getName());
Intent intentW = new Intent(context, RepoWatchersActivity.class); if (!currentItem.getDescription().equals("")) {
intentW.putExtra("repoFullNameForWatchers", fullName.getText()); holder.mTextView2.setVisibility(View.VISIBLE);
context.startActivity(intentW); holder.mTextView2.setText(currentItem.getDescription());
dialog.dismiss(); }
holder.fullName.setText(currentItem.getFullname());
}); if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
}); holder.repoType.setText(R.string.strPrivate);
}
} else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
} holder.repoType.setText(R.string.strPublic);
}
public ReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) { holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
this.mCtx = mCtx; holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList); }
}
@Override
@NonNull public int getItemCount() {
@Override return reposList.size();
public ReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { }
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false); @Override
return new ReposViewHolder(v); public Filter getFilter() {
} return reposFilter;
}
@Override
public void onBindViewHolder(@NonNull ReposViewHolder holder, int position) { private Filter reposFilter = new Filter() {
@Override
UserRepositories currentItem = reposList.get(position); protected FilterResults performFiltering(CharSequence constraint) {
holder.repoDescription.setVisibility(View.GONE); List<UserRepositories> filteredList = new ArrayList<>();
holder.repoBranch.setText(currentItem.getDefault_branch());
if (constraint == null || constraint.length() == 0) {
ColorGenerator generator = ColorGenerator.MATERIAL; filteredList.addAll(reposListFull);
int color = generator.getColor(currentItem.getName()); } else {
String firstCharacter = String.valueOf(currentItem.getName().charAt(0)); String filterPattern = constraint.toString().toLowerCase().trim();
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3); for (UserRepositories item : reposListFull) {
if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
if(currentItem.getAvatar_url() != null) { filteredList.add(item);
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); }
} }
else {
holder.image.setImageDrawable(drawable); FilterResults results = new FilterResults();
} results.values = filteredList;
}
else { return results;
holder.image.setImageDrawable(drawable); }
}
@Override
holder.repoName.setText(currentItem.getName()); protected void publishResults(CharSequence constraint, FilterResults results) {
if(!currentItem.getDescription().equals("")) { reposList.clear();
holder.repoDescription.setVisibility(View.VISIBLE); reposList.addAll((List) results.values);
holder.repoDescription.setText(currentItem.getDescription()); notifyDataSetChanged();
} }
holder.fullName.setText(currentItem.getFullname()); };
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
}
else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return reposList.size();
}
@Override
public Filter getFilter() {
return reposFilter;
}
private Filter reposFilter = new Filter() {
@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();
}
};
} }

View File

@ -1,41 +1,34 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import retrofit2.Call; import androidx.annotation.NonNull;
import retrofit2.Callback; import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
/** /**
* Author M M Arif * Author M M Arif
@ -50,23 +43,19 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
static class OrgReposViewHolder extends RecyclerView.ViewHolder { static class OrgReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image; private ImageView image;
private TextView repoName; private TextView mTextView1;
private TextView repoDescription; private TextView mTextView2;
private TextView fullName; private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoForks; private TextView repoForks;
private TextView repoOpenIssuesCount; private TextView repoOpenIssuesCount;
private TextView repoType; private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private OrgReposViewHolder(View itemView) { private OrgReposViewHolder(View itemView) {
super(itemView); super(itemView);
repoName = itemView.findViewById(R.id.repoName); mTextView1 = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription); mTextView2 = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar); image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
@ -75,138 +64,86 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount); repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
Intent intent = new Intent(context, RepoDetailActivity.class); Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", fullName.getText().toString()); intent.putExtra("repoFullName", fullName.getText().toString());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullName.getText().toString()); tinyDb.putString("repoFullName", fullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString()); tinyDb.putString("repoType", repoType.getText().toString());
//tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked()); context.startActivity(intent);
tinyDb.putString("repoBranch", repoBranch.getText().toString());
String[] parts = fullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
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); reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
tinyDb.putLong("repositoryId", data.getRepositoryId()); @Override
public void onClick(View v) {
} final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
//store if user is watching this repo PopupMenu popupMenu = new PopupMenu(context, v);
{ popupMenu.inflate(R.menu.repo_dotted_list_menu);
final String instanceUrl = tinyDb.getString("instanceUrl"); Object menuHelper;
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); Class[] argTypes;
try {
Call<WatchInfo> call; Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); } catch (Exception e) {
call.enqueue(new Callback<WatchInfo>() { popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.repoStargazers:
if(response.isSuccessful()) { Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
break;
assert response.body() != null; case R.id.repoWatchers:
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else { Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
break;
tinyDb.putBoolean("repoWatch", false); case R.id.repoOpenInBrowser:
if(response.code() != 404) { Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
Toasty.info(context, context.getString(R.string.genericApiStatusError)); context.startActivity(intentOpenInBrowser);
break;
}
} }
return false;
}
@Override
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
}); });
popupMenu.show();
} }
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(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(openInBrowser -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(openInBrowser -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
}); });
} }
@ -222,7 +159,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
@NonNull @NonNull
@Override @Override
public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repositories_by_org_list, parent, false);
return new RepositoriesByOrgAdapter.OrgReposViewHolder(v); return new RepositoriesByOrgAdapter.OrgReposViewHolder(v);
} }
@ -230,8 +167,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
public void onBindViewHolder(@NonNull RepositoriesByOrgAdapter.OrgReposViewHolder holder, int position) { public void onBindViewHolder(@NonNull RepositoriesByOrgAdapter.OrgReposViewHolder holder, int position) {
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.mTextView2.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -249,7 +185,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
if (currentItem.getAvatar_url() != null) { if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) { if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else { } else {
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
@ -258,36 +194,24 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
holder.repoName.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.mTextView2.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullname()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
holder.repoType.setText(R.string.strPrivate); holder.repoType.setText(R.string.strPrivate);
} }
else { else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
holder.repoType.setText(R.string.strPublic); holder.repoType.setText(R.string.strPublic);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if (holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
} }
@Override @Override

View File

@ -1,41 +1,34 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import retrofit2.Call; import androidx.annotation.NonNull;
import retrofit2.Callback; import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
/** /**
* Author M M Arif * Author M M Arif
@ -50,23 +43,19 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
static class StarredReposViewHolder extends RecyclerView.ViewHolder { static class StarredReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image; private ImageView image;
private TextView repoName; private TextView mTextView1;
private TextView repoDescription; private TextView mTextView2;
private TextView fullName; private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoForks; private TextView repoForks;
private TextView repoOpenIssuesCount; private TextView repoOpenIssuesCount;
private TextView repoType; private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private StarredReposViewHolder(View itemView) { private StarredReposViewHolder(View itemView) {
super(itemView); super(itemView);
repoName = itemView.findViewById(R.id.repoName); mTextView1 = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription); mTextView2 = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar); image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
@ -75,141 +64,86 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount); repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
Intent intent = new Intent(context, RepoDetailActivity.class); Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", fullName.getText().toString()); intent.putExtra("repoFullName", fullName.getText().toString());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullName.getText().toString()); tinyDb.putString("repoFullName", fullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString()); tinyDb.putString("repoType", repoType.getText().toString());
//tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked()); context.startActivity(intent);
tinyDb.putString("repoBranch", repoBranch.getText().toString());
String[] parts = fullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
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); reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
tinyDb.putLong("repositoryId", data.getRepositoryId()); @Override
public void onClick(View v) {
} final Context context = v.getContext();
Context context_ = new ContextThemeWrapper(context, R.style.AppThemeConfirmDialog);
//store if user is watching this repo PopupMenu popupMenu = new PopupMenu(context, v);
{ popupMenu.inflate(R.menu.repo_dotted_list_menu);
final String instanceUrl = tinyDb.getString("instanceUrl"); Object menuHelper;
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); Class[] argTypes;
try {
WatchInfo watch = new WatchInfo(); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
Call<WatchInfo> call; } catch (Exception e) {
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); popupMenu.show();
return;
call.enqueue(new Callback<WatchInfo>() { }
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.repoStargazers:
if(response.isSuccessful()) { Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
break;
assert response.body() != null; case R.id.repoWatchers:
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else { Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
break;
tinyDb.putBoolean("repoWatch", false); case R.id.repoOpenInBrowser:
if(response.code() != 404) { Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
Toasty.info(context, context.getString(R.string.genericApiStatusError)); context.startActivity(intentOpenInBrowser);
break;
}
} }
return false;
}
@Override
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
}); });
popupMenu.show();
} }
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(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
}); });
} }
@ -225,7 +159,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
@NonNull @NonNull
@Override @Override
public StarredReposListAdapter.StarredReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public StarredReposListAdapter.StarredReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.starred_repos_list, parent, false);
return new StarredReposListAdapter.StarredReposViewHolder(v); return new StarredReposListAdapter.StarredReposViewHolder(v);
} }
@ -233,8 +167,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
public void onBindViewHolder(@NonNull StarredReposListAdapter.StarredReposViewHolder holder, int position) { public void onBindViewHolder(@NonNull StarredReposListAdapter.StarredReposViewHolder holder, int position) {
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.mTextView2.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -252,7 +185,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
if (currentItem.getAvatar_url() != null) { if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) { if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else { } else {
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
@ -261,34 +194,23 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
holder.repoName.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.mTextView2.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullname()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
holder.repoType.setText(R.string.strPrivate); holder.repoType.setText(R.string.strPrivate);
} }
else { else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
holder.repoType.setText(R.string.strPublic); holder.repoType.setText(R.string.strPublic);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if (holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
} }

View File

@ -9,11 +9,11 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import java.util.List; import java.util.List;
/** /**
@ -64,7 +64,7 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
TeamMembersByOrgAdapter.ViewHolder viewHolder = null; TeamMembersByOrgAdapter.ViewHolder viewHolder = null;
if (finalView == null) { if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_members_by_team_by_org, null); finalView = LayoutInflater.from(mCtx).inflate(R.layout.members_by_team_by_org_list, null);
viewHolder = new ViewHolder(finalView); viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder); finalView.setTag(viewHolder);
} }
@ -80,24 +80,29 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
private void initData(TeamMembersByOrgAdapter.ViewHolder viewHolder, int position) { private void initData(TeamMembersByOrgAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = teamMembersList.get(position); UserInfo currentItem = teamMembersList.get(position);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar); Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
final TinyDB tinyDb = new TinyDB(mCtx); final TinyDB tinyDb = new TinyDB(mCtx);
Typeface myTypeface; Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) { if(tinyDb.getInt("customFontId") == 0) {
case 0: myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
break;
case 2: }
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
break;
default: myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
break; }
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
} }
@ -110,5 +115,12 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
viewHolder.memberName.setTypeface(myTypeface); viewHolder.memberName.setTypeface(myTypeface);
} }
if(tinyDb.getInt("themeId") == 1) { //light
viewHolder.memberName.setTextColor(mCtx.getResources().getColor(R.color.lightThemeTextColor));
}
else { // dark
viewHolder.memberName.setTextColor(mCtx.getResources().getColor(R.color.white));
}
} }
} }

View File

@ -9,7 +9,7 @@ import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.TextView; import android.widget.TextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OrganizationTeamMembersActivity; import org.mian.gitnex.activities.OrgTeamMembersActivity;
import org.mian.gitnex.models.Teams; import org.mian.gitnex.models.Teams;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -46,7 +46,7 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.Or
Context context = v.getContext(); Context context = v.getContext();
Intent intent = new Intent(context, OrganizationTeamMembersActivity.class); Intent intent = new Intent(context, OrgTeamMembersActivity.class);
intent.putExtra("teamTitle", teamTitle.getText().toString()); intent.putExtra("teamTitle", teamTitle.getText().toString());
intent.putExtra("teamId", teamId.getText().toString()); intent.putExtra("teamId", teamId.getText().toString());
context.startActivity(intent); context.startActivity(intent);
@ -67,7 +67,7 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.Or
@NonNull @NonNull
@Override @Override
public TeamsByOrgAdapter.OrgTeamsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public TeamsByOrgAdapter.OrgTeamsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_teams_by_org, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.teams_by_org_list, parent, false);
return new TeamsByOrgAdapter.OrgTeamsViewHolder(v); return new TeamsByOrgAdapter.OrgTeamsViewHolder(v);
} }

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