Compare commits

..

33 Commits

Author SHA1 Message Date
f135508745 Release 3.0.0 rc3 (#570)
Release 3.0.0 rc3

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/570
2020-06-30 21:08:10 +02:00
3e5e94790e Update libs, remove depricated libs (#566)
proper decleration

Merge branch 'update-libs-fix-deps' of codeberg.org:gitnex/GitNex into update-libs-fix-deps

import searchview and other improvements

Merge branch 'master' into update-libs-fix-deps

Update libs, remove depricated libs

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/566
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-06-30 20:59:11 +02:00
62aace4b91 Fix old URLs which do not have a slash at the end. (#568)
Merge branch 'master' into fix-older-urls

Fix old URLs which do not have a slash at the end.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/568
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-30 20:36:24 +02:00
2412245a9f Fixing path issues. (#567)
Fixing path issues.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/567
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-30 20:19:55 +02:00
e872069093 Proper URL parsing, label redesign and other improvements. (#564)
Final improvements.

Fixing reply mention.

Do NOT use "instanceUrlRaw" as of now.

Minor fixes

Merge remote-tracking branch 'remotes/main/master' into login-fix

URL parsing, label and other improvements.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/564
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-30 16:43:27 +02:00
5672208fd0 Adding ability to quote and to copy issue comments. (#562)
Minor fix.

Merge branch 'master' into reply-tools

Merge remote-tracking branch 'opyale/reply-tools' into reply-tools

Changing names.

Merge branch 'master' into reply-tools

Adding ability to cite and to copy issue comments.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Co-authored-by: 6543 <6543@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/562
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-28 19:26:59 +02:00
7379e9945d Fixing bugs of previous pull (#563)
Fixing bugs of previous pull.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/563
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-06-28 18:48:33 +02:00
815417bf11 Refactoring LoginActivity and other improvements. (#561)
Adding error message for login().

Final touch.

Refactoring LoginActivity and other improvements.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/561
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-06-28 17:11:59 +02:00
95fc5e1e9a Fix bug #549, add more file ext to file viewer (#560)
Fix empty release notes bug

Add new sponsor

Fix bug #549, add more file ext to file viewer

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/560
Reviewed-by: opyale <opyale@noreply.codeberg.org>
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-06-28 16:45:39 +02:00
f285d47a0b Fix Crash on closed PRs with deleted Fork (#559)
Fix edge-case DeletedFork of a Pull-Branch

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-26 17:09:18 +02:00
2483968f11 Inverting color of divider too (#553)
Inverting color of divider too

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-06-25 01:27:13 +02:00
d0fde4e791 Adjusting icon color to fit background. (#551)
Adjusting icon color to fit background.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-24 23:02:22 +02:00
c7c2ac2a11 Enhance bottomsheets ui (#550)
Fix name collision in themes

Add space between org and repo name

standard use of dimens

more ui improvements

wip to enhance all bottom sheets

Fix radius and improve the ui

enhance bottom sheet

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-06-24 22:29:58 +02:00
4f79ea0156 Fix Crash when searching issues/pr (#547)
fix in pr and ms fragments

Fix Crash when searching issues/pr

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-24 17:05:02 +02:00
22943ca9cd Fix user team search crash (#545)
Fix team user search crash

Refactor userName

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-06-23 20:59:23 +02:00
5a10127c1c Calculate ImageContrastColor more precise & some doc nits (#544)
Fixing color bug, updating license headers and CONTRIBUTORS

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-23 16:54:27 +02:00
7de29687eb Fixing collaborators bug and some improvements in RepoDetailActivity (#543)
* Minor improvements.

* Fixing collaborators bug and many (performance) improvements in RepoDetailActivity.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-06-22 18:28:08 +02:00
1a95475140 Gitea >= v1.12.0 only need read rights for Colaborators Tab (#542)
show "Add Collaborator" option only if you have the right to do so

gitea >= v1.12.0 only need read rights for Colaborators Tab

Signed-off-by: 6543 <6543@obermui.de>

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-22 17:59:36 +02:00
d2265aecae Fix profile title (#541)
Fix profile
2020-06-22 09:57:21 +02:00
626746be8b Release 3.0.0 rc2 (#539)
release 3.0.0 rc2

Co-authored-by: M M Arif <mmarif@swatian.com>
2020-06-11 15:47:28 +02:00
f21f23c1f0 Refactor FileDiffActivety (#537)
use androidx @NonNull instead of jetbrains @NotNull

Merge branch 'master' into refactor_FileDiffActivity

code format corrections

Merge branch 'master' into refactor_FileDiffActivity

add Unit TESTs for ParseDiff.getFileDiffViewArray

add get methods

make rm/add similar to gitea stats

calc diff stat based on diff itself

rename getFileContents -> toString

fix empty content bug & add comments

format AppUtil.java

rm unused

working version

skip binary files for now ... [DONT CRASH]

better regex

format FileDiffView.java

rename toolbar_title -> toolbarTitle

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-11 15:31:11 +02:00
5005fcc5b5 Redesign releases screen (#526)
Add download assets

implement release layout in adapter

update the layout

Fixing gravity.

Adding layouts for new release items.

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-06-11 01:45:11 +02:00
008e446b93 GitNex drop 1.10 support and add 1.13 (#538)
GitNex drop 1.10 support and add 1.13

rm unused

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-10 17:22:49 +02:00
50e0142f6c Pull Diff View: Use new API if gitea >= 1.13.0 (#536)
right arg order & right instanceUrl

use new API if gitea >= 1.13.0

correct name

format code

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-06-09 15:36:08 +02:00
42640f2d1c Updating gradle. (#535)
Updating gradle.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-08 18:43:57 +02:00
4a8ee2ea96 Improving design of organisation detail page. (#534)
Design changes and updating dependencies.

Small fix.

Adding missing library.

Cleanup.

Improving design of organisation detail page.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-08 08:34:53 +02:00
acc55e3433 Using blurred avatar as background. (#532)
Fixing NullPointerException when image isn't loaded yet.

Display country instead of raw language code.

Minor improvements and contrasting color.

First changes.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-06 22:04:07 +02:00
e267aa5100 Show archived repo message (#530)
Implement archived repo in all adapters

Merge branch 'archive-repo2' into archive-repo

Fix typos

Fixing gravity.

Restoring old names.

Design changes.

Adjusting sizing.

Improving design of archived message.

Show archived repo message and other fixes

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-06-06 21:41:19 +02:00
5e41469452 Move to CodeBerg (#528)
the rest

move to CodeBerg

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-06-04 17:37:51 +02:00
55473701b8 Improving design of "Show more information" (#527)
Adding comments to editorconfig.

Formatting.

Adding link color attribute.

Minor improvements.

Use dedicated layout for additional information.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-06-04 16:21:23 +02:00
546346ff48 Improving milestones. (#525)
Removing unused strings.

Adding a little bit more space between title and progress bar.

Swapping icons.

Merge remote-tracking branch 'remotes/main/master' into improve-milestones

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

Minor improvements.

Merge branch 'improve-layouts' of https://gitea.com/opyale/GitNex into improve-milestones

Merge branch 'improve-layouts' of https://gitea.com/gitnex/GitNex into improve-milestones

Moving items.

Merge branch 'master' into improve-layouts

Merge branch 'master' into improve-layouts

Translation and additional formatting.

Enhancing editorconfig

Formatting and removing unused imports.

Removing milestone state.

Improving milestones.

branches and milestones layout update. Fix milestone infinite pagination loop for lower versions

layout updates for issues, pr. Fix pr nullable objects for lower versions

improve files layout

improve org info and list orgs

improve teams list layout by org

Fix repo layouts

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/525
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-06-01 16:43:58 +00:00
4f0091f151 Improve layouts (#524)
make release checkboxes unchecked

admin users layout update

update commits and releases layout

profile fragments layout updates

improve labels

Merge branch 'master' into improve-layouts

branches and milestones layout update. Fix milestone infinite pagination loop for lower versions

layout updates for issues, pr. Fix pr nullable objects for lower versions

improve files layout

improve org info and list orgs

improve teams list layout by org

Fix repo layouts

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/524
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-06-01 15:53:56 +00:00
37367e142f Fixes for rc1 (#523)
Fix commits query limit

Fix text colors for auto theme

Fix text color in grid views

fix file size for dir

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/523
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-06-01 14:19:34 +00:00
185 changed files with 4240 additions and 3115 deletions

View File

@ -4,14 +4,23 @@ 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
max_line_length = 220
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

@ -36,6 +36,7 @@
<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="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="WRAP_ON_TYPING" value="1" />
<indentOptions>
@ -156,4 +157,4 @@
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
</component>

View File

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

View File

@ -10,7 +10,7 @@ Please ask if you are not sure about the scope of work to be submitted to avoid
**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://gitea.com/gitnex/GitNex/wiki/Code-Standards)
It is documented in the Wiki: [Code-Standards](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards)
**How to submit a PR**
Fork this repository. Pull the forked repository from your namespace to your local machine. Create new branch and work on the bug/feature/enhancement you would like to submit. Push it to your forked version. From there create Pull Request(PR) against **master** branch.

View File

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

View File

@ -1,4 +1,4 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://gitea.com/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://gitea.com/gitnex/GitNex/releases) [![Build Status](https://drone.gitea.com/api/badges/gitnex/GitNex/status.svg)](https://drone.gitea.com/gitnex/GitNex) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf)
[![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)
[<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)
@ -18,7 +18,7 @@ Download latest build from master: [https://cloud.swatian.com/s/Cq592xGEfnsGAAW]
## Note about Gitea version
Please make sure that you are on latest stable release or later for better app experience.
Check the versions [compatibility page](https://gitea.com/gitnex/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio.
Check the versions [compatibility page](https://codeberg.org/gitnex/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio.
## Build from source
Option 1 - Download the source code, open it in Android Studio and build it there.
@ -32,41 +32,41 @@ Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew build`
- Issues list
- Pull requests
- Merge pull request
- [MANY MORE](https://gitea.com/gitnex/GitNex/wiki/Features)
- [MANY MORE](https://codeberg.org/gitnex/GitNex/wiki/Features)
## Contributing
[CONTRIBUTING](https://gitea.com/gitnex/GitNex/src/branch/master/CONTRIBUTING.md)
[CONTRIBUTING](https://codeberg.org/gitnex/GitNex/src/branch/master/CONTRIBUTING.md)
## Translation
Help us translate GitNex to your native language.
We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your language is not listed, please request [here](https://gitea.com/gitnex/GitNex/issues) to add it to the project.
We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your language is not listed, please request [here](https://codeberg.org/gitnex/GitNex/issues) to add it to the project.
**Link: https://crowdin.com/project/GitNex**
## Screenshots:
<img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/001.png" alt="001.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/002.png" alt="002.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/003.png" alt="003.png" width="200"/> | <img src="https://gitea.com/gitnex/GitNex/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/004.png" alt="004.png" width="200"/>
<img src="https://codeberg.org/gitnex/GitNex/raw/branch/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/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"/>
<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"/>
## FAQ
[Faq](https://gitea.com/gitnex/GitNex/wiki/FAQ)
[Faq](https://codeberg.org/gitnex/GitNex/wiki/FAQ)
## Links
[Website](https://gitnex.com)
[Wiki](https://gitea.com/gitnex/GitNex/wiki/Home)
[Wiki](https://codeberg.org/gitnex/GitNex/wiki/Home)
[Website Repository](https://gitlab.com/mmarif4u/gitnex-website)
[Troubleshoot Guide](https://gitea.com/gitnex/GitNex/wiki/Troubleshoot-Guide)
[Troubleshoot Guide](https://codeberg.org/gitnex/GitNex/wiki/Troubleshoot-Guide)
## Thanks
Thanks to all the open source libraries, contributors and donators.
Open source libraries
#### Open source libraries
- Retrofit
- Gson
- Okhttp
@ -87,5 +87,7 @@ Open source libraries
- Droidsonroids.gif/android-gif-drawable
- Barteksc/AndroidPdfViewer
- Ge0rg/MemorizingTrustManager
- Dimezis/BlurView
- mikaelhg/urlbuilder
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)

View File

@ -6,8 +6,8 @@ android {
applicationId "org.mian.gitnex"
minSdkVersion 21
targetSdkVersion 29
versionCode 295
versionName "3.0.0-rc1"
versionCode 297
versionName "3.0.0-rc3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
viewBinding {
@ -36,27 +36,28 @@ configurations {
}
dependencies {
def lifecycle_version = "2.2.0"
def markwon_version = '4.3.1'
def lifecycle_version = "2.3.0-alpha05"
def markwon_version = '4.4.0'
def acra = "5.5.0"
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:1.2.0-rc01"
implementation "com.google.android.material:material:1.2.0-beta01"
implementation "androidx.appcompat:appcompat:1.3.0-alpha01"
implementation "com.google.android.material:material:1.3.0-alpha01"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
testImplementation "junit:junit:4.13"
androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
implementation "com.github.vihtarb:tooltip:0.2.0"
implementation 'com.squareup.okhttp3:okhttp:4.7.0'
implementation 'com.squareup.okhttp3:okhttp:4.7.2'
implementation "com.google.code.gson:gson:2.8.6"
implementation "com.squareup.picasso:picasso:2.71828"
implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1"
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
implementation 'com.squareup.retrofit2:converter-scalars:2.8.1'
implementation 'com.squareup.okhttp3:logging-interceptor:4.7.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.7.2'
implementation 'org.ocpsoft.prettytime:prettytime:4.0.5.Final'
implementation "com.vdurmont:emoji-java:5.1.1"
implementation "com.pes.materialcolorpicker:library:1.2.5"
@ -77,8 +78,6 @@ dependencies {
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.19"
implementation "com.hendraanggrian.appcompat:socialview:0.2"
implementation "com.hendraanggrian.appcompat:socialview-commons:0.2"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
implementation "commons-io:commons-io:20030203.000550"
implementation "com.github.chrisbanes:PhotoView:2.3.0"
@ -86,5 +85,7 @@ dependencies {
implementation "ch.acra:acra-mail:$acra"
implementation "ch.acra:acra-limiter:$acra"
implementation "ch.acra:acra-notification:$acra"
implementation "com.eightbitlab:blurview:1.6.3"
implementation "io.mikael:urlbuilder:2.0.9"
}

View File

@ -203,7 +203,7 @@ public class IssueActions {
}
else {
Toasty.info(ctx, ctx.getString(R.string.subscribtionError));
Toasty.info(ctx, ctx.getString(R.string.subscriptionError));
}
@ -263,7 +263,7 @@ public class IssueActions {
}
else {
Toasty.info(ctx, ctx.getString(R.string.unsubscribtionError));
Toasty.info(ctx, ctx.getString(R.string.unsubscriptionError));
}
@ -272,7 +272,7 @@ public class IssueActions {
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.info(ctx, ctx.getString(R.string.unsubscribtionError));
Toasty.info(ctx, ctx.getString(R.string.unsubscriptionError));
}
});
}

View File

@ -96,7 +96,7 @@ public class AddNewTeamMemberActivity extends BaseActivity {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(!addNewTeamMember.getText().toString().equals("")) {
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);

View File

@ -1,13 +1,5 @@
package org.mian.gitnex.activities;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@ -19,16 +11,20 @@ import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.AdminGetUsersAdapter;
import org.mian.gitnex.fragments.BottomSheetAdminUsersFragment;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.AdminGetUsersViewModel;
import java.util.List;
import java.util.Objects;
/**
* Author M M Arif
@ -79,18 +75,12 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
}
}, 500);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setRefreshing(false);
AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
}, 500));
fetchDataAsync(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
@ -98,25 +88,24 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
private void fetchDataAsync(Context ctx, String instanceUrl, String instanceToken) {
AdminGetUsersViewModel usersModel = ViewModelProviders.of(this).get(AdminGetUsersViewModel.class);
AdminGetUsersViewModel usersModel = new ViewModelProvider(this).get(AdminGetUsersViewModel.class);
usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
@Override
public void onChanged(@Nullable List<UserInfo> usersListMain) {
adapter = new AdminGetUsersAdapter(ctx, usersListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(adapter);
noDataUsers.setVisibility(View.GONE);
searchFilter = true;
}
else {
//adapter.notifyDataSetChanged();
//mRecyclerView.setAdapter(adapter);
mRecyclerView.setVisibility(View.GONE);
noDataUsers.setVisibility(View.VISIBLE);
}
usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, usersListMain -> {
adapter = new AdminGetUsersAdapter(ctx, usersListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(adapter);
noDataUsers.setVisibility(View.GONE);
searchFilter = true;
}
else {
//adapter.notifyDataSetChanged();
//mRecyclerView.setAdapter(adapter);
mRecyclerView.setVisibility(View.GONE);
noDataUsers.setVisibility(View.VISIBLE);
}
});
}
@ -127,37 +116,36 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if(searchFilter) {
new Handler().postDelayed(() -> {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
if(searchFilter) {
inflater.inflate(R.menu.search_menu, menu);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
inflater.inflate(R.menu.search_menu, menu);
if(!connToInternet) {
return;
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
if(!connToInternet) {
return;
}
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) { return true; }
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
}
});
}
}, 500);
return true;
@ -194,12 +182,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
}
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
onClickListener = view -> finish();
}
}

View File

@ -103,6 +103,11 @@ public abstract class BaseActivity extends AppCompatActivity {
tinyDb.putString("cacheSizeImagesStr", getResources().getString(R.string.cacheSizeImagesSelectionSelectedText));
}
if(!tinyDb.getString("instanceUrlWithProtocol").endsWith("/")) {
tinyDb.putString("instanceUrlWithProtocol", tinyDb.getString("instanceUrlWithProtocol") + "/");
}
if (tinyDb.getBoolean("crashReportingEnabled")) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);

View File

@ -23,7 +23,6 @@ import org.mian.gitnex.adapters.CommitsAdapter;
import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Commits;
@ -102,7 +101,7 @@ public class CommitsActivity extends BaseActivity {
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setRefreshing(false);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit);
adapter.notifyDataChanged();
}, 200));
@ -113,7 +112,7 @@ public class CommitsActivity extends BaseActivity {
if(commitsList.size() == resultLimit || pageSize == resultLimit) {
int page = (commitsList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, branchName);
loadMore(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, branchName, resultLimit);
}
@ -124,13 +123,13 @@ public class CommitsActivity extends BaseActivity {
recyclerView.setAdapter(adapter);
api = AppApiService.createService(ApiInterface.class, instanceUrl, ctx);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit);
}
private void loadInitial(String token, String repoOwner, String repoName, String branchName) {
private void loadInitial(String token, String repoOwner, String repoName, String branchName, int resultLimit) {
Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, 1, branchName);
Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, 1, branchName, resultLimit);
call.enqueue(new Callback<List<Commits>>() {
@ -175,13 +174,13 @@ public class CommitsActivity extends BaseActivity {
}
private void loadMore(String token, String repoOwner, String repoName, final int page, String branchName) {
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);
Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, page, branchName, resultLimit);
call.enqueue(new Callback<List<Commits>>() {
@ -204,7 +203,6 @@ public class CommitsActivity extends BaseActivity {
}
else {
Toasty.info(ctx, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}

View File

@ -61,7 +61,7 @@ public class CreateFileActivity extends BaseActivity {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -146,7 +146,7 @@ public class CreateFileActivity extends BaseActivity {
private void processNewFile() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");

View File

@ -82,7 +82,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -153,7 +153,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private void processNewIssue() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");

View File

@ -73,7 +73,7 @@ public class CreateLabelActivity extends BaseActivity {
}
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
ImageView closeActivity = findViewById(R.id.close);
colorPicker = findViewById(R.id.colorPicker);
@ -154,7 +154,7 @@ public class CreateLabelActivity extends BaseActivity {
private void processUpdateLabel() {
final TinyDB tinyDb = new TinyDB(appCtx);
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
@ -202,7 +202,7 @@ public class CreateLabelActivity extends BaseActivity {
private void processCreateLabel() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");
@ -446,4 +446,4 @@ public class CreateLabelActivity extends BaseActivity {
}
}
}

View File

@ -50,7 +50,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -92,7 +92,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
private void processNewMilestone() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");

View File

@ -48,7 +48,7 @@ public class CreateNewUserActivity extends BaseActivity {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -80,7 +80,7 @@ public class CreateNewUserActivity extends BaseActivity {
private void processCreateNewUser() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");

View File

@ -47,7 +47,7 @@ public class CreateOrganizationActivity extends BaseActivity {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -97,7 +97,7 @@ public class CreateOrganizationActivity extends BaseActivity {
private void processNewOrganization() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");

View File

@ -60,7 +60,7 @@ public class CreateReleaseActivity extends BaseActivity {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -125,7 +125,7 @@ public class CreateReleaseActivity extends BaseActivity {
private void processNewRelease() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");

View File

@ -64,7 +64,7 @@ public class CreateRepoActivity extends BaseActivity {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(ctx);
boolean connToInternet = AppUtil.hasNetworkConnection(ctx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
@ -124,7 +124,7 @@ public class CreateRepoActivity extends BaseActivity {
private void processNewRepo() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");

View File

@ -78,7 +78,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -256,7 +256,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String orgName = tinyDb.getString("orgName");;
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String newTeamName = teamName.getText().toString();
String newTeamDesc = teamDesc.getText().toString();
String newTeamPermission = teamPermission.getText().toString().toLowerCase();

View File

@ -196,7 +196,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
private void processEditIssue() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");

View File

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

View File

@ -12,6 +12,7 @@ import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -22,7 +23,6 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.navigation.NavigationView;
import com.squareup.picasso.NetworkPolicy;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
@ -38,6 +38,7 @@ import org.mian.gitnex.fragments.StarredRepositoriesFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.ChangeLog;
import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.GiteaVersion;
@ -45,6 +46,8 @@ import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.Objects;
import eightbitlab.com.blurview.BlurView;
import eightbitlab.com.blurview.RenderScriptBlur;
import retrofit2.Call;
import retrofit2.Callback;
@ -55,9 +58,12 @@ import retrofit2.Callback;
public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
private BlurView blurView;
private TextView userFullName;
private TextView userEmail;
private ImageView userAvatar;
private ImageView userAvatarBackground;
private ViewGroup navHeaderFrame;
private TextView toolbarTitle;
final Context ctx = this;
private Context appCtx;
@ -100,7 +106,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
tinyDb.putInt("homeScreenId", 0);
}
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if(!tinyDb.getBoolean("loggedInMode")) {
logout(this, ctx);
@ -131,6 +137,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
FragmentManager fm = getSupportFragmentManager();
Fragment fragmentById = fm.findFragmentById(R.id.fragment_container);
if(fragmentById instanceof SettingsFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings));
}
@ -163,15 +170,10 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.darkGreen));
drawer.addDrawerListener(toggle);
drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
}
@Override
public void onDrawerOpened(@NonNull View drawerView) {
@ -184,78 +186,119 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
String userFullNameNav = tinyDb.getString("userFullname");
String userAvatarNav = tinyDb.getString("userAvatar");
blurView = hView.findViewById(R.id.blurView);
userEmail = hView.findViewById(R.id.userEmail);
userFullName = hView.findViewById(R.id.userFullname);
userAvatar = hView.findViewById(R.id.userAvatar);
userAvatarBackground = hView.findViewById(R.id.userAvatarBackground);
navHeaderFrame = hView.findViewById(R.id.navHeaderFrame);
userEmail.setTypeface(myTypeface);
userFullName.setTypeface(myTypeface);
navigationView.getMenu().findItem(R.id.nav_administration).setVisible(tinyDb.getBoolean("userIsAdmin"));
if(!userEmailNav.equals("")) {
userEmail.setText(userEmailNav);
userEmail.setTypeface(myTypeface);
}
userFullName = hView.findViewById(R.id.userFullname);
if(!userFullNameNav.equals("")) {
userFullName.setText(userFullNameNav);
userFullName.setTypeface(myTypeface);
}
userAvatar = hView.findViewById(R.id.userAvatar);
if(!userAvatarNav.equals("")) {
PicassoService.getInstance(ctx).get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
PicassoService.getInstance(ctx).get()
.load(userAvatarNav)
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0))
.resize(160, 160)
.centerCrop().into(userAvatar);
PicassoService.getInstance(ctx).get()
.load(userAvatarNav)
.into(userAvatarBackground, new com.squareup.picasso.Callback() {
@Override
public void onSuccess() {
int textColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground);
userFullName.setTextColor(textColor);
userEmail.setTextColor(textColor);
blurView.setupWith(navHeaderFrame)
.setBlurAlgorithm(new RenderScriptBlur(ctx))
.setBlurRadius(5)
.setHasFixedTransformationMatrix(false);
}
@Override
public void onError(Exception e) {}
});
}
userAvatar.setOnClickListener(new View.OnClickListener() {
userAvatar.setOnClickListener(v -> {
public void onClick(View v) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
drawer.closeDrawers();
}
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
drawer.closeDrawers();
});
}
@Override
public void onDrawerClosed(@NonNull View drawerView) {
// Called when a drawer has settled in a completely closed state.
}
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {}
@Override
public void onDrawerStateChanged(int newState) {
// Called when the drawer motion state changes. The new state will be one of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING.
}
public void onDrawerClosed(@NonNull View drawerView) {}
@Override
public void onDrawerStateChanged(int newState) {}
});
toggle.syncState();
if(savedInstanceState == null) {
if(tinyDb.getInt("homeScreenId") == 0) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home);
}
else if(tinyDb.getInt("homeScreenId") == 1) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_starred_repos);
}
else if(tinyDb.getInt("homeScreenId") == 2) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_organizations);
}
else if(tinyDb.getInt("homeScreenId") == 3) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_repositories);
}
else if(tinyDb.getInt("homeScreenId") == 4) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
}
else {
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home);
switch(tinyDb.getInt("homeScreenId")) {
case 1:
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_starred_repos);
break;
case 2:
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_organizations);
break;
case 3:
toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_repositories);
break;
case 4:
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
break;
default:
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home);
break;
}
}
if(!connToInternet) {
@ -269,7 +312,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
}
else {
displayUserInfo(instanceUrl, instanceToken, loginUid);
loadUserInfo(instanceUrl, instanceToken, loginUid);
giteaVersion(instanceUrl);
tinyDb.putBoolean("noConnection", false);
@ -314,46 +357,56 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch(menuItem.getItemId()) {
case R.id.nav_home:
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
break;
case R.id.nav_organizations:
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
break;
case R.id.nav_profile:
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
break;
case R.id.nav_repositories:
toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
break;
case R.id.nav_settings:
toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit();
break;
case R.id.nav_logout:
logout(this, ctx);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
break;
case R.id.nav_about:
toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit();
break;
case R.id.nav_rate_app:
rateThisApp();
break;
case R.id.nav_starred_repos:
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
break;
case R.id.nav_explore:
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreRepositoriesFragment()).commit();
break;
case R.id.nav_administration:
toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AdministrationFragment()).commit();
@ -422,15 +475,12 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
}
private void displayUserInfo(String instanceUrl, String token, String loginUid) {
private void loadUserInfo(String instanceUrl, String token, String loginUid) {
final TinyDB tinyDb = new TinyDB(appCtx);
Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo(Authorization.returnAuthentication(ctx, loginUid, token));
NavigationView navigationView = findViewById(R.id.nav_view);
final View hView = navigationView.getHeaderView(0);
call.enqueue(new Callback<UserInfo>() {
@Override
@ -443,12 +493,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
if(response.code() == 200) {
assert userDetails != null;
if(userDetails.getIs_admin() != null) {
tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin());
navigationView.getMenu().findItem(R.id.nav_administration).setVisible(userDetails.getIs_admin());
}
tinyDb.putString("userLogin", userDetails.getLogin());
tinyDb.putInt("userId", userDetails.getId());
if(!userDetails.getFullname().equals("")) {
tinyDb.putString("userFullname", userDetails.getFullname());
}
@ -458,51 +510,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
tinyDb.putString("userEmail", userDetails.getEmail());
tinyDb.putString("userAvatar", userDetails.getAvatar());
if(userDetails.getLang() != null) {
tinyDb.putString("userLang", userDetails.getLang());
}
else {
tinyDb.putString("userLang", "...");
tinyDb.putString("userLang", "");
}
userAvatar = hView.findViewById(R.id.userAvatar);
if(!Objects.requireNonNull(userDetails).getAvatar().equals("")) {
PicassoService.getInstance(ctx).get().load(userDetails.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
}
else {
userAvatar.setImageResource(R.mipmap.app_logo_round);
}
userFullName = hView.findViewById(R.id.userFullname);
if(!userDetails.getFullname().equals("")) {
userFullName.setText(userDetails.getFullname());
}
else if(!userDetails.getLogin().equals("")) {
userFullName.setText(userDetails.getLogin());
}
else {
userFullName.setText("...");
}
userEmail = hView.findViewById(R.id.userEmail);
if(!userDetails.getEmail().equals("")) {
userEmail.setText(userDetails.getEmail());
}
else {
userEmail.setText("...");
}
userAvatar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
drawer.closeDrawers();
}
});
}
}
else if(response.code() == 401) {
@ -511,7 +526,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
}
else {
String toastError = getResources().getString(R.string.genericApiStatusError) + String.valueOf(response.code());
String toastError = getResources().getString(R.string.genericApiStatusError) + response.code();
Toasty.info(ctx, toastError);
}

View File

@ -62,7 +62,7 @@ public class MergePullRequestActivity extends BaseActivity {
View view = viewBinding.getRoot();
setContentView(view);
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -217,7 +217,7 @@ public class MergePullRequestActivity extends BaseActivity {
String mergePRTitle = viewBinding.mergeTitle.getText().toString();
boolean deleteBranch = viewBinding.deleteBranch.isChecked();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if(!connToInternet) {

View File

@ -5,7 +5,13 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.PathsHelper;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
import java.net.URI;
import java.net.URISyntaxException;
import io.mikael.urlbuilder.UrlBuilder;
/**
* Author M M Arif
@ -18,20 +24,28 @@ public class OpenRepoInBrowserActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw");
if (!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol");
}
try {
String repoFullNameBrowser = getIntent().getStringExtra("repoFullNameBrowser");
Uri url = Uri.parse(instanceUrlWithProtocol + "/" + repoFullNameBrowser);
Intent i = new Intent(Intent.ACTION_VIEW, url);
startActivity(i);
finish();
URI instanceUrl = new URI(tinyDb.getString("instanceUrlWithProtocol"));
String browserPath = PathsHelper.join(instanceUrl.getPath(), getIntent().getStringExtra("repoFullNameBrowser"));
String browserUrl = UrlBuilder.fromUri(instanceUrl)
.withPath(browserPath)
.toString();
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(browserUrl));
startActivity(i);
finish();
}
catch(URISyntaxException e) {
Toasty.error(appCtx, getString(R.string.genericError));
}
}

View File

@ -49,7 +49,7 @@ public class ProfileEmailActivity extends BaseActivity {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -84,7 +84,7 @@ public class ProfileEmailActivity extends BaseActivity {
private void processAddNewEmail() {
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");

View File

@ -58,13 +58,13 @@ public class ReplyToIssueActivity extends BaseActivity {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
addComment = findViewById(R.id.addComment);
addComment.setShowSoftInputOnFocus(true);
defaultMentionAdapter = new MentionArrayAdapter<>(this);
defaultMentionAdapter = new MentionArrayAdapter<>(ctx);
loadCollaboratorsList();
addComment.setMentionAdapter(defaultMentionAdapter);
@ -191,7 +191,7 @@ public class ReplyToIssueActivity extends BaseActivity {
private void processNewCommentReply() {
String newReplyDT = addComment.getText().toString();
boolean connToInternet = AppUtil.haveNetworkConnection(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if(!connToInternet) {

View File

@ -42,7 +42,6 @@ import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.Objects;
import retrofit2.Call;
@ -63,59 +62,19 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
private FragmentRefreshListenerPr fragmentRefreshListenerPr;
private FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone;
final Context ctx = this;
private final Context ctx = this;
private Context appCtx;
// issues interface
public FragmentRefreshListener getFragmentRefreshListener() {
private TinyDB tinyDB;
return fragmentRefreshListener;
}
private String instanceUrl;
private String loginUid;
private String instanceToken;
public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) {
private String repositoryOwner;
private String repositoryName;
this.fragmentRefreshListener = fragmentRefreshListener;
}
public interface FragmentRefreshListener {
void onRefresh(String text);
}
// pr interface
public FragmentRefreshListenerPr getFragmentRefreshListenerPr() {
return fragmentRefreshListenerPr;
}
public void setFragmentRefreshListenerPr(FragmentRefreshListenerPr fragmentRefreshListenerPr) {
this.fragmentRefreshListenerPr = fragmentRefreshListenerPr;
}
public interface FragmentRefreshListenerPr {
void onRefresh(String text);
}
// milestones interface
public FragmentRefreshListenerMilestone getFragmentRefreshListenerMilestone() {
return fragmentRefreshListenerMilestone;
}
public void setFragmentRefreshListenerMilestone(FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone) {
this.fragmentRefreshListenerMilestone = fragmentRefreshListenerMilestone;
}
public interface FragmentRefreshListenerMilestone {
void onRefresh(String text);
}
private int tabsCount;
@Override
protected int getLayoutResourceId() {
@ -129,40 +88,32 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoName1 = parts[1];
tinyDB = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String repoOwner = parts[0];
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
tinyDb.putString("repoIssuesState", "open");
tinyDb.putString("repoPrState", "open");
tinyDb.putString("milestoneState", "open");
String appLocale = tinyDb.getString("locale");
AppUtil.setAppLocale(getResources(), appLocale);
String[] repoNameParts = tinyDB.getString("repoFullName").split("/");
repositoryOwner = repoNameParts[0];
repositoryName = repoNameParts[1];
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
toolbarTitle.setText(repositoryName);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(repoName1);
Objects.requireNonNull(getSupportActionBar()).setTitle(repositoryName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
instanceUrl = tinyDB.getString("instanceUrl");
loginUid = tinyDB.getString("loginUid");
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
ViewPager mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
tinyDB.putString("repoIssuesState", "open");
tinyDB.putString("repoPrState", "open");
tinyDB.putString("milestoneState", "open");
Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) {
switch(tinyDB.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
@ -179,34 +130,50 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
}
toolbarTitle.setTypeface(myTypeface);
toolbarTitle.setText(repoName1);
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
TabLayout tabLayout = findViewById(R.id.tabs);
ViewGroup viewGroup = (ViewGroup) tabLayout.getChildAt(0);
tabsCount = viewGroup.getChildCount();
for(int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
ViewGroup vgTab = (ViewGroup) viewGroup.getChildAt(j);
int tabChildCount = vgTab.getChildCount();
for(int i = 0; i < tabChildCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if(tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(myTypeface);
}
}
}
// only show Collaborators if you have permission to
final View collaboratorTab = vg.getChildAt(8);
if(tinyDb.getBoolean("isRepoAdmin")) {
// Only show collaborators tab, if you have permission to
View collaboratorTab = viewGroup.getChildAt(8);
if(tinyDB.getBoolean("isRepoAdmin") || new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
collaboratorTab.setVisibility(View.VISIBLE);
}
else {
tabsCount--;
collaboratorTab.setVisibility(View.GONE);
}
ViewPager mViewPager = findViewById(R.id.container);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
if(tinyDb.getBoolean("enableCounterBadges")) {
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);
@ -221,41 +188,48 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
textViewBadgePull.setVisibility(View.GONE);
textViewBadgeRelease.setVisibility(View.GONE);
getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName1);
getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
ColorStateList textColor = tabLayout.getTabTextColors();
// issue count
// Issue count
if(textViewBadgeIssue.getText() != "") {
TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2);
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2);
assert tabOpenIssues != null;
assert tabOpenIssues != null; // FIXME This should be cleaned up
TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeIssueText);
openIssueTabView.setTextColor(textColor);
}
// pull count
// 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;
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"))) {
// 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;
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), repoOwner, repoName1);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName1);
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
}
@ -263,17 +237,10 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("enableCounterIssueBadge")) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
if(tinyDB.getBoolean("enableCounterIssueBadge")) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
}
}
@ -293,27 +260,34 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
int id = item.getItemId();
switch(id) {
case android.R.id.home:
finish();
return true;
case R.id.repoMenu:
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment();
bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet");
return true;
case R.id.filter:
BottomSheetIssuesFilterFragment filterBottomSheet = new BottomSheetIssuesFilterFragment();
filterBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuBottomSheet");
return true;
case R.id.filterPr:
BottomSheetPullRequestFilterFragment filterPrBottomSheet = new BottomSheetPullRequestFilterFragment();
filterPrBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuPrBottomSheet");
return true;
case R.id.filterMilestone:
BottomSheetMilestonesFilterFragment filterMilestoneBottomSheet = new BottomSheetMilestonesFilterFragment();
filterMilestoneBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuMilestoneBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@ -321,68 +295,81 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
@Override
public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(appCtx);
switch(text) {
case "label":
startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class));
break;
case "newIssue":
startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class));
break;
case "newMilestone":
startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class));
break;
case "addCollaborator":
startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class));
break;
case "createRelease":
startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
break;
case "openWebRepo":
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(tinyDb.getString("repoHtmlUrl")));
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")));
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;
}
}
@ -398,54 +385,58 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
@Override
public Fragment getItem(int position) {
TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
Fragment fragment = null;
switch(position) {
case 0: // information
return RepoInfoFragment.newInstance(repoOwner, repoName);
case 1: // files
return FilesFragment.newInstance(repoOwner, repoName);
case 2: // issues
case 0: // Repository details
return RepoInfoFragment.newInstance(repositoryOwner, repositoryName);
case 1: // Files
return FilesFragment.newInstance(repositoryOwner, repositoryName);
case 2: // Issues
fragment = new IssuesFragment();
break;
case 3: // pull requests
case 3: // Pull requests
fragment = new PullRequestsFragment();
break;
case 4: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 5: // releases
return ReleasesFragment.newInstance(repoOwner, repoName);
case 6: // milestones
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(repoOwner, repoName);
case 8: // collaborators
return CollaboratorsFragment.newInstance(repoOwner, repoName);
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 9;
return tabsCount;
}
}
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) {
TinyDB tinyDb = new TinyDB(appCtx);
Call<UserRepositories> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserRepository(token, owner, repo);
call.enqueue(new Callback<UserRepositories>() {
@Override
@ -457,20 +448,23 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
if(response.code() == 200) {
if(tinyDb.getBoolean("enableCounterBadges")) {
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());
}
@ -480,6 +474,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
}
else {
Log.e("onFailure", String.valueOf(response.code()));
}
@ -497,17 +492,13 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) {
Call<JsonElement> call;
call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoStarStatus(instanceToken, owner, repo);
Call<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 tinyDb = new TinyDB(appCtx);
tinyDb.putInt("repositoryStarStatus", response.code());
tinyDB.putInt("repositoryStarStatus", response.code());
}
@ -525,22 +516,23 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoWatchStatus(instanceToken, owner, repo);
call.enqueue(new Callback<WatchInfo>() {
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
TinyDB tinyDb = new TinyDB(appCtx);
if(response.code() == 200) {
assert response.body() != null;
if(response.body().getSubscribed()) {
tinyDb.putBoolean("repositoryWatchStatus", true);
tinyDB.putBoolean("repositoryWatchStatus", true);
}
}
else {
tinyDb.putBoolean("repositoryWatchStatus", false);
tinyDB.putBoolean("repositoryWatchStatus", false);
}
}
@ -554,4 +546,25 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
}
// 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); }
}

View File

@ -201,7 +201,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
AlertDialog.Builder hsBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this);
hsBuilder.setTitle(R.string.settingshomeScreenSelectorDialogTitle);
hsBuilder.setTitle(R.string.settingsHomeScreenSelectorDialogTitle);
if(homeScreenSelectedChoice != -1) {
hsBuilder.setCancelable(true);
}

View File

@ -9,6 +9,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
@ -58,6 +59,8 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private ReposSearchViewHolder(View itemView) {
@ -73,6 +76,8 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
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);
itemView.setOnClickListener(v -> {
@ -150,7 +155,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullName.getText());
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();
@ -230,9 +235,11 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
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);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
@ -242,6 +249,13 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override

View File

@ -165,6 +165,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
holder.fileInfo.setText(AppUtil.formatFileSizeInDetail(currentItem.getSize()));
}
else if(currentItem.getType().equals("dir")) {
holder.fileInfo.setVisibility(View.GONE);
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_folder_24));
}
else {

View File

@ -86,7 +86,7 @@ public class FilesDiffAdapter extends BaseAdapter {
FileDiffView data = (FileDiffView) getItem(position);
headerFileName.setText(data.getFileName());
if(data.isFileType()) {
if(data.isFileBinary()) {
diffStats.setVisibility(View.GONE);
diffLines.addView(getMessageView(context.getResources().getString(R.string.binaryFileError)));
@ -97,7 +97,7 @@ public class FilesDiffAdapter extends BaseAdapter {
diffStats.setVisibility(View.VISIBLE);
headerFileInfo.setText(data.getFileInfo());
String[] codeLines = getLines(data.getFileContents());
String[] codeLines = getLines(data.toString());
if(MAXIMUM_LINES > codeLines.length) {

View File

@ -1,6 +1,8 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
@ -104,6 +106,8 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit);
TextView commentShare = view.findViewById(R.id.issueCommentShare);
TextView commentMenuQuote = view.findViewById(R.id.commentMenuQuote);
TextView commentMenuCopy = view.findViewById(R.id.commentMenuCopy);
TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete);
if(!loginUid.contentEquals(commenterUsername.getText())) {
@ -111,6 +115,10 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
commentMenuDelete.setVisibility(View.GONE);
}
if(issueComment.getText().toString().isEmpty()) {
commentMenuCopy.setVisibility(View.GONE);
}
BottomSheetDialog dialog = new BottomSheetDialog(ctx);
dialog.setContentView(view);
dialog.show();
@ -143,6 +151,48 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
});
commentMenuQuote.setOnClickListener(v1 -> {
StringBuilder stringBuilder = new StringBuilder();
String commenterName = commenterUsername.getText().toString();
if(!commenterName.equals(tinyDb.getString("userLogin"))) {
stringBuilder.append("@").append(commenterName).append("\n\n");
}
String[] lines = commendBodyRaw.getText().toString().split("\\R");
for(String line : lines) {
stringBuilder.append(">").append(line).append("\n");
}
stringBuilder.append("\n");
Intent intent = new Intent(ctx, ReplyToIssueActivity.class);
intent.putExtra("commentBody", stringBuilder.toString());
intent.putExtra("cursorToEnd", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialog.dismiss();
ctx.startActivity(intent);
});
commentMenuCopy.setOnClickListener(view1 -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
assert clipboard != null;
ClipData clip = ClipData.newPlainText("Comment on issue #" + issueNumber.getText().toString(), issueComment.getText().toString());
clipboard.setPrimaryClip(clip);
dialog.dismiss();
Toasty.info(ctx, ctx.getString(R.string.copyIssueCommentToastMsg));
});
commentMenuDelete.setOnClickListener(deleteComment -> {
deleteIssueComment(ctx, Integer.parseInt(commendId.getText().toString()), getAdapterPosition());

View File

@ -3,26 +3,25 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.core.widget.ImageViewCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.CreateLabelActivity;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.models.Labels;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
* Author M M Arif
@ -39,12 +38,17 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
private TextView labelTitle;
private TextView labelId;
private TextView labelColor;
private ImageView labelsView;
private CardView labelView;
private ImageView labelIcon;
private TextView labelName;
private LabelsViewHolder(View itemView) {
super(itemView);
labelsView = itemView.findViewById(R.id.labelsView);
labelView = itemView.findViewById(R.id.labelView);
labelIcon = itemView.findViewById(R.id.labelIcon);
labelName = itemView.findViewById(R.id.labelName);
ImageView labelsOptionsMenu = itemView.findViewById(R.id.labelsOptionsMenu);
labelTitle = itemView.findViewById(R.id.labelTitle);
labelId = itemView.findViewById(R.id.labelId);
@ -119,19 +123,13 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
String labelName = currentItem.getName();
int color = Color.parseColor("#" + labelColor);
int contrastColor = new ColorInverter().getContrastColor(color);
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.bold()
.textColor(new ColorInverter().getContrastColor(color))
.fontSize(35)
.width(LabelWidthCalculator.calculateLabelWidth(labelName, Typeface.DEFAULT, 40, 20))
.height(55)
.endConfig()
.buildRoundRect(labelName, color, 10);
ImageViewCompat.setImageTintList(holder.labelIcon, ColorStateList.valueOf(contrastColor));
holder.labelsView.setImageDrawable(drawable);
holder.labelName.setTextColor(contrastColor);
holder.labelName.setText(labelName);
holder.labelView.setCardBackgroundColor(color);
}
@ -140,4 +138,4 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
return labelsList.size();
}
}
}

View File

@ -2,7 +2,6 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Spanned;
@ -15,7 +14,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R;
@ -56,369 +54,346 @@ import io.noties.markwon.linkify.LinkifyPlugin;
public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private final int TYPE_LOAD = 0;
private List<Milestones> dataList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false;
private boolean isMoreDataAvailable = true;
private String TAG = StaticGlobalVariables.tagMilestonesAdapter;
private Context context;
private final int TYPE_LOAD = 0;
private List<Milestones> dataList;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false;
private boolean isMoreDataAvailable = true;
private String TAG = StaticGlobalVariables.tagMilestonesAdapter;
public MilestonesAdapter(Context context, List<Milestones> dataListMain) {
public MilestonesAdapter(Context context, List<Milestones> dataListMain) {
this.context = context;
this.dataList = dataListMain;
this.context = context;
this.dataList = dataListMain;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new MilestonesAdapter.DataHolder(inflater.inflate(R.layout.list_milestones, parent, false));
}
else {
return new MilestonesAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
if(viewType == TYPE_LOAD) {
return new MilestonesAdapter.DataHolder(inflater.inflate(R.layout.list_milestones, parent, false));
}
else {
return new MilestonesAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
@Override
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;
loadMoreListener.onLoadMore();
isLoading = true;
loadMoreListener.onLoadMore();
}
}
if(getItemViewType(position) == TYPE_LOAD) {
if(getItemViewType(position) == TYPE_LOAD) {
((MilestonesAdapter.DataHolder) holder).bindData(dataList.get(position));
((MilestonesAdapter.DataHolder) holder).bindData(dataList.get(position));
}
}
}
}
class DataHolder extends RecyclerView.ViewHolder {
class DataHolder extends RecyclerView.ViewHolder {
private TextView milestoneId;
private TextView msTitle;
private TextView msDescription;
private TextView msOpenIssues;
private TextView msClosedIssues;
private TextView msDueDate;
private ImageView msStatus;
private ProgressBar msProgress;
private TextView milestoneStatus;
private TextView milestoneId;
private TextView msTitle;
private TextView msDescription;
private TextView msOpenIssues;
private TextView msClosedIssues;
private TextView msDueDate;
private ProgressBar msProgress;
private TextView milestoneStatus;
DataHolder(View itemView) {
DataHolder(View itemView) {
super(itemView);
super(itemView);
milestoneId = itemView.findViewById(R.id.milestoneId);
msTitle = itemView.findViewById(R.id.milestoneTitle);
msStatus = itemView.findViewById(R.id.milestoneState);
msDescription = itemView.findViewById(R.id.milestoneDescription);
msOpenIssues = itemView.findViewById(R.id.milestoneIssuesOpen);
msClosedIssues = itemView.findViewById(R.id.milestoneIssuesClosed);
msDueDate = itemView.findViewById(R.id.milestoneDueDate);
msProgress = itemView.findViewById(R.id.milestoneProgress);
ImageView milestonesMenu = itemView.findViewById(R.id.milestonesMenu);
milestoneStatus = itemView.findViewById(R.id.milestoneStatus);
milestoneId = itemView.findViewById(R.id.milestoneId);
msTitle = itemView.findViewById(R.id.milestoneTitle);
msDescription = itemView.findViewById(R.id.milestoneDescription);
msOpenIssues = itemView.findViewById(R.id.milestoneIssuesOpen);
msClosedIssues = itemView.findViewById(R.id.milestoneIssuesClosed);
msDueDate = itemView.findViewById(R.id.milestoneDueDate);
msProgress = itemView.findViewById(R.id.milestoneProgress);
ImageView milestonesMenu = itemView.findViewById(R.id.milestonesMenu);
milestoneStatus = itemView.findViewById(R.id.milestoneStatus);
milestonesMenu.setOnClickListener(v -> {
milestonesMenu.setOnClickListener(v -> {
Context ctx = v.getContext();
int milestoneId_ = Integer.parseInt(milestoneId.getText().toString());
Context ctx = v.getContext();
int milestoneId_ = Integer.parseInt(milestoneId.getText().toString());
@SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_milestones_in_list, null);
@SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_milestones_in_list, null);
TextView closeMilestone = view.findViewById(R.id.closeMilestone);
TextView openMilestone = view.findViewById(R.id.openMilestone);
TextView closeMilestone = view.findViewById(R.id.closeMilestone);
TextView openMilestone = view.findViewById(R.id.openMilestone);
BottomSheetDialog dialog = new BottomSheetDialog(ctx);
dialog.setContentView(view);
dialog.show();
BottomSheetDialog dialog = new BottomSheetDialog(ctx);
dialog.setContentView(view);
dialog.show();
if(milestoneStatus.getText().toString().equals("open")) {
if(milestoneStatus.getText().toString().equals("open")) {
closeMilestone.setVisibility(View.VISIBLE);
openMilestone.setVisibility(View.GONE);
closeMilestone.setVisibility(View.VISIBLE);
openMilestone.setVisibility(View.GONE);
}
else {
}
else {
closeMilestone.setVisibility(View.GONE);
openMilestone.setVisibility(View.VISIBLE);
closeMilestone.setVisibility(View.GONE);
openMilestone.setVisibility(View.VISIBLE);
}
}
closeMilestone.setOnClickListener(v12 -> {
closeMilestone.setOnClickListener(v12 -> {
MilestoneActions.closeMilestone(ctx, milestoneId_);
dialog.dismiss();
updateAdapter(getAdapterPosition());
MilestoneActions.closeMilestone(ctx, milestoneId_);
dialog.dismiss();
updateAdapter(getAdapterPosition());
});
});
openMilestone.setOnClickListener(v12 -> {
openMilestone.setOnClickListener(v12 -> {
MilestoneActions.openMilestone(ctx, milestoneId_);
dialog.dismiss();
updateAdapter(getAdapterPosition());
MilestoneActions.openMilestone(ctx, milestoneId_);
dialog.dismiss();
updateAdapter(getAdapterPosition());
});
});
});
});
}
@SuppressLint("SetTextI18n")
void bindData(Milestones dataModel) {
final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
}
milestoneId.setText(String.valueOf(dataModel.getId()));
milestoneStatus.setText(dataModel.getState());
@SuppressLint("SetTextI18n")
void bindData(Milestones dataModel) {
final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
.usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = context.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
context.getPackageName());
final Drawable drawable = context.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(context.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(context.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(context.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(context))
.usePlugin(TaskListPlugin.create(context))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
Spanned msTitle_ = markwon.toMarkdown(dataModel.getTitle());
markwon.setParsedMarkdown(msTitle, msTitle_);
if(dataModel.getState().equals("open")) {
@SuppressLint("ResourceType") int color = Color.parseColor(context.getResources().getString(R.color.releaseStable));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
//.useFont(Typeface.DEFAULT)
.textColor(context.getResources().getColor(R.color.white))
.fontSize(30)
.toUpperCase()
.width(120)
.height(60)
.endConfig()
.buildRoundRect("open", color, 8);
msStatus.setImageDrawable(drawable);
}
else if(dataModel.getState().equals("closed")) {
@SuppressLint("ResourceType") int color = Color.parseColor(context.getResources().getString(R.color.colorRed));
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
//.useFont(Typeface.DEFAULT)
.textColor(context.getResources().getColor(R.color.white))
.fontSize(30)
.toUpperCase()
.width(140)
.height(60)
.endConfig()
.buildRoundRect("closed", color, 8);
msStatus.setImageDrawable(drawable);
}
if (!dataModel.getDescription().equals("")) {
final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(dataModel.getDescription()));
msDescription.setText(bodyWithMD);
}
else {
msDescription.setText("");
}
msOpenIssues.setText(String.valueOf(dataModel.getOpen_issues()));
msOpenIssues.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneOpenIssues, dataModel.getOpen_issues()), context));
msClosedIssues.setText(String.valueOf(dataModel.getClosed_issues()));
msClosedIssues.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneClosedIssues, dataModel.getClosed_issues()), context));
if ((dataModel.getOpen_issues() + dataModel.getClosed_issues()) > 0) {
if (dataModel.getOpen_issues() == 0) {
msProgress.setProgress(100);
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 100), context));
}
else {
int msCompletion = 100 * dataModel.getClosed_issues() / (dataModel.getOpen_issues() + dataModel.getClosed_issues());
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, msCompletion), context));
msProgress.setProgress(msCompletion);
}
}
else {
msProgress.setProgress(0);
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 0), context));
}
if(dataModel.getDue_on() != null) {
if (timeFormat.equals("normal") || timeFormat.equals("pretty")) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
Date date = null;
try {
date = formatter.parse(dataModel.getDue_on());
}
catch (ParseException e) {
Log.e(TAG, e.toString());
}
assert date != null;
String dueDate = formatter.format(date);
final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
if(date.before(new Date())) {
msDueDate.setTextColor(context.getResources().getColor(R.color.darkRed));
}
milestoneId.setText(String.valueOf(dataModel.getId()));
milestoneStatus.setText(dataModel.getState());
msDueDate.setText(dueDate);
msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(dataModel.getDue_on()), context));
Markwon markwon = Markwon.builder(Objects.requireNonNull(context)).usePlugin(CorePlugin.create()).usePlugin(ImagesPlugin.create(plugin -> {
plugin.addSchemeHandler(new SchemeHandler() {
}
else if (timeFormat.equals("normal1")) {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
Date date1 = null;
try {
date1 = formatter.parse(dataModel.getDue_on());
}
catch (ParseException e) {
Log.e(TAG, e.toString());
}
assert date1 != null;
String dueDate = formatter.format(date1);
msDueDate.setText(dueDate);
final int resourceId = context.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
context.getPackageName());
}
final Drawable drawable = context.getDrawable(resourceId);
}
else {
msDueDate.setText("");
}
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(context.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(context.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
private void updateAdapter(int position) {
}))
dataList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, dataList.size());
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(context.getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(context))
.usePlugin(TaskListPlugin.create(context))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
}
Spanned msTitle_ = markwon.toMarkdown(dataModel.getTitle());
markwon.setParsedMarkdown(msTitle, msTitle_);
@Override
public int getItemViewType(int position) {
if(!dataModel.getDescription().equals("")) {
if(dataList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(dataModel.getDescription()));
msDescription.setText(bodyWithMD);
}
}
else {
@Override
public int getItemCount() {
msDescription.setText(context.getString(R.string.milestoneNoDescription));
}
return dataList.size();
msOpenIssues.setText(context.getString(R.string.milestoneIssueStatusOpen, dataModel.getOpen_issues()));
msClosedIssues.setText(context.getString(R.string.milestoneIssueStatusClosed, dataModel.getClosed_issues()));
}
if((dataModel.getOpen_issues() + dataModel.getClosed_issues()) > 0) {
static class LoadHolder extends RecyclerView.ViewHolder {
if(dataModel.getOpen_issues() == 0) {
LoadHolder(View itemView) {
msProgress.setProgress(100);
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 100), context));
super(itemView);
}
}
else {
}
int msCompletion = 100 * dataModel.getClosed_issues() / (dataModel.getOpen_issues() + dataModel.getClosed_issues());
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, msCompletion), context));
msProgress.setProgress(msCompletion);
public void setMoreDataAvailable(boolean moreDataAvailable) {
}
isMoreDataAvailable = moreDataAvailable;
}
else {
}
msProgress.setProgress(0);
msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 0), context));
public void notifyDataChanged() {
}
notifyDataSetChanged();
isLoading = false;
if(dataModel.getDue_on() != null) {
}
if(timeFormat.equals("normal") || timeFormat.equals("pretty")) {
public interface OnLoadMoreListener {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
Date date = null;
void onLoadMore();
try {
date = formatter.parse(dataModel.getDue_on());
}
catch(ParseException e) {
Log.e(TAG, e.toString());
}
}
assert date != null;
String dueDate = formatter.format(date);
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
if(date.before(new Date())) {
msDueDate.setTextColor(context.getResources().getColor(R.color.darkRed));
}
this.loadMoreListener = loadMoreListener;
msDueDate.setText(dueDate);
msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(dataModel.getDue_on()), context));
}
}
else if(timeFormat.equals("normal1")) {
public void updateList(List<Milestones> list) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
dataList = list;
notifyDataSetChanged();
}
Date date1 = null;
try {
date1 = formatter.parse(dataModel.getDue_on());
}
catch(ParseException e) {
Log.e(TAG, e.toString());
}
assert date1 != null;
String dueDate = formatter.format(date1);
msDueDate.setText(dueDate);
}
}
else {
msDueDate.setText(context.getString(R.string.milestoneNoDueDate));
}
}
}
private void updateAdapter(int position) {
dataList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, dataList.size());
}
@Override
public int getItemViewType(int position) {
if(dataList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return dataList.size();
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<Milestones> list) {
dataList = list;
notifyDataSetChanged();
}
}

View File

@ -11,6 +11,7 @@ import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
@ -56,6 +57,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
private TextView repoOpenIssuesCount;
private TextView repoType;
private CheckBox isRepoAdmin;
private LinearLayout archiveRepo;
private MyReposViewHolder(View itemView) {
super(itemView);
@ -70,6 +72,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
itemView.setOnClickListener(v -> {
@ -148,7 +151,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(repoFullName.getText());
bottomSheetHeader.setText(String.format("%s / %s", repoFullName.getText().toString().split("/")[0], repoFullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
@ -252,6 +255,13 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override

View File

@ -188,9 +188,18 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
prNumber.setText(String.valueOf(prModel.getNumber()));
prMergeable.setText(String.valueOf(prModel.isMergeable()));
prHeadBranch.setText(prModel.getHead().getRef());
prIsFork.setText(String.valueOf(prModel.getHead().getRepo().isFork()));
prForkFullName.setText(prModel.getHead().getRepo().getFull_name());
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));

View File

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

View File

@ -0,0 +1,68 @@
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

@ -109,13 +109,6 @@ public class RepoStargazersAdapter extends BaseAdapter {
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

@ -109,13 +109,6 @@ public class RepoWatchersAdapter extends BaseAdapter {
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

@ -11,6 +11,7 @@ import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
@ -56,6 +57,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private ReposViewHolder(View itemView) {
@ -71,6 +73,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
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);
itemView.setOnClickListener(v -> {
@ -150,7 +153,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullName.getText());
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();
@ -249,6 +252,13 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override

View File

@ -11,6 +11,7 @@ import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
@ -56,6 +57,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private OrgReposViewHolder(View itemView) {
super(itemView);
@ -70,6 +72,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
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);
itemView.setOnClickListener(v -> {
@ -147,7 +150,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullName.getText());
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();
@ -252,6 +255,13 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override

View File

@ -11,6 +11,7 @@ import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
@ -56,6 +57,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private StarredReposViewHolder(View itemView) {
super(itemView);
@ -70,6 +72,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
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);
itemView.setOnClickListener(v -> {
@ -148,7 +151,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullName.getText());
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();
@ -252,6 +255,13 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override

View File

@ -111,12 +111,5 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
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

@ -104,12 +104,11 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter<UserSea
if (!currentItem.getFullname().equals("")) {
holder.userFullName.setText(currentItem.getFullname());
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
}
else {
holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
}
holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
if (!currentItem.getAvatar().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar);
@ -123,7 +122,6 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter<UserSea
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<UserInfo> call = RetrofitClient

View File

@ -27,7 +27,7 @@ public class AppApiService {
public static <S> S createService(Class<S> serviceClass, String instanceURL, Context ctx) {
TinyDB tinyDb = new TinyDB(ctx);
final boolean connToInternet = AppUtil.haveNetworkConnection(ctx);
final boolean connToInternet = AppUtil.hasNetworkConnection(ctx);
File httpCacheDirectory = new File(ctx.getCacheDir(), "responses");
int cacheSize = FilesData.returnOnlyNumber(tinyDb.getString("cacheSizeStr")) * 1024 * 1024;
Cache cache = new Cache(httpCacheDirectory, cacheSize);

View File

@ -14,16 +14,18 @@ import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
/**
* Author anonTree1417
* Author opyale
*/
public class PicassoService {
private static PicassoService picassoService;
private static File cachePath;
private Picasso picasso;
private PicassoService(Context context) {
cachePath = new File(context.getCacheDir() + "/picasso_cache/");
Picasso.Builder builder = new Picasso.Builder(context);
try {
@ -45,10 +47,6 @@ public class PicassoService {
});
File cachePath = new File(context.getCacheDir() + "/picasso_cache/");
//noinspection ResultOfMethodCallIgnored
cachePath.mkdirs();
picasso = builder.memoryCache(new PicassoCache(cachePath, context)).build();
}
@ -61,7 +59,9 @@ public class PicassoService {
public Picasso get() {
cachePath.mkdirs();
return picasso;
}
public static synchronized PicassoService getInstance(Context context) {

View File

@ -32,7 +32,7 @@ public class RetrofitClient {
private RetrofitClient(String instanceUrl, Context ctx) {
TinyDB tinyDb = new TinyDB(ctx);
final boolean connToInternet = AppUtil.haveNetworkConnection(ctx);
final boolean connToInternet = AppUtil.hasNetworkConnection(ctx);
int cacheSize = FilesData.returnOnlyNumber(tinyDb.getString("cacheSizeStr")) * 1024 * 1024;
File httpCacheDirectory = new File(ctx.getCacheDir(), "responses");
Cache cache = new Cache(httpCacheDirectory, cacheSize);

View File

@ -71,13 +71,14 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
}
});
addCollaborator.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("addCollaborator");
dismiss();
}
});
if (tinyDb.getBoolean("isRepoAdmin")) {
addCollaborator.setOnClickListener(v1 -> {
bmListener.onButtonClicked("addCollaborator");
dismiss();
});
} else {
addCollaborator.setVisibility(View.GONE);
}
createRelease.setOnClickListener(new View.OnClickListener() {
@Override

View File

@ -19,10 +19,14 @@ import org.mian.gitnex.activities.AddRemoveLabelsActivity;
import org.mian.gitnex.activities.EditIssueActivity;
import org.mian.gitnex.activities.FileDiffActivity;
import org.mian.gitnex.activities.MergePullRequestActivity;
import org.mian.gitnex.helpers.PathsHelper;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.util.TinyDB;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Objects;
import io.mikael.urlbuilder.UrlBuilder;
/**
* Author M M Arif
@ -64,7 +68,10 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
mergePullRequest.setVisibility(View.VISIBLE);
}
if(tinyDB.getString("repoType").equals("public")) {
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.13.0")) {
openFilesDiff.setVisibility(View.VISIBLE);
}
else if(tinyDB.getString("repoType").equals("public")) {
openFilesDiff.setVisibility(View.VISIBLE);
}
else {
@ -135,53 +142,61 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
shareIssue.setOnClickListener(v1 -> {
// get url of repo
String repoFullName = tinyDB.getString("repoFullName");
String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw");
if(!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol");
try {
URI instanceUrl = new URI(tinyDB.getString("instanceUrlWithProtocol"));
String issuePath = PathsHelper.join(instanceUrl.getPath(), tinyDB.getString("repoFullName"), "/issues/", tinyDB.getString("issueNumber"));
String issueUrl = UrlBuilder.fromUri(instanceUrl)
.withPath(issuePath)
.toString();
// share issue
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, issueUrl);
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle")));
}
catch(URISyntaxException e) {
Toasty.error(ctx, getString(R.string.genericError));
}
finally {
dismiss();
}
// get issue Url
String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber");
// share issue
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, issueUrl);
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle")));
dismiss();
});
copyIssueUrl.setOnClickListener(new View.OnClickListener() {
copyIssueUrl.setOnClickListener(v12 -> {
@Override
public void onClick(View v) {
try {
// get url of repo
String repoFullName = tinyDB.getString("repoFullName");
String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw");
if(!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol");
}
URI instanceUrl = new URI(tinyDB.getString("instanceUrlWithProtocol"));
// get issue Url
String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber");
String issuePath = PathsHelper.join(instanceUrl.getPath(), tinyDB.getString("repoFullName"), "/issues/", tinyDB.getString("issueNumber"));
String issueUrl = UrlBuilder.fromUri(instanceUrl)
.withPath(issuePath)
.toString();
// copy to clipboard
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(android.content.Context.CLIPBOARD_SERVICE);
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("issueUrl", issueUrl);
assert clipboard != null;
clipboard.setPrimaryClip(clip);
dismiss();
Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg));
}
catch(URISyntaxException e) {
Toasty.error(ctx, getString(R.string.genericError));
}
finally {
dismiss();
}
});
if(tinyDB.getString("issueType").equals("issue")) {

View File

@ -325,6 +325,9 @@ public class IssuesFragment extends Fragment {
List<Issues> arr = new ArrayList<>();
for(Issues d : issuesList) {
if(d == null || d.getTitle() == null || d.getBody() == null) {
continue;
}
if(d.getTitle().toLowerCase().contains(text) || d.getBody().toLowerCase().contains(text)) {
arr.add(d);
}

View File

@ -104,7 +104,7 @@ public class MembersByOrgFragment extends Fragment {
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);

View File

@ -77,16 +77,20 @@ public class MilestonesFragment extends Fragment {
dataList = new ArrayList<>();
adapter = new MilestonesAdapter(ctx, dataList);
adapter.setLoadMoreListener(() -> viewBinding.recyclerView.post(() -> {
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
if(dataList.size() == resultLimit || pageSize == resultLimit) {
adapter.setLoadMoreListener(() -> viewBinding.recyclerView.post(() -> {
int page = (dataList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, tinyDb.getString("milestoneState"));
if(dataList.size() == resultLimit || pageSize == resultLimit) {
}
int page = (dataList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, tinyDb.getString("milestoneState"));
}));
}
}));
}
viewBinding.recyclerView.setHasFixedSize(true);
viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx));
@ -113,16 +117,21 @@ public class MilestonesFragment extends Fragment {
dataList.clear();
adapter = new MilestonesAdapter(ctx, dataList);
adapter.setLoadMoreListener(() -> viewBinding.recyclerView.post(() -> {
if(dataList.size() == resultLimit || pageSize == resultLimit) {
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
int page = (dataList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, milestoneState);
adapter.setLoadMoreListener(() -> viewBinding.recyclerView.post(() -> {
}
if(dataList.size() == resultLimit || pageSize == resultLimit) {
}));
int page = (dataList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, milestoneState);
}
}));
}
tinyDb.putString("milestoneState", milestoneState);
@ -171,7 +180,7 @@ public class MilestonesFragment extends Fragment {
@Override
public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull Response<List<Milestones>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
assert response.body() != null;
if(response.body().size() > 0) {
@ -222,7 +231,7 @@ public class MilestonesFragment extends Fragment {
@Override
public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull Response<List<Milestones>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
//remove loading view
dataList.remove(dataList.size() - 1);
@ -238,7 +247,6 @@ public class MilestonesFragment extends Fragment {
}
else {
Toasty.info(ctx, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}
@ -310,6 +318,9 @@ public class MilestonesFragment extends Fragment {
List<Milestones> arr = new ArrayList<>();
for(Milestones d : dataList) {
if(d == null || d.getTitle() == null || d.getDescription() == null) {
continue;
}
if(d.getTitle().toLowerCase().contains(text) || d.getDescription().toLowerCase().contains(text)) {
arr.add(d);
}

View File

@ -81,7 +81,7 @@ public class MyRepositoriesFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
final View v = inflater.inflate(R.layout.fragment_my_repositories, container, false);
setHasOptionsMenu(true);
@ -196,7 +196,7 @@ public class MyRepositoriesFragment extends Fragment {
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);

View File

@ -3,17 +3,16 @@ package org.mian.gitnex.fragments;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import retrofit2.Call;
import retrofit2.Callback;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
@ -21,6 +20,8 @@ import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.Organization;
import org.mian.gitnex.util.TinyDB;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
@ -37,6 +38,7 @@ public class OrganizationInfoFragment extends Fragment {
private TextView orgDescInfo;
private TextView orgWebsiteInfo;
private TextView orgLocationInfo;
private LinearLayout orgInfoLayout;
private RepoInfoFragment.OnFragmentInteractionListener mListener;
@ -76,6 +78,7 @@ public class OrganizationInfoFragment extends Fragment {
orgDescInfo = v.findViewById(R.id.orgDescInfo);
orgWebsiteInfo = v.findViewById(R.id.orgWebsiteInfo);
orgLocationInfo = v.findViewById(R.id.orgLocationInfo);
orgInfoLayout = v.findViewById(R.id.orgInfoLayout);
orgNameInfo.setText(orgName);
@ -99,19 +102,46 @@ public class OrganizationInfoFragment extends Fragment {
Organization orgInfo = response.body();
if (response.isSuccessful()) {
if (response.code() == 200) {
if (response.code() == 200) {
orgInfoLayout.setVisibility(View.VISIBLE);
assert orgInfo != null;
PicassoService.getInstance(ctx).get().load(orgInfo.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(orgAvatar);
orgDescInfo.setText(orgInfo.getDescription());
orgWebsiteInfo.setText(orgInfo.getWebsite());
orgLocationInfo.setText(orgInfo.getLocation());
assert orgInfo != null;
mProgressBar.setVisibility(View.GONE);
PicassoService.getInstance(ctx).get()
.load(orgInfo.getAvatar_url())
.placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0))
.resize(230, 230)
.centerCrop().into(orgAvatar);
if(!orgInfo.getDescription().isEmpty()) {
orgDescInfo.setText(orgInfo.getDescription());
}
else {
orgDescInfo.setText(getString(R.string.noDataDescription));
}
if(!orgInfo.getWebsite().isEmpty()) {
orgWebsiteInfo.setText(orgInfo.getWebsite());
}
else {
orgWebsiteInfo.setText(getString(R.string.noDataWebsite));
}
if(!orgInfo.getLocation().isEmpty()) {
orgLocationInfo.setText(orgInfo.getLocation());
}
else {
orgLocationInfo.setText(getString(R.string.noDataLocation));
}
mProgressBar.setVisibility(View.GONE);
}
else if(response.code() == 404) {
mProgressBar.setVisibility(View.GONE);
}
else {

View File

@ -52,7 +52,7 @@ public class OrganizationsFragment extends Fragment {
final View v = inflater.inflate(R.layout.fragment_organizations, container, false);
setHasOptionsMenu(true);
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
@ -158,7 +158,7 @@ public class OrganizationsFragment extends Fragment {
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);

View File

@ -1,14 +1,9 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -17,13 +12,25 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.ImageViewCompat;
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.squareup.picasso.Callback;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB;
import java.util.Locale;
import java.util.Objects;
import eightbitlab.com.blurview.BlurView;
import eightbitlab.com.blurview.RenderScriptBlur;
/**
* Author M M Arif
@ -31,26 +38,80 @@ import java.util.Objects;
public class ProfileFragment extends Fragment {
private Context ctx = getContext();
private Context ctx;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ctx = getContext();
View v = inflater.inflate(R.layout.fragment_profile, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
BlurView blurView = v.findViewById(R.id.blurView);
TextView userFullName = v.findViewById(R.id.userFullName);
ImageView userAvatarBackground = v.findViewById(R.id.userAvatarBackground);
ImageView userAvatar = v.findViewById(R.id.userAvatar);
TextView userLogin = v.findViewById(R.id.userLogin);
TextView userEmail = v.findViewById(R.id.userEmail);
View divider = v.findViewById(R.id.divider);
TextView userLanguage = v.findViewById(R.id.userLanguage);
ImageView userLanguageIcon = v.findViewById(R.id.userLanguageIcon);
ViewGroup aboutFrame = v.findViewById(R.id.aboutFrame);
String[] userLanguageCodes = tinyDb.getString("userLang").split("-");
if(userLanguageCodes.length >= 2) {
Locale locale = new Locale(userLanguageCodes[0], userLanguageCodes[1]);
userLanguage.setText(locale.getDisplayCountry());
}
else {
userLanguage.setText(R.string.notSupported);
}
userFullName.setText(tinyDb.getString("userFullname"));
userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin")));
PicassoService.getInstance(ctx).get()
.load(tinyDb.getString("userAvatar"))
.transform(new RoundedTransformation(8, 0))
.placeholder(R.drawable.loader_animated)
.resize(120, 120)
.centerCrop().into(userAvatar);
PicassoService.getInstance(ctx).get()
.load(tinyDb.getString("userAvatar"))
.into(userAvatarBackground, new Callback() {
@Override
public void onSuccess() {
int invertedColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground);
userFullName.setTextColor(invertedColor);
divider.setBackgroundColor(invertedColor);
userLogin.setTextColor(invertedColor);
userLanguage.setTextColor(invertedColor);
ImageViewCompat.setImageTintList(userLanguageIcon, ColorStateList.valueOf(invertedColor));
blurView.setupWith(aboutFrame)
.setBlurAlgorithm(new RenderScriptBlur(ctx))
.setBlurRadius(3)
.setHasFixedTransformationMatrix(true);
}
@Override
public void onError(Exception e) {}
});
userFullName.setText(tinyDb.getString("userFullname"));
PicassoService.getInstance(ctx).get().load(tinyDb.getString("userAvatar")).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(userAvatar);
userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin")));
userEmail.setText(tinyDb.getString("userEmail"));
ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
@ -79,11 +140,16 @@ public class ProfileFragment extends Fragment {
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);
}
@ -108,15 +174,22 @@ public class ProfileFragment extends Fragment {
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0: // followers
return ProfileFollowersFragment.newInstance("repoOwner", "repoName");
case 1: // following
return ProfileFollowingFragment.newInstance("repoOwner", "repoName");
case 2: // emails
return ProfileEmailsFragment.newInstance("repoOwner", "repoName");
}
return fragment;
}
@Override
@ -128,9 +201,11 @@ public class ProfileFragment extends Fragment {
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.profile_dotted_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
@ -139,17 +214,20 @@ public class ProfileFragment extends Fragment {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
((MainActivity)ctx).finish();
return true;
case R.id.profileMenu:
BottomSheetProfileFragment bottomSheet = new BottomSheetProfileFragment();
bottomSheet.show(getChildFragmentManager(), "profileBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
}

View File

@ -332,6 +332,9 @@ public class PullRequestsFragment extends Fragment {
List<PullRequests> arr = new ArrayList<>();
for(PullRequests d : prList) {
if(d == null || d.getTitle() == null || d.getBody() == null) {
continue;
}
if(d.getTitle().toLowerCase().contains(text) || d.getBody().toLowerCase().contains(text)) {
arr.add(d);
}

View File

@ -4,10 +4,34 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spanned;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Objects;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin;
@ -26,30 +50,6 @@ import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call;
import retrofit2.Callback;
import android.text.Spanned;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Objects;
/**
* Author M M Arif
@ -57,405 +57,427 @@ import java.util.Objects;
public class RepoInfoFragment extends Fragment {
private Context ctx;
private ProgressBar mProgressBar;
private LinearLayout pageContent;
private static String repoNameF = "param2";
private static String repoOwnerF = "param1";
private Context ctx;
private ProgressBar mProgressBar;
private LinearLayout pageContent;
private static String repoNameF = "param2";
private static String repoOwnerF = "param1";
private String repoName;
private String repoOwner;
private TextView repoMetaName;
private TextView repoMetaDescription;
private TextView repoMetaStars;
private TextView repoMetaPullRequests;
private LinearLayout repoMetaPullRequestsFrame;
private TextView repoMetaForks;
private TextView repoMetaSize;
private TextView repoMetaWatchers;
private TextView repoMetaCreatedAt;
private TextView repoMetaWebsite;
private Button repoAdditionalButton;
private TextView repoFileContents;
private LinearLayout repoMetaFrame;
private ImageView repoMetaDataExpandCollapse;
private ImageView repoFilenameExpandCollapse;
private LinearLayout fileContentsFrameHeader;
private LinearLayout fileContentsFrame;
private String repoName;
private String repoOwner;
private TextView repoMetaName;
private TextView repoMetaDescription;
private TextView repoMetaStars;
private TextView repoMetaPullRequests;
private LinearLayout repoMetaPullRequestsFrame;
private TextView repoMetaForks;
private TextView repoMetaSize;
private TextView repoMetaWatchers;
private TextView repoMetaCreatedAt;
private TextView repoMetaWebsite;
private Button repoAdditionalButton;
private TextView repoFileContents;
private LinearLayout repoMetaFrame;
private ImageView repoMetaDataExpandCollapse;
private ImageView repoFilenameExpandCollapse;
private LinearLayout fileContentsFrameHeader;
private LinearLayout fileContentsFrame;
private OnFragmentInteractionListener mListener;
private OnFragmentInteractionListener mListener;
public RepoInfoFragment() {
public RepoInfoFragment() {
}
}
public static RepoInfoFragment newInstance(String param1, String param2) {
RepoInfoFragment fragment = new RepoInfoFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
fragment.setArguments(args);
return fragment;
}
public static RepoInfoFragment newInstance(String param1, String param2) {
RepoInfoFragment fragment = new RepoInfoFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
repoName = getArguments().getString(repoNameF);
repoOwner = getArguments().getString(repoOwnerF);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
repoName = getArguments().getString(repoNameF);
repoOwner = getArguments().getString(repoOwnerF);
}
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_repo_info, container, false);
View v = inflater.inflate(R.layout.fragment_repo_info, container, false);
TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
ctx = getActivity();
ctx = getActivity();
pageContent = v.findViewById(R.id.repoInfoLayout);
pageContent.setVisibility(View.GONE);
pageContent = v.findViewById(R.id.repoInfoLayout);
pageContent.setVisibility(View.GONE);
mProgressBar = v.findViewById(R.id.progress_bar);
repoMetaName = v.findViewById(R.id.repoMetaName);
repoMetaDescription = v.findViewById(R.id.repoMetaDescription);
repoMetaStars = v.findViewById(R.id.repoMetaStars);
repoMetaPullRequests = v.findViewById(R.id.repoMetaPullRequests);
repoMetaPullRequestsFrame = v.findViewById(R.id.repoMetaPullRequestsFrame);
repoMetaForks = v.findViewById(R.id.repoMetaForks);
repoMetaSize = v.findViewById(R.id.repoMetaSize);
repoMetaWatchers = v.findViewById(R.id.repoMetaWatchers);
repoMetaCreatedAt = v.findViewById(R.id.repoMetaCreatedAt);
repoMetaWebsite = v.findViewById(R.id.repoMetaWebsite);
repoAdditionalButton = v.findViewById(R.id.repoAdditionalButton);
repoFileContents = v.findViewById(R.id.repoFileContents);
repoMetaFrame = v.findViewById(R.id.repoMetaFrame);
LinearLayout repoMetaFrameHeader = v.findViewById(R.id.repoMetaFrameHeader);
repoMetaDataExpandCollapse = v.findViewById(R.id.repoMetaDataExpandCollapse);
repoFilenameExpandCollapse = v.findViewById(R.id.repoFilenameExpandCollapse);
fileContentsFrameHeader = v.findViewById(R.id.fileContentsFrameHeader);
fileContentsFrame = v.findViewById(R.id.fileContentsFrame);
mProgressBar = v.findViewById(R.id.progress_bar);
repoMetaName = v.findViewById(R.id.repoMetaName);
repoMetaDescription = v.findViewById(R.id.repoMetaDescription);
repoMetaStars = v.findViewById(R.id.repoMetaStars);
repoMetaPullRequests = v.findViewById(R.id.repoMetaPullRequests);
repoMetaPullRequestsFrame = v.findViewById(R.id.repoMetaPullRequestsFrame);
repoMetaForks = v.findViewById(R.id.repoMetaForks);
repoMetaSize = v.findViewById(R.id.repoMetaSize);
repoMetaWatchers = v.findViewById(R.id.repoMetaWatchers);
repoMetaCreatedAt = v.findViewById(R.id.repoMetaCreatedAt);
repoMetaWebsite = v.findViewById(R.id.repoMetaWebsite);
repoAdditionalButton = v.findViewById(R.id.repoAdditionalButton);
repoFileContents = v.findViewById(R.id.repoFileContents);
repoMetaFrame = v.findViewById(R.id.repoMetaFrame);
LinearLayout repoMetaFrameHeader = v.findViewById(R.id.repoMetaFrameHeader);
repoMetaDataExpandCollapse = v.findViewById(R.id.repoMetaDataExpandCollapse);
repoFilenameExpandCollapse = v.findViewById(R.id.repoFilenameExpandCollapse);
fileContentsFrameHeader = v.findViewById(R.id.fileContentsFrameHeader);
fileContentsFrame = v.findViewById(R.id.fileContentsFrame);
repoMetaFrame.setVisibility(View.GONE);
repoMetaFrame.setVisibility(View.GONE);
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, locale, timeFormat);
getFileContents(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getResources().getString(R.string.defaultFilename));
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, locale, timeFormat);
getFileContents(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getResources().getString(R.string.defaultFilename));
if(isExpandViewVisible()) {
toggleExpandView();
}
if(isExpandViewVisible()) {
toggleExpandView();
}
if(!isExpandViewMetaVisible()) {
toggleExpandViewMeta();
}
if(!isExpandViewMetaVisible()) {
toggleExpandViewMeta();
}
fileContentsFrameHeader.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
toggleExpandView();
}
});
fileContentsFrameHeader.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
toggleExpandView();
}
});
repoMetaFrameHeader.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
toggleExpandViewMeta();
}
});
repoMetaFrameHeader.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
toggleExpandViewMeta();
}
});
return v;
}
return v;
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
private void toggleExpandView() {
private void toggleExpandView() {
if (repoFileContents.getVisibility() == View.GONE) {
repoFilenameExpandCollapse.setImageResource(R.drawable.ic_arrow_up);
repoFileContents.setVisibility(View.VISIBLE);
//Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
//fileContentsFrame.startAnimation(slide_down);
}
else {
repoFilenameExpandCollapse.setImageResource(R.drawable.ic_arrow_down);
repoFileContents.setVisibility(View.GONE);
//Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
//fileContentsFrame.startAnimation(slide_up);
}
}
if (repoFileContents.getVisibility() == View.GONE) {
repoFilenameExpandCollapse.setImageResource(R.drawable.ic_arrow_up);
repoFileContents.setVisibility(View.VISIBLE);
//Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
//fileContentsFrame.startAnimation(slide_down);
}
else {
repoFilenameExpandCollapse.setImageResource(R.drawable.ic_arrow_down);
repoFileContents.setVisibility(View.GONE);
//Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
//fileContentsFrame.startAnimation(slide_up);
}
}
private boolean isExpandViewVisible() {
return repoFileContents.getVisibility() == View.VISIBLE;
}
private boolean isExpandViewVisible() {
return repoFileContents.getVisibility() == View.VISIBLE;
}
private void toggleExpandViewMeta() {
private void toggleExpandViewMeta() {
if (repoMetaFrame.getVisibility() == View.GONE) {
repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_arrow_up);
repoMetaFrame.setVisibility(View.VISIBLE);
//Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
//repoMetaFrame.startAnimation(slide_down);
}
else {
repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_arrow_down);
repoMetaFrame.setVisibility(View.GONE);
//Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
//repoMetaFrame.startAnimation(slide_up);
}
}
if (repoMetaFrame.getVisibility() == View.GONE) {
repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_arrow_up);
repoMetaFrame.setVisibility(View.VISIBLE);
//Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
//repoMetaFrame.startAnimation(slide_down);
}
else {
repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_arrow_down);
repoMetaFrame.setVisibility(View.GONE);
//Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
//repoMetaFrame.startAnimation(slide_up);
}
}
private boolean isExpandViewMetaVisible() {
return repoMetaFrame.getVisibility() == View.VISIBLE;
}
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) {
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) {
final TinyDB tinyDb = new TinyDB(getContext());
final TinyDB tinyDb = new TinyDB(getContext());
Call<UserRepositories> call = RetrofitClient
.getInstance(instanceUrl, getContext())
.getApiInterface()
.getUserRepository(token, owner, repo);
Call<UserRepositories> call = RetrofitClient
.getInstance(instanceUrl, getContext())
.getApiInterface()
.getUserRepository(token, owner, repo);
call.enqueue(new Callback<UserRepositories>() {
call.enqueue(new Callback<UserRepositories>() {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
UserRepositories repoInfo = response.body();
UserRepositories repoInfo = response.body();
if (isAdded()) {
if (isAdded()) {
if (response.isSuccessful()) {
if (response.isSuccessful()) {
if (response.code() == 200) {
if (response.code() == 200) {
assert repoInfo != null;
repoMetaName.setText(repoInfo.getName());
repoMetaDescription.setText(repoInfo.getDescription());
repoMetaStars.setText(repoInfo.getStars_count());
assert repoInfo != null;
repoMetaName.setText(repoInfo.getName());
if(repoInfo.getOpen_pull_count() != null) {
repoMetaPullRequests.setText(repoInfo.getOpen_pull_count());
}
else {
repoMetaPullRequestsFrame.setVisibility(View.GONE);
}
if(!repoInfo.getDescription().isEmpty()) {
repoMetaDescription.setText(repoInfo.getDescription());
}
else {
repoMetaDescription.setText(getString(R.string.noDataDescription));
}
repoMetaForks.setText(repoInfo.getForks_count());
repoMetaWatchers.setText(repoInfo.getWatchers_count());
repoMetaStars.setText(repoInfo.getStars_count());
if(repoInfo.getSize() != 0) {
repoMetaSize.setText(AppUtil.formatFileSize(repoInfo.getSize()));
}
else {
repoMetaSize.setText("0");
}
if(repoInfo.getOpen_pull_count() != null) {
repoMetaPullRequests.setText(repoInfo.getOpen_pull_count());
}
else {
repoMetaPullRequestsFrame.setVisibility(View.GONE);
}
repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx));
if(timeFormat.equals("pretty")) {
repoMetaCreatedAt.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), ctx));
}
repoMetaForks.setText(repoInfo.getForks_count());
repoMetaWatchers.setText(repoInfo.getWatchers_count());
String repoMetaUpdatedAt = TimeHelper.formatTime(repoInfo.getUpdated_at(), new Locale(locale), timeFormat, ctx);
if(repoInfo.getSize() != 0) {
repoMetaSize.setText(AppUtil.formatFileSize(repoInfo.getSize()));
}
else {
repoMetaSize.setText("0 B");
}
String website = (repoInfo.getWebsite().isEmpty()) ? getResources().getString(R.string.noDataWebsite) : repoInfo.getWebsite();
repoMetaWebsite.setText(website);
repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx));
if(timeFormat.equals("pretty")) {
repoMetaCreatedAt.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), ctx));
}
repoAdditionalButton.setOnClickListener(v -> {
String repoMetaUpdatedAt = TimeHelper.formatTime(repoInfo.getUpdated_at(), new Locale(locale), timeFormat, ctx);
StringBuilder message = new StringBuilder();
String website = (repoInfo.getWebsite().isEmpty()) ? getResources().getString(R.string.noDataWebsite) : repoInfo.getWebsite();
repoMetaWebsite.setText(website);
message.append(getResources().getString(R.string.infoTabRepoDefaultBranch))
.append(" :\n").append(repoInfo.getDefault_branch()).append("\n\n");
repoAdditionalButton.setOnClickListener(v -> {
message.append(getResources().getString(R.string.infoTabRepoUpdatedAt))
.append(" :\n").append(repoMetaUpdatedAt).append("\n\n");
View view = LayoutInflater.from(ctx).inflate(R.layout.layout_repo_more_info, null);
message.append(getResources().getString(R.string.infoTabRepoSshUrl))
.append(" :\n").append(repoInfo.getSsh_url()).append("\n\n");
TextView defaultBranchHeader = view.findViewById(R.id.defaultBranchHeader);
TextView defaultBranchContent = view.findViewById(R.id.defaultBranchContent);
message.append(getResources().getString(R.string.infoTabRepoCloneUrl))
.append(" :\n").append(repoInfo.getClone_url()).append("\n\n");
TextView lastUpdatedHeader = view.findViewById(R.id.lastUpdatedHeader);
TextView lastUpdatedContent = view.findViewById(R.id.lastUpdatedContent);
message.append(getResources().getString(R.string.infoTabRepoRepoUrl))
.append(" :\n").append(repoInfo.getHtml_url());
TextView sshUrlHeader = view.findViewById(R.id.sshUrlHeader);
TextView sshUrlContent = view.findViewById(R.id.sshUrlContent);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx);
TextView cloneUrlHeader = view.findViewById(R.id.cloneUrlHeader);
TextView cloneUrlContent = view.findViewById(R.id.cloneUrlContent);
alertDialog.setTitle(getResources().getString(R.string.infoMoreInformation));
alertDialog.setMessage(message);
alertDialog.setPositiveButton(getResources().getString(R.string.close), (dialog, which) -> dialog.dismiss());
alertDialog.create().show();
TextView repoUrlHeader = view.findViewById(R.id.repoUrlHeader);
TextView repoUrlContent = view.findViewById(R.id.repoUrlContent);
});
defaultBranchHeader.setText(getString(R.string.infoTabRepoDefaultBranch));
defaultBranchContent.setText(repoInfo.getDefault_branch());
if(repoInfo.getHas_issues() != null) {
tinyDb.putBoolean("hasIssues", repoInfo.getHas_issues());
}
else {
tinyDb.putBoolean("hasIssues", true);
}
lastUpdatedHeader.setText(getString(R.string.infoTabRepoUpdatedAt));
lastUpdatedContent.setText(repoMetaUpdatedAt);
tinyDb.putString("repoHtmlUrl", repoInfo.getHtml_url());
sshUrlHeader.setText(getString(R.string.infoTabRepoSshUrl));
sshUrlContent.setText(repoInfo.getSsh_url());
mProgressBar.setVisibility(View.GONE);
pageContent.setVisibility(View.VISIBLE);
cloneUrlHeader.setText(getString(R.string.infoTabRepoCloneUrl));
cloneUrlContent.setText(repoInfo.getClone_url());
}
repoUrlHeader.setText(getString(R.string.infoTabRepoRepoUrl));
repoUrlContent.setText(repoInfo.getHtml_url());
}
else {
Log.e("onFailure", String.valueOf(response.code()));
}
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx);
}
alertDialog.setTitle(getResources().getString(R.string.infoMoreInformation));
alertDialog.setView(view);
alertDialog.setPositiveButton(getResources().getString(R.string.close), (dialog, which) -> dialog.dismiss());
alertDialog.create().show();
}
});
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
if(repoInfo.getHas_issues() != null) {
tinyDb.putBoolean("hasIssues", repoInfo.getHas_issues());
}
else {
tinyDb.putBoolean("hasIssues", true);
}
}
tinyDb.putString("repoHtmlUrl", repoInfo.getHtml_url());
private void getFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) {
mProgressBar.setVisibility(View.GONE);
pageContent.setVisibility(View.VISIBLE);
final TinyDB tinyDb = new TinyDB(getContext());
}
Call<String> call = RetrofitClient
.getInstance(instanceUrl, getContext())
.getApiInterface()
.getFileContents(token, owner, repo, filename);
}
else {
Log.e("onFailure", String.valueOf(response.code()));
}
call.enqueue(new Callback<String>() {
}
@Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
}
if (isAdded()) {
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
if (response.code() == 200) {
}
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext()))
.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) {
private void getFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) {
final int resourceId = getContext().getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
getContext().getPackageName());
final TinyDB tinyDb = new TinyDB(getContext());
final Drawable drawable = getContext().getDrawable(resourceId);
Call<String> call = RetrofitClient
.getInstance(instanceUrl, getContext())
.getApiInterface()
.getFileContents(token, owner, repo, filename);
assert drawable != null;
return ImageItem.withResult(drawable);
}
call.enqueue(new Callback<String>() {
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(getContext().getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getContext().getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(getContext()))
.usePlugin(TaskListPlugin.create(getContext()))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
@Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
Spanned bodyWithMD = null;
if (isAdded()) {
if (response.body() != null) {
bodyWithMD = markwon.toMarkdown(response.body());
}
if (response.code() == 200) {
assert bodyWithMD != null;
markwon.setParsedMarkdown(repoFileContents, bodyWithMD);
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext()))
.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) {
} else if (response.code() == 401) {
final int resourceId = getContext().getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
getContext().getPackageName());
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
final Drawable drawable = getContext().getDrawable(resourceId);
} else if (response.code() == 403) {
assert drawable != null;
return ImageItem.withResult(drawable);
}
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(getContext().getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getContext().getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(getContext()))
.usePlugin(TaskListPlugin.create(getContext()))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
} else if (response.code() == 404) {
Spanned bodyWithMD = null;
fileContentsFrameHeader.setVisibility(View.GONE);
fileContentsFrame.setVisibility(View.GONE);
if (response.body() != null) {
bodyWithMD = markwon.toMarkdown(response.body());
}
} else {
assert bodyWithMD != null;
markwon.setParsedMarkdown(repoFileContents, bodyWithMD);
Toasty.info(getContext(), getString(R.string.genericError));
} else if (response.code() == 401) {
}
}
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
} else if (response.code() == 403) {
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
}
} else if (response.code() == 404) {
fileContentsFrameHeader.setVisibility(View.GONE);
fileContentsFrame.setVisibility(View.GONE);
} else {
Toasty.info(getContext(), getString(R.string.genericError));
}
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
}

View File

@ -152,7 +152,7 @@ public class RepositoriesByOrgFragment extends Fragment {
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);

View File

@ -51,7 +51,7 @@ public class RepositoriesFragment extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
final View v = inflater.inflate(R.layout.fragment_repositories, container, false);
setHasOptionsMenu(true);
@ -161,7 +161,7 @@ public class RepositoriesFragment extends Fragment {
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);

View File

@ -78,7 +78,7 @@ public class StarredRepositoriesFragment extends Fragment {
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_starred_repositories, container, false);
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
@ -186,7 +186,7 @@ public class StarredRepositoriesFragment extends Fragment {
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);

View File

@ -148,7 +148,7 @@ public class TeamsByOrgFragment extends Fragment {
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);

View File

@ -19,28 +19,26 @@ public class AlertDialogs {
public static void authorizationTokenRevokedDialog(final Context context, String title, String message, String copyNegativeButton, String copyPositiveButton) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context)
.setTitle(title)
.setMessage(message)
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setNegativeButton(copyNegativeButton, (dialog, which) -> dialog.dismiss())
.setPositiveButton(copyPositiveButton, (dialog, which) -> {
alertDialogBuilder
.setTitle(title)
.setMessage(message)
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setNegativeButton(copyNegativeButton, (dialog, which) -> dialog.dismiss())
.setPositiveButton(copyPositiveButton, (dialog, which) -> {
final TinyDB tinyDb = new TinyDB(context);
tinyDb.putBoolean("loggedInMode", false);
tinyDb.remove("basicAuthPassword");
tinyDb.putBoolean("basicAuthFlag", false);
Intent intent = new Intent(context, LoginActivity.class);
context.startActivity(intent);
dialog.dismiss();
final TinyDB tinyDb = new TinyDB(context);
tinyDb.putBoolean("loggedInMode", false);
tinyDb.remove("basicAuthPassword");
tinyDb.putBoolean("basicAuthFlag", false);
Intent intent = new Intent(context, LoginActivity.class);
context.startActivity(intent);
dialog.dismiss();
});
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialogBuilder.create().show();
alertDialog.show();
}
public static void labelDeleteDialog(final Context context, final String labelTitle, final String labelId, String title, String message, String positiveButton, String negativeButton) {

View File

@ -1,6 +1,9 @@
package org.mian.gitnex.helpers;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.widget.ImageView;
import androidx.annotation.ColorInt;
/**
@ -16,7 +19,7 @@ public class ColorInverter {
int d;
if (a < 0.5) {
d = 0; // black
d = 30; // almost black
} else {
d = 255; // white
}
@ -24,4 +27,35 @@ public class ColorInverter {
return Color.rgb(d, d, d);
}
@ColorInt
public int getImageViewContrastColor(ImageView imageView) {
if(imageView != null) {
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
int colorSum = 0;
int divisionValue = 0;
for(int height=0; height<bitmap.getHeight(); height += 10) {
for(int width=0; width<bitmap.getWidth(); width += 10) {
colorSum += bitmap.getPixel(width, height);
divisionValue++;
}
}
// Calculate average color
return getContrastColor(colorSum / divisionValue);
}
else {
return Color.rgb(255, 255, 255);
}
}
}

View File

@ -23,73 +23,4 @@ public class LabelWidthCalculator {
}
public static int customWidth(int labelLength) {
int width = 33;
if(labelLength == 20) {
width = ((width * labelLength) - 150);
}
else if(labelLength == 19) {
width = ((width * labelLength) - 140);
}
else if(labelLength == 18) {
width = ((width * labelLength) - 130);
}
else if(labelLength == 17) {
width = ((width * labelLength) - 120);
}
else if(labelLength == 16) {
width = ((width * labelLength) - 110);
}
else if(labelLength == 15) {
width = ((width * labelLength) - 100);
}
else if(labelLength == 14) {
width = ((width * labelLength) - 90);
}
else if(labelLength == 13) {
width = ((width * labelLength) - 80);
}
else if(labelLength == 12) {
width = ((width * labelLength) - 70);
}
else if(labelLength == 11) {
width = ((width * labelLength) - 60);
}
else if(labelLength == 10) {
width = ((width * labelLength) - 50);
}
else if(labelLength == 9) {
width = ((width * labelLength) - 40);
}
else if(labelLength == 8) {
width = ((width * labelLength) - 30);
}
else if(labelLength == 7) {
width = ((width * labelLength) - 20);
}
else if(labelLength == 6) {
width = ((width * labelLength) - 10);
}
else if(labelLength == 5) {
width = ((width * labelLength) - 10);
}
else if(labelLength == 4) {
width = ((width * labelLength) - 10);
}
else if(labelLength == 3) {
width = ((width * labelLength) - 10);
}
else if(labelLength == 2) {
width = ((width * labelLength));
}
else {
width = (width * labelLength - 5);
}
return width;
}
}

View File

@ -0,0 +1,145 @@
package org.mian.gitnex.helpers;
import org.mian.gitnex.models.FileDiffView;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Author 6543
*/
public class ParseDiff {
private static String[] getFileNames(String raw) {
String[] lines2 = raw.split(" b/");
if(lines2.length < 2) {
return new String[1];
}
String oldName = lines2[0];
String newName = lines2[1].split("\\n")[0];
return new String[]{oldName, newName};
}
private static String getFileInfo(String raw) {
if(raw.contains("\ndeleted file mode \\d+\n")) {
return "delete";
}
else if(raw.contains("\nnew file mode \\d+\n")) {
return "new";
}
return "change";
}
private static int[] countRemoveAdd(String raw) {
int rm = 0, add = 0;
Pattern rmPattern = Pattern.compile("\n-");
Pattern addPattern = Pattern.compile("\n\\+");
Matcher rmMatcher = rmPattern.matcher(raw);
Matcher addMatcher = addPattern.matcher(raw);
while(rmMatcher.find())
rm++;
while(addMatcher.find())
add++;
return new int[]{rm, add};
}
public static List<FileDiffView> getFileDiffViewArray(String raw) {
List<FileDiffView> fileContentsArray = new ArrayList<>();
String[] lines = raw.split("(^|\\n)diff --git a/");
if(lines.length > 1) {
// for each file in diff
for(int i = 1; i < lines.length; i++) {
// check if it is a binary file
if(lines[i].contains("\nBinary files a/")) {
String[] fileNames = getFileNames(lines[i]);
if(fileNames.length != 2) {
continue;
}
fileContentsArray.add(new FileDiffView(fileNames[0], fileNames[1], "binary", "", null));
}
// check if it is a binary patch
else if(lines[i].contains("\nGIT binary patch\n")) {
String[] fileNames = getFileNames(lines[i]);
if(fileNames.length != 2) {
continue;
}
String[] tmp = lines[i].split("literal \\d+\\n");
String rawContent = "";
if(tmp.length >= 2) {
rawContent = tmp[1].replace("\n", "");
}
List<FileDiffView.Content> contents = new ArrayList<>();
contents.add(new FileDiffView.Content(rawContent));
fileContentsArray.add(new FileDiffView(fileNames[0], fileNames[1], "binary", getFileInfo(lines[i]), contents));
}
// check if it is normal diff
else if(lines[i].contains("\n@@ -")) {
String[] fileNames = getFileNames(lines[i]);
if(fileNames.length != 2) {
continue;
}
String[] rawDiffs = lines[i].split("\n@@ -");
if(rawDiffs.length <= 1) {
continue;
}
List<FileDiffView.Content> contents = new ArrayList<>();
// parse each section starting with "@@" at line beginning
for(int j = 1; j < rawDiffs.length; j++) {
// remove stats info (ending with @@)
// raw diff is the whole raw diff without any diff meta info's
String[] rawDiff = rawDiffs[j].split("^\\d+(,\\d+)? \\+\\d+(,\\d+)? @@");
if(rawDiff.length <= 1) {
continue;
}
// extract the diff stats info of the first line
String statsLine = rawDiffs[j].split("\n")[0].split(" @@")[0];
// parse "-1,2 +2,3" and "-1 -3" and so on
int oldStart = 0, newStart = 0;
String diffPos[] = statsLine.split(" \\+");
if(diffPos.length == 2) {
oldStart = Integer.parseInt(diffPos[0].split(",")[0]);
newStart = Integer.parseInt(diffPos[1].split(",")[0]);
}
// get stat
int[] stats = countRemoveAdd(rawDiff[1]);
contents.add(new FileDiffView.Content(rawDiff[1], oldStart, newStart, stats[0], stats[1]));
}
fileContentsArray.add(new FileDiffView(fileNames[0], fileNames[1], "diff", getFileInfo(lines[i]), contents));
}
// a rename
else if(lines[i].contains("\nrename from")) {
String[] lines2 = lines[i].split("\\nrename (from|to )");
if(lines2.length != 3) {
continue;
}
fileContentsArray.add(new FileDiffView(lines2[1], lines2[2].split("\\n")[0], "rename", "rename", null));
}
}
}
return fileContentsArray;
}
}

View File

@ -0,0 +1,37 @@
package org.mian.gitnex.helpers;
/**
* Author opyale
*/
public class PathsHelper {
public static String join(String... paths) {
StringBuilder stringBuilder = new StringBuilder();
for(String path : paths) {
if(path != null && !path.isEmpty()) {
if(!path.startsWith("/")) {
stringBuilder.append("/");
}
if(path.endsWith("/")) {
path = path.substring(0, path.lastIndexOf("/"));
}
stringBuilder.append(path);
}
}
return stringBuilder.append("/").toString();
}
}

View File

@ -17,7 +17,7 @@ import java.util.Map;
import java.util.UUID;
/**
* Author anonTree1417
* Author opyale
*/
public class PicassoCache implements Cache {

View File

@ -13,34 +13,34 @@ import org.mian.gitnex.R;
public class Toasty {
public static void info(Context context, String message) {
public static void info(Context context, String message) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate( context.getResources().getLayout(R.layout.custom_toast), null );
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(context.getResources().getLayout(R.layout.custom_toast), null);
TextView text = view.findViewById(R.id.toastText);
text.setText(message);
TextView text = view.findViewById(R.id.toastText);
text.setText(message);
Toast toast = new Toast(context);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(view);
toast.show();
Toast toast = new Toast(context);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(view);
toast.show();
}
}
public static void error(Context context, String message) {
public static void error(Context context, String message) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate( context.getResources().getLayout(R.layout.custom_toast_error), null );
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(context.getResources().getLayout(R.layout.custom_toast_error), null);
TextView text = view.findViewById(R.id.toastText);
text.setText(message);
TextView text = view.findViewById(R.id.toastText);
text.setText(message);
Toast toast = new Toast(context);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(view);
toast.show();
Toast toast = new Toast(context);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(view);
toast.show();
}
}
}

View File

@ -9,34 +9,39 @@ import java.net.URISyntaxException;
public class UrlHelper {
public static String cleanUrl(String url) {
public static String cleanUrl(String url) {
URI uri = null;
try {
uri = new URI(url);
} catch (URISyntaxException e) {
e.printStackTrace();
}
URI uri = null;
try {
uri = new URI(url);
}
catch(URISyntaxException e) {
e.printStackTrace();
}
assert uri != null;
String urlProtocol = uri.getScheme();
String urlHost = uri.getHost();
int urlPort = uri.getPort();
assert uri != null;
String urlProtocol = uri.getScheme();
String urlHost = uri.getHost();
int urlPort = uri.getPort();
String urlFinal = null;
if(urlPort > 0) {
urlFinal = urlProtocol + "://" + urlHost + ":" + urlPort;
}
else if(urlProtocol != null) {
urlFinal = urlProtocol + "://" + urlHost;
}
else {
urlFinal = urlHost;
}
String urlFinal = null;
if(urlPort > 0) {
urlFinal = urlProtocol + "://" + urlHost + ":" + urlPort;
}
else if(urlProtocol != null) {
urlFinal = urlProtocol + "://" + urlHost;
}
else {
urlFinal = urlHost;
}
return urlFinal;
return urlFinal;
}
}
public static String fixScheme(String url, String scheme) {
return !url.matches("^(http|https)://.+$") ? scheme + "://" + url : url;
}
}

View File

@ -1,6 +1,6 @@
package org.mian.gitnex.helpers;
import org.jetbrains.annotations.NotNull;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@ -70,7 +70,7 @@ public class Version {
* @param v
* @return
*/
public boolean equal(@NotNull Version v) {
public boolean equal(@NonNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
@ -101,7 +101,7 @@ public class Version {
* @param v
* @return
*/
public boolean less(@NotNull Version v) {
public boolean less(@NonNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
@ -142,7 +142,7 @@ public class Version {
* @param v
* @return
*/
public boolean higher(@NotNull Version v) {
public boolean higher(@NonNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
@ -182,7 +182,7 @@ public class Version {
* @param v
* @return
*/
public boolean lessOrEqual(@NotNull Version v) {
public boolean lessOrEqual(@NonNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
@ -213,7 +213,7 @@ public class Version {
* @param v
* @return
*/
public boolean higherOrEqual(@NotNull Version v) {
public boolean higherOrEqual(@NonNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
@ -225,4 +225,4 @@ public class Version {
}
}
}

View File

@ -1,7 +1,7 @@
package org.mian.gitnex.helpers.ssl;
/**
* Author Georg Lukas, modified by anonTree1417
* Author Georg Lukas, modified by opyale
*/
class MTMDecision {

View File

@ -7,7 +7,7 @@ import android.os.Bundle;
import org.mian.gitnex.R;
/**
* Author Georg Lukas, modified by anonTree1417
* Author Georg Lukas, modified by opyale
*/
public class MemorizingActivity extends Activity {
@ -41,4 +41,4 @@ public class MemorizingActivity extends Activity {
}
}
}

View File

@ -39,7 +39,7 @@ import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
/**
* Author Georg Lukas, modified by anonTree1417
* Author Georg Lukas, modified by opyale
*/
public class MemorizingTrustManager implements X509TrustManager {
@ -605,7 +605,7 @@ public class MemorizingTrustManager implements X509TrustManager {
private boolean interactHostname(X509Certificate cert, String hostname) {
if(interact(hostNameMessage(cert, hostname), R.string.mtm_accept_servername) == MTMDecision.DECISION_ALWAYS) {
if(interact(hostNameMessage(cert, hostname), R.string.mtm_accept_server_name) == MTMDecision.DECISION_ALWAYS) {
storeCert(hostname, cert);
return true;
}

View File

@ -267,11 +267,14 @@ public interface ApiInterface {
@GET("repos/{owner}/{repo}/pulls") // get repository pull requests
Call<List<PullRequests>> getPullRequests(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("state") String state, @Query("limit") int limit);
@GET("repos/{owner}/{repo}/pulls/{index}.diff") // get pull diff file contents
Call<ResponseBody> getPullDiffContent(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Path("index") String pullIndex);
@POST("repos/{owner}/{repo}/pulls/{index}/merge") // merge a pull request
Call<ResponseBody> mergePullRequest(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int index, @Body MergePullRequest jsonStr);
@GET("repos/{owner}/{repo}/commits") // get all commits
Call<List<Commits>> getRepositoryCommits(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("sha") String branchName);
Call<List<Commits>> getRepositoryCommits(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("sha") String branchName, @Query("limit") int limit);
@PATCH("repos/{owner}/{repo}/milestones/{index}") // close / reopen milestone
Call<JsonElement> closeReopenMilestone(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int index, @Body Milestones jsonStr);

View File

@ -1,39 +1,159 @@
package org.mian.gitnex.models;
import androidx.annotation.NonNull;
import java.util.List;
/**
* Author M M Arif
* Author 6543
*/
public class FileDiffView {
private String fileName;
private boolean fileType;
private String fileInfo;
private String fileContents;
private String fileNewName;
private String fileOldName;
private String diffType;
private String fileInfo;
private Stats stats;
private List<Content> contents;
public FileDiffView(String fileName, boolean fileType, String fileInfo, String fileContents)
{
public class Stats {
this.fileName = fileName;
this.fileType = fileType;
this.fileInfo = fileInfo;
this.fileContents = fileContents;
private int lineAdded;
private int lineRemoved;
}
public Stats(int added, int removed) {
public String getFileName() {
return fileName;
}
this.lineAdded = added;
this.lineRemoved = removed;
}
public boolean isFileType() {
return fileType;
}
public int getAdded() {
public String getFileInfo() {
return fileInfo;
}
return lineAdded;
}
public int getRemoved() {
return lineRemoved;
}
@NonNull
public String toString() {
return "+" + this.lineAdded + ", -" + this.lineRemoved;
}
}
public static class Content {
private int lineAdded;
private int lineRemoved;
private int oldLineStart;
private int newLineStart;
private String raw;
public Content(String content) {
this.raw = content;
}
public Content(String content, int oldStart, int newStart, int removed, int added) {
this.raw = content;
this.lineAdded = added;
this.lineRemoved = removed;
this.oldLineStart = oldStart;
this.newLineStart = newStart;
}
public String getRaw() {
return raw;
}
public int getLineAdded() {
return this.lineAdded;
}
public int getLineRemoved() {
return this.lineRemoved;
}
public int getOldLineStart() {
return this.oldLineStart;
}
public int getNewLineStart() {
return this.newLineStart;
}
}
public FileDiffView(String oldName, String newName, String diffType, String fileInfo, List<Content> fileContents) {
this.fileNewName = newName.trim();
this.fileOldName = oldName.trim();
this.diffType = diffType;
this.fileInfo = fileInfo;
this.contents = fileContents;
this.stats = new Stats(0, 0);
if(fileContents != null) {
for(Content content : this.contents) {
stats.lineAdded += content.lineAdded;
stats.lineRemoved += content.lineRemoved;
}
}
}
public String getFileName() {
if(fileOldName.length() != 0 && !fileOldName.equals(fileNewName)) {
return fileOldName + " -> " + fileNewName;
}
return fileNewName;
}
public boolean isFileBinary() {
return diffType.equals("binary");
}
public String getFileInfo() {
if(diffType.equals("binary")) {
return diffType + " " + fileInfo;
}
if(fileInfo.equals("change") && this.stats != null) {
return this.stats.toString();
}
return fileInfo;
}
@NonNull
public String toString() {
StringBuilder raw = new StringBuilder();
if(this.contents != null) {
for(Content c : this.contents) {
raw.append(c.getRaw());
}
}
return raw.toString();
}
@NonNull
public List<Content> getFileContents() {
return this.contents;
}
public String getFileContents() {
return fileContents;
}
}

View File

@ -31,6 +31,7 @@ public class UserRepositories {
private String forks_count;
private Boolean has_issues;
private String avatar_url;
private boolean archived;
private permissionsObject permissions;
@ -167,4 +168,24 @@ public class UserRepositories {
return avatar_url;
}
public boolean isPrivateFlag() {
return privateFlag;
}
public String getOpen_pr_counter() {
return open_pr_counter;
}
public String getRelease_counter() {
return release_counter;
}
public boolean isArchived() {
return archived;
}
}

View File

@ -9,6 +9,7 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.view.View;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@ -23,271 +24,279 @@ import java.util.Locale;
public class AppUtil {
public static String strReplace(String str, String original, String replace) {
return str.replace(original, replace);
}
public static boolean haveNetworkConnection(Context context) {
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
haveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
return haveConnectedWifi || haveConnectedMobile;
}
public static int getAppBuildNo(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Could not get package name: " + e);
}
}
public static String getAppVersion(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Could not get package name: " + e);
}
}
public int charactersLength(String str) {
return str.length();
}
public Boolean checkStringsWithAlphaNumeric(String str) { // [a-zA-Z0-9]
return str.matches("^[\\w]+$");
}
public Boolean checkStrings(String str) { // [a-zA-Z0-9-_. ]
return str.matches("^[\\w .-]+$");
}
public Boolean checkStringsWithAlphaNumericDashDotUnderscore(String str) { // [a-zA-Z0-9-_]
return str.matches("^[\\w.-]+$");
}
public Boolean checkStringsWithDash(String str) { // [a-zA-Z0-9-_. ]
return str.matches("^[\\w-]+$");
}
public Boolean checkIntegers(String str) {
return str.matches("\\d+");
}
public int getResponseStatusCode(String u) throws Exception {
URL url = new URL(u);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
return (http.getResponseCode());
}
public static void setAppLocale(Resources resource, String locCode) {
DisplayMetrics dm = resource.getDisplayMetrics();
Configuration config = resource.getConfiguration();
config.setLocale(new Locale(locCode.toLowerCase()));
resource.updateConfiguration(config, dm);
}
public static boolean httpCheck(String url) {
String pattern = "^(http|https)://.*$";
return url.matches(pattern);
}
public static String formatFileSize(long size) {
String repoSize = null;
double m = size/1024.0;
double g = ((size/1024.0)/1024.0);
double t = (((size/1024.0)/1024.0)/1024.0);
DecimalFormat dec = new DecimalFormat("0.00");
if ( t > 1 ) {
repoSize = dec.format(t).concat(" TB");
}
else if ( g > 1 ) {
repoSize = dec.format(g).concat(" GB");
}
else if ( m > 1 ) {
repoSize = dec.format(m).concat(" MB");
}
else if ( (double) size > 1 ) {
repoSize = dec.format((double) size).concat(" KB");
}
return repoSize;
}
public static String formatFileSizeInDetail(long size) {
public static String strReplace(String str, String original, String replace) {
String fileSize = null;
return str.replace(original, replace);
}
double k = size/1024.0;
double m = ((size/1024.0)/1024.0);
double g = (((size/1024.0)/1024.0)/1024.0);
double t = ((((size/1024.0)/1024.0)/1024.0)/1024.0);
public static boolean hasNetworkConnection(Context context) {
DecimalFormat dec = new DecimalFormat("0.00");
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
if ( t > 1 ) {
fileSize = dec.format(t).concat(" TB");
}
else if ( g > 1 ) {
fileSize = dec.format(g).concat(" GB");
}
else if ( m > 1 ) {
fileSize = dec.format(m).concat(" MB");
}
else if ( k > 1 ) {
fileSize = dec.format(k).concat(" KB");
}
else if ( (double) size > 1 ) {
fileSize = dec.format((double) size).concat(" B");
}
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for(NetworkInfo ni : netInfo) {
if(ni.getTypeName().equalsIgnoreCase("WIFI")) {
if(ni.isConnected()) {
haveConnectedWifi = true;
}
}
if(ni.getTypeName().equalsIgnoreCase("MOBILE")) {
if(ni.isConnected()) {
haveConnectedMobile = true;
}
}
}
return haveConnectedWifi || haveConnectedMobile;
}
return fileSize;
public static int getAppBuildNo(Context context) {
}
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
}
catch(PackageManager.NameNotFoundException e) {
throw new RuntimeException("Could not get package name: " + e);
}
}
public static String customDateFormat(String customDate) {
public static String getAppVersion(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionName;
}
catch(PackageManager.NameNotFoundException e) {
throw new RuntimeException("Could not get package name: " + e);
}
}
public int charactersLength(String str) {
return str.length();
}
String[] parts = customDate.split("-");
final String year = parts[0];
final String month = parts[1];
final String day = parts[2];
public Boolean checkStringsWithAlphaNumeric(String str) { // [a-zA-Z0-9]
return str.matches("^[\\w]+$");
}
String sMonth;
if (Integer.parseInt(month) < 10) {
sMonth = "0"+ month;
} else {
sMonth = month;
}
public Boolean checkStrings(String str) { // [a-zA-Z0-9-_. ]
return str.matches("^[\\w .-]+$");
}
public Boolean checkStringsWithAlphaNumericDashDotUnderscore(String str) { // [a-zA-Z0-9-_]
return str.matches("^[\\w.-]+$");
}
public Boolean checkStringsWithDash(String str) { // [a-zA-Z0-9-_. ]
return str.matches("^[\\w-]+$");
}
public static Boolean checkIntegers(String str) {
return str.matches("\\d+");
}
public int getResponseStatusCode(String u) throws Exception {
URL url = new URL(u);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
return (http.getResponseCode());
}
public static void setAppLocale(Resources resource, String locCode) {
DisplayMetrics dm = resource.getDisplayMetrics();
Configuration config = resource.getConfiguration();
config.setLocale(new Locale(locCode.toLowerCase()));
resource.updateConfiguration(config, dm);
}
public static String formatFileSize(long size) {
String repoSize = size + " B";
double m = size / 1024.0;
double g = ((size / 1024.0) / 1024.0);
double t = (((size / 1024.0) / 1024.0) / 1024.0);
DecimalFormat dec = new DecimalFormat("0.00");
if(t > 1) {
repoSize = dec.format(t).concat(" TB");
}
else if(g > 1) {
repoSize = dec.format(g).concat(" GB");
}
else if(m > 1) {
repoSize = dec.format(m).concat(" MB");
}
else if((double) size > 1) {
repoSize = dec.format((double) size).concat(" KB");
}
return repoSize;
}
String sDay;
if (Integer.parseInt(day) < 10) {
sDay = "0"+ day;
} else {
sDay = day;
}
public static String formatFileSizeInDetail(long size) {
return year + "-" + sMonth + "-" + sDay;
String fileSize = null;
}
double k = size / 1024.0;
double m = ((size / 1024.0) / 1024.0);
double g = (((size / 1024.0) / 1024.0) / 1024.0);
double t = ((((size / 1024.0) / 1024.0) / 1024.0) / 1024.0);
public static String customDateCombine(String customDate) {
DecimalFormat dec = new DecimalFormat("0.00");
final Calendar c = Calendar.getInstance();
int mHour = c.get(Calendar.HOUR_OF_DAY);
int mMinute = c.get(Calendar.MINUTE);
int mSeconds = c.get(Calendar.SECOND);
if(t > 1) {
fileSize = dec.format(t).concat(" TB");
}
else if(g > 1) {
fileSize = dec.format(g).concat(" GB");
}
else if(m > 1) {
fileSize = dec.format(m).concat(" MB");
}
else if(k > 1) {
fileSize = dec.format(k).concat(" KB");
}
else if((double) size > 1) {
fileSize = dec.format((double) size).concat(" B");
}
String sMin;
if ((mMinute) < 10) {
sMin = "0"+ mMinute;
} else {
sMin = String.valueOf(mMinute);
}
return fileSize;
String sSec;
if ((mSeconds) < 10) {
sSec = "0"+ mSeconds;
} else {
sSec = String.valueOf(mSeconds);
}
}
return (customDate + "T" + mHour + ":" + sMin + ":" + sSec + "Z");
public static String customDateFormat(String customDate) {
}
String[] parts = customDate.split("-");
final String year = parts[0];
final String month = parts[1];
final String day = parts[2];
public String encodeBase64(String str) {
String sMonth;
if(Integer.parseInt(month) < 10) {
sMonth = "0" + month;
}
else {
sMonth = month;
}
String base64Str = str;
if(!str.equals("")) {
byte[] data = str.getBytes(StandardCharsets.UTF_8);
base64Str = Base64.encodeToString(data, Base64.DEFAULT);
}
String sDay;
if(Integer.parseInt(day) < 10) {
sDay = "0" + day;
}
else {
sDay = day;
}
return base64Str;
return year + "-" + sMonth + "-" + sDay;
}
}
public String decodeBase64(String str) {
public static String customDateCombine(String customDate) {
String base64Str = str;
if(!str.equals("")) {
byte[] data = Base64.decode(base64Str, Base64.DEFAULT);
base64Str = new String(data, StandardCharsets.UTF_8);
}
final Calendar c = Calendar.getInstance();
int mHour = c.get(Calendar.HOUR_OF_DAY);
int mMinute = c.get(Calendar.MINUTE);
int mSeconds = c.get(Calendar.SECOND);
return base64Str;
String sMin;
if((mMinute) < 10) {
sMin = "0" + mMinute;
}
else {
sMin = String.valueOf(mMinute);
}
}
String sSec;
if((mSeconds) < 10) {
sSec = "0" + mSeconds;
}
else {
sSec = String.valueOf(mSeconds);
}
public Boolean sourceCodeExtension(String ext) {
return (customDate + "T" + mHour + ":" + sMin + ":" + sSec + "Z");
String[] extValues = new String[] {"md", "json", "java", "go", "php", "c", "cc", "cpp", "h", "cxx", "cyc", "m",
"cs", "bash", "sh", "bsh", "cv", "python", "perl", "pm", "rb", "ruby", "javascript",
"coffee", "rc", "rs", "rust", "basic", "clj", "css", "dart", "lisp", "erl", "hs", "lsp", "rkt",
"ss", "llvm", "ll", "lua", "matlab", "pascal", "r", "scala", "sql", "latex", "tex", "vb", "vbs",
"vhd", "tcl", "wiki.meta", "yaml", "yml", "markdown", "xml", "proto", "regex", "py", "pl", "js",
"html", "htm", "volt", "ini", "htaccess", "conf", "gitignore", "gradle", "txt", "properties", "bat",
"twig"};
}
return Arrays.asList(extValues).contains(ext);
public String encodeBase64(String str) {
}
String base64Str = str;
if(!str.equals("")) {
byte[] data = str.getBytes(StandardCharsets.UTF_8);
base64Str = Base64.encodeToString(data, Base64.DEFAULT);
}
public Boolean pdfExtension(String ext) {
return base64Str;
String[] extValues = new String[] {"pdf"};
}
return Arrays.asList(extValues).contains(ext);
public String decodeBase64(String str) {
}
String base64Str = str;
if(!str.equals("")) {
byte[] data = Base64.decode(base64Str, Base64.DEFAULT);
base64Str = new String(data, StandardCharsets.UTF_8);
}
public Boolean imageExtension(String ext) {
return base64Str;
String[] extValues = new String[] {"jpg", "jpeg", "gif", "png", "ico"};
}
return Arrays.asList(extValues).contains(ext);
public Boolean sourceCodeExtension(String ext) {
}
String[] extValues = new String[]{"md", "json", "java", "go", "php", "c", "cc", "cpp", "h", "cxx", "cyc", "m", "cs", "bash", "sh", "bsh", "cv", "python", "perl", "pm", "rb", "ruby", "javascript", "coffee", "rc", "rs", "rust", "basic", "clj", "css", "dart", "lisp", "erl", "hs", "lsp", "rkt", "ss", "llvm", "ll", "lua", "matlab", "pascal", "r", "scala", "sql", "latex", "tex", "vb", "vbs", "vhd", "tcl", "wiki.meta", "yaml", "yml", "markdown", "xml", "proto", "regex", "py", "pl", "js", "html", "htm", "volt", "ini", "htaccess", "conf", "gitignore", "gradle", "txt", "properties", "bat", "twig", "cvs", "cmake", "in", "info", "spec", "m4", "am", "dist", "pam"};
public Boolean excludeFilesInFileViewerExtension(String ext) {
return Arrays.asList(extValues).contains(ext);
String[] extValues = new String[] {"doc", "docx", "ppt", "pptx", "xls", "xlsx", "xlsm", "odt",
"ott", "odf", "ods", "ots", "exe", "jar", "odg", "otg", "odp", "otp", "bin", "dmg", "psd",
"xcf"};
}
return Arrays.asList(extValues).contains(ext);
public Boolean pdfExtension(String ext) {
}
String[] extValues = new String[]{"pdf"};
public String getLastCharactersOfWord( String str, int count ) {
return Arrays.asList(extValues).contains(ext);
return str.substring(str.length() - count);
}
public Boolean imageExtension(String ext) {
String[] extValues = new String[]{"jpg", "jpeg", "gif", "png", "ico"};
return Arrays.asList(extValues).contains(ext);
}
public Boolean excludeFilesInFileViewerExtension(String ext) {
String[] extValues = new String[]{"doc", "docx", "ppt", "pptx", "xls", "xlsx", "xlsm", "odt", "ott", "odf", "ods", "ots", "exe", "jar", "odg", "otg", "odp", "otp", "bin", "dmg", "psd", "xcf"};
return Arrays.asList(extValues).contains(ext);
}
public String getLastCharactersOfWord(String str, int count) {
return str.substring(str.length() - count);
}
public static void setMultiVisibility(int visibility, View... views) {
for(View view : views) {
view.setVisibility(visibility);
}
}
}
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:topLeftRadius="12dp"
android:topRightRadius="12dp" />
<padding android:top="12dp" />
<solid android:color="?attr/primaryBackgroundColor" />
</shape>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#368F73"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20.54,5.23l-1.39,-1.68C18.88,3.21 18.47,3 18,3H6c-0.47,0 -0.88,0.21 -1.16,0.55L3.46,5.23C3.17,5.57 3,6.02 3,6.5V19c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V6.5c0,-0.48 -0.17,-0.93 -0.46,-1.27zM12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5zM5.12,5l0.81,-1h12l0.94,1H5.12z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#368F73"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M8.59,16.34l4.58,-4.59 -4.58,-4.59L10,5.75l6,6 -6,6z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#368F73"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M9.4,16.6L4.8,12l4.6,-4.6L8,6l-6,6 6,6 1.4,-1.4zM14.6,16.6l4.6,-4.6 -4.6,-4.6L16,6l6,6 -6,6 -1.4,-1.4z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#368F73"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
</vector>

View File

@ -9,8 +9,8 @@
android:right="1dp"
android:left="1dp">
<shape>
<corners android:radius="15dp"/>
<solid android:color="@color/divider"/>
<corners android:radius="10dp"/>
<solid android:color="?attr/inputBackgroundColor"/>
</shape>
</item>
@ -23,9 +23,9 @@
<scale android:scaleWidth="100%">
<shape>
<corners android:radius="15dp" />
<corners android:radius="10dp" />
</shape>
</scale>
</item>
</layer-list>
</layer-list>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="3dp"/>
<solid android:color="@color/releasePre" />
</shape>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="@color/releasePre">
</solid>
<corners
android:radius="3dp">
</corners>
</shape>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="@color/releaseStable">
</solid>
<corners
android:radius="3dp">
</corners>
</shape>

View File

@ -54,7 +54,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:padding="4dp"
android:scrollbars="vertical" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
@ -70,4 +69,4 @@
android:textSize="20sp"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>

View File

@ -58,7 +58,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:padding="4dp"
android:scrollbars="vertical" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
@ -83,4 +82,4 @@
android:indeterminate="true"
android:visibility="visible" />
</RelativeLayout>
</RelativeLayout>

View File

@ -160,7 +160,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/releaseTypeText"
android:checked="true"
android:checked="false"
android:textSize="16sp"
android:layout_marginTop="10dp"
android:textColor="?attr/primaryTextColor"/>
@ -170,7 +170,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/releaseDraftText"
android:checked="true"
android:checked="false"
android:textSize="16sp"
android:layout_marginTop="10dp"
android:textColor="?attr/primaryTextColor"/>
@ -194,4 +194,4 @@
</ScrollView>
</LinearLayout>
</LinearLayout>

View File

@ -74,7 +74,7 @@
android:background="@drawable/shape_inputs"
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:textColorHighlight="?attr/primaryTextColor"/>
android:textColorHighlight="?attr/primaryTextColor" />
<TextView
android:layout_width="match_parent"
@ -97,7 +97,7 @@
android:background="@drawable/shape_inputs"
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:textColorHighlight="?attr/primaryTextColor"/>
android:textColorHighlight="?attr/primaryTextColor" />
<TextView
android:layout_width="match_parent"
@ -105,7 +105,7 @@
android:text="@string/newTeamPermission"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:layout_marginTop="10dp"/>
android:layout_marginTop="10dp" />
<TextView
android:id="@+id/teamPermission"
@ -116,10 +116,10 @@
android:textSize="14sp"
tools:ignore="Autofill"
android:background="@drawable/shape_inputs"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:inputType="none"
android:textColorHighlight="@color/white"/>
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:textColorHighlight="?attr/primaryTextColor"
android:inputType="none" />
<TextView
android:id="@+id/teamPermissionDetail"
@ -128,7 +128,7 @@
android:textColor="?attr/primaryTextColor"
android:textSize="12sp"
android:gravity="start"
android:visibility="gone"/>
android:visibility="gone" />
<TextView
android:layout_width="match_parent"
@ -136,7 +136,7 @@
android:text="@string/newTeamAccessControls"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:layout_marginTop="10dp"/>
android:layout_marginTop="10dp" />
<TextView
android:id="@+id/teamAccessControls"
@ -147,16 +147,16 @@
android:textSize="14sp"
tools:ignore="Autofill"
android:background="@drawable/shape_inputs"
android:textColor="?attr/primaryTextColor"
android:textColorHint="?attr/primaryTextColor"
android:inputType="none"
android:textColorHighlight="?attr/primaryTextColor"/>
android:textColor="?attr/inputTextColor"
android:textColorHint="?attr/hintColor"
android:textColorHighlight="?attr/primaryTextColor"
android:inputType="none" />
<TextView
android:id="@+id/teamAccessControlsArray"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
android:visibility="gone" />
<Button
android:id="@+id/createTeamButton"
@ -171,10 +171,10 @@
<View
android:layout_width="match_parent"
android:layout_height="35dp"/>
android:layout_height="35dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</LinearLayout>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"
android:gravity="center"
@ -239,4 +239,4 @@
</LinearLayout>
</ScrollView>
</ScrollView>

View File

@ -4,9 +4,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="?attr/primaryBackgroundColor"
android:paddingTop="8dp">
android:paddingTop="6dp"
android:paddingBottom="12dp"
android:background="?attr/primaryBackgroundColor">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -27,10 +27,10 @@
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="16dp" />
android:padding="12dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</LinearLayout>

View File

@ -4,9 +4,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="?attr/primaryBackgroundColor"
android:paddingTop="8dp">
android:paddingTop="6dp"
android:paddingBottom="12dp"
android:background="?attr/primaryBackgroundColor">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -27,10 +27,10 @@
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="16dp" />
android:padding="12dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</LinearLayout>

View File

@ -4,9 +4,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="?attr/primaryBackgroundColor"
android:paddingTop="8dp">
android:paddingTop="6dp"
android:paddingBottom="12dp"
android:background="?attr/primaryBackgroundColor">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -27,7 +27,7 @@
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="16dp" />
android:padding="12dp" />
<TextView
android:id="@+id/commentMenuDelete"
@ -39,7 +39,31 @@
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="16dp" />
android:padding="12dp" />
<TextView
android:id="@+id/commentMenuQuote"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/menuQuoteText"
android:drawableStart="@drawable/ic_comment"
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="12dp" />
<TextView
android:id="@+id/commentMenuCopy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/menuCopyText"
android:drawableStart="@drawable/ic_content_copy"
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="12dp" />
<TextView
android:id="@+id/issueCommentShare"
@ -51,10 +75,10 @@
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="16dp" />
android:padding="12dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</LinearLayout>

View File

@ -4,9 +4,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:background="?attr/primaryBackgroundColor"
android:paddingTop="8dp">
android:paddingTop="6dp"
android:paddingBottom="12dp"
android:background="?attr/primaryBackgroundColor">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -27,7 +27,7 @@
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="16dp" />
android:padding="12dp" />
<TextView
android:id="@+id/closedIssues"
@ -39,10 +39,10 @@
android:drawablePadding="24dp"
android:textColor="?attr/primaryTextColor"
android:textSize="16sp"
android:padding="16dp" />
android:padding="12dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</LinearLayout>

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