Compare commits

...

496 Commits
2.1.0 ... 3.0.0

Author SHA1 Message Date
0928e936d7 Prepare release (#599)
update  feature list in readme

Merge branch 'master' into 480-update-screenshots

update desc for f-droid

update screenshots, add changelogs

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/599
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-23 19:35:46 +02:00
a29011c6a2 Crowdin 2020-07-23 (#602)
Crowdin Update

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/602
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-23 18:38:18 +02:00
c09fc4988a Support Samsung DeX (#601)
Support Samsung DeX

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/601
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-23 18:37:32 +02:00
39ac49b258 Notifications (#554)
Cleanup

Extending and improving notifications

Using new icons instead

Lowering polling delay to one minute and other improvements

Fixing minor issues

Simplifying progress layout

Fixing bugs and other improvements

Adding translations

Notifications

Co-authored-by: opyale <opyale@noreply.gitea.io>
Co-authored-by: 6543 <6543@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/554
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-22 21:32:42 +02:00
cd55f946f0 Crowdin 2020-07-22 (#597)
Crowdin Update

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/597
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-07-22 14:48:12 +02:00
b529f81115 Fix some bugs (#596)
remove redundant casting

Fix edittext layout when typing(reduce size), fix refresh drafts. Minor improvements

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/596
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-19 15:44:08 +02:00
e6109ef36d Search drafts (#574)
Merge branch 'master' into search-drafts

Merge branch 'master' into search-drafts

Merge branch 'master' into search-drafts

Merge branch 'master' into search-drafts

Merge branch 'master' into search-drafts

Merge branch 'master' into search-drafts

Merge branch 'master' into search-drafts

Merge branch 'master' into search-drafts

Merge branch 'master' into search-drafts

# Conflicts:
#	app/src/main/java/org/mian/gitnex/fragments/DraftsFragment.java

search drafts

Co-authored-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/574
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-19 12:33:58 +02:00
e00fcd846a Add missed icons and improve the ratio of all icons across the app (#592)
Merge branch 'master' into new-missing-icons

Merge branch 'master' into new-missing-icons

Fix background and icon

Fix search bar icons and layout to match the themes

new lines?

Merge branch 'master' into new-missing-icons

Add missed icons, and improve the ratio of all icons across the app

Co-authored-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/592
2020-07-19 12:24:47 +02:00
060c86c090 Add server avatar to user accounts (#594)
Add server avatar to user accounts

Co-authored-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/594
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-19 12:13:37 +02:00
26f54280a1 Add explore and drafts to set as home screen options (#588)
Fix icon cut off sizes

Add explore and drafts to set as home screen options

Co-authored-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/588
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-19 12:05:08 +02:00
8a7923cba7 Fix VersionCheck (#591)
code dedub

Bugfix & Test Correction

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/591
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-07-14 18:20:00 +02:00
673b9f564c Crowdin 2020-07-14 (#590)
crowdin_2020-07-14

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/590
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-14 17:14:06 +02:00
d1be03956c Transition of old icons to new ones (#589)
last set of updates and changes to the icons

Add more icons

WIP : transition of more icons

Switch of icons to new icons for the whole app - WIP

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/589
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-12 19:18:50 +02:00
caa437d5e3 Switch branches (#571)
Fix default branch

Merge branch 'master' into switch-branches

# Conflicts:
#	app/src/main/res/layout/bottom_sheet_repo.xml
#	app/src/main/res/values/strings.xml

update icon

Merge branch 'master' into switch-branches

Merge branch 'master' into switch-branches

update the missing parts

Minor updates

Merge branch 'master' into switch-branches

Merge branch 'master' into switch-branches

# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java
#	app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java
#	app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java
#	app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java

Add branch to breadcrumb and dir structure fix

Make change branch work

clean up

Merge branch 'master' into switch-branches

add icon in top bar, add interface listener

Merge branch 'master' into switch-branches

Merge remote-tracking branch 'remotes/main/master' into switch-branches

# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/LoginActivity.java
#	app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java
#	app/src/main/java/org/mian/gitnex/helpers/PathsHelper.java

Switching between branches.

Minor fixes

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

URL parsing, label and other improvements.

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/571
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-12 17:14:50 +02:00
25036ce5d2 Remove Unused Locales (#585)
Remove Unused Locales

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/585
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-11 12:49:35 +02:00
a8a34ccc7a New icons (#587)
repo info icons update

Update icons across the app

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/587
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-10 22:54:09 +02:00
f87e8020d8 Remove Unused Resources (#586)
Remove Unused Resources

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/586
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-10 12:43:51 +02:00
4d67e63db4 Fix license (#584)
Fix license

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/584
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-07-09 17:42:13 +02:00
3561dde19f Badges and drone fix. (#583)
Removing link

Badges and drone fix.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/583
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-09 15:18:21 +02:00
9c48dec54d Delete drafts [settings] (#576)
Merge branch '450-drafts-settings' of codeberg.org:gitnex/GitNex into 450-drafts-settings

Fix package move

Merge branch 'master' into 450-drafts-settings

Merge branch 'master' into 450-drafts-settings

fix default value save

Delete drafts settings

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/576
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-07-09 13:55:09 +02:00
3d72d68e14 Fixing CI (#582)
Fixing CI

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/582
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-09 13:37:44 +02:00
47b24470e6 Improving CI. (#581)
Improving CI.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/581
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-09 13:29:36 +02:00
1db6a3294b Using GitLab CI. (#580)
Using smaller image and publishing releases.

Fixing things.

Merge branch 'gitlab-ci' of https://codeberg.org/opyale/GitNex into gitlab-ci

Removing eclint.

Merge branch 'master' into gitlab-ci

Only run jobs when master changed.

Using GitLab CI.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/580
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-09 08:55:05 +02:00
500dc019c1 Moving TinyDB and AppUtil to helpers. (#579)
Moving TinyDB and AppUtil to helpers.

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/579
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-07 19:15:01 +02:00
e2aff890d7 Accounts overview screen (#577)
optimize url string

Overview of accounts in the app

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/577
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-07-07 16:20:43 +02:00
cdfc2cfb9e Implement drafts, introduce Room persistence library for db (#139)
Fix no draft message

translation updates

format improvements

typo update

some renaming refactors

Use better naming convention

remove duplicate source

arrange draft titles

enhance click listener area

Launch drafts from reply screen and clean up

Add message draft saved

update repositories tasks

Update user accounts repository with thread, remove async tasks

remove async task in drafts

update layout, change async to thread in drafts

Merge branch 'master' into pull_139

# Conflicts:
#	app/build.gradle
#	app/src/main/java/org/mian/gitnex/activities/LoginActivity.java

Merge branch 'master' into pull_139

# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/ReplyToIssueActivity.java

Merge branch 'pull_139' of codeberg.org:gitnex/GitNex into pull_139

# Conflicts:
#	app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java

Merge branch 'master' into pull_139

# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/LoginActivity.java
#	app/src/main/java/org/mian/gitnex/activities/ReplyToIssueActivity.java
#	app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java

Merge branch 'master' into pull_139

Merge branch 'master' into pull_139

Merge branch 'master' into pull_139 and fix conflicts

# Conflicts:
#	app/build.gradle
#	app/src/main/java/org/mian/gitnex/activities/LoginActivity.java
#	app/src/main/java/org/mian/gitnex/activities/MainActivity.java
#	app/src/main/java/org/mian/gitnex/activities/ReplyToIssueActivity.java
#	app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java
#	app/src/main/res/values/strings.xml

Code Format

Merge branch 'master' into 15-comments-draft

Merge branch 'master' into 15-comments-draft

Merge branch 'master' into 15-comments-draft

# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/MainActivity.java
#	app/src/main/res/values/strings.xml

Go to draft, save on type and other fixes

delete all drafts, added messages where needed

delete draft

Force logout

Merge branch 'master' into 15-comments-draft

Merge branch 'master' into 15-comments-draft

# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/MainActivity.java
#	app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java

check if account data is null, we need to log the user out for the 1st time.

Merge branch 'master' into 15-comments-draft

fix repo owner, name sequence

Add comments for test, show drafts list

Add repos to db

Add account to db and other refactors to the code

Merge branch 'master' into 15-comments-draft

Merge branch 'master' into 15-comments-draft

Merge branch 'master' into 15-comments-draft

Merge branch 'master' into 15-comments-draft

# Conflicts:
#	app/build.gradle
#	app/src/main/AndroidManifest.xml

Merge branch 'master' into 15-comments-draft

merge

more queries, added dao repositories, layout update

Added queries in dao

some refactor. added models, dao, entities (accounts, repositories, drafts)

WIP on implementing drafts, introduced Room persistence library for db.

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/139
Reviewed-by: opyale <opyale@noreply.codeberg.org>
2020-07-04 22:51:55 +02:00
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
8b1c79c0c3 Merge pull request 'Prepare release 3.0.0 rc1' (#520) from prepare-release into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/520
2020-05-31 13:39:25 +00:00
bf26a44376 Prepare release 3.0.0 rc1 2020-05-31 18:36:42 +05:00
6721b09de9 Improve single issue UI (#518)
Merge branch 'master' into single-issue-ui

Add progressbar, match the ui to other ui for views(lines etc). And other refactors.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/518
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-30 16:59:52 +00:00
0f9e130cf4 Using more recent docker image for eclint. (#516)
Using more recent docker image for eclint.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/516
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-29 21:31:55 +00:00
014b06cc46 Fix org repos layout bug, cleanup layouts and adapters (#514)
Merge branch 'extra-space' into fix-extra-space

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

fix margins and clean up

Adjusting margin to be consistent.

remove association

Fix org repos layout bug, cleanup layouts and adapters

Co-authored-by: opyale <opyale@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/514
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-29 19:30:04 +00:00
6654b6fb48 [CI] Use enviroment variables again (#511)
[CI] Hopefully fixing upload now.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/511
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-28 10:19:14 +00:00
f1eb632d9b CI: Adding basic formatting tests (#509)
better names

Using dedicated eclint image

Reconfiguring editorconfig

Removing intellij-specific configuration and making adjustments.

Final improvements

Minor improvements.

end_of_line = lf

Adding basic formatting tests.

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/509
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-27 18:09:55 +00:00
34f8f82b63 Fix infined load on Issues/Pulls if they dont exist (#507)
404 fix for issues

add 404 for pr

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/507
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-23 18:30:33 +00:00
b30e2da387 Milestones filter(open/close) + refactor (#506)
remove strings

translation: generic but with contecxt

Merge branch 'milestones-filter' of gitea.com:gitnex/GitNex into milestones-filter

Clean up strings

Merge branch 'master' into milestones-filter

clean up and add missing parts

enhance and refactor milestone, added filter for closed and open ms

change to viewbinding

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/506
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-23 17:54:16 +00:00
6b3ac84113 Decreasing upload time to 3 minutes, increasing attempts and removing proxy. (#504)
CI: Decreasing upload time to 3 minutes, increasing attempts and removing proxy.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/504
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-23 08:38:09 +00:00
9541ef7dbc Merge pull request 'Enhance profile screen' (#505) from enhance-profile into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/505
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-22 15:46:48 +00:00
6a6bbef63d Enhance profile screen 2020-05-22 17:02:16 +05:00
dc168a732b Update Crowdin 2020-05-21 (#503)
Update Crowdin 2020-05-21

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/503
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-21 23:08:40 +00:00
d06f5353c6 Delete branch after merge (#496)
delete branch API call

Add fork repo info for branch

Check if pr is mergeable, show message if not.

Use checkbox instead of button

make ripple effects work for buttons with enable/disable

introduce viewbinding

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/496
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-21 22:49:09 +00:00
1b213783bc New file saving (#502)
New file saving

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/502
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-21 20:16:31 +00:00
e83b9eb736 Check Issue Subscription and display button based on that (#445)
update string names

Update strings

Merge branch 'master' into imprufe-issue-subscription-checking

switch icon as per @mmarif

Migrate to new Version Check & disable IssueSubscription function for gitea < 1.12.0

Merge branch 'master' into imprufe-issue-subscription-checking

Merge branch 'master' into imprufe-issue-subscription-checking

Merge branch 'master' into imprufe-issue-subscription-checking

refactor  & use dismiss()

realy check If issue is subscribed

add 200 http Status check and handle it

Rename WatchRepository to WatchInfo & add checkIssueWatchStatus

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/445
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-21 18:58:00 +00:00
ad7c3696d5 [BugFix] Version Compare (#500)
BugFix of Version

add new TestCase

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/500
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-21 14:13:14 +00:00
7bfdfa3223 Add/Remove new member to team (#483)
Search as user type, fix datalist.

Code Format

Fix users search theme

add and remove user from team

Add interface and user search and check for being team member or not

bottom sheet menu and few refactors

Co-authored-by: 6543 <6543@noreply.gitea.io>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/483
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-20 18:21:09 +00:00
0f38d81cd0 Minor improvements concerning CI. (#498)
Minor improvements concerning CI

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/498
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-19 17:56:38 +00:00
dd92ef9732 Merge pull request 'Adding additional functionality to build upload.' (#497) from opyale/GitNex:ci-upload-reloaded into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/497
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-18 23:20:47 +00:00
408fd9627b Adding additional functionality. 2020-05-19 01:09:56 +02:00
3de4dd9463 Refactor Version Checks (#472)
Merge branch 'master' into refactor-versionCheck

Merge branch 'master' into refactor-versionCheck

Revert "test CI"

This reverts commit b56eff0920.

test CI

Reformat LoginActivity.java

cleanup

migrate

Working + Tests

add first UnitTest

wip ...

enum2class

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/472
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-17 16:14:06 +00:00
7f0689524f Merge pull request 'Add corners to popup dialogs' (#495) from ui-enhancements into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/495
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-15 22:08:29 +00:00
a4afa5fbc2 Add corners to popup dialogs 2020-05-16 02:09:49 +05:00
29756511f3 Merge pull request 'Small layout adjustments and correcting typos.' (#493) from opyale/GitNex:settings-design-typo-adj into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/493
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-14 15:09:48 +00:00
56d8cd0fac Small layout adjustments and correcting typos. 2020-05-14 12:46:49 +02:00
4e6057171b Adding deprecation dialog. (#492)
Additional improvements.

Final improvements.

Adding deprecation dialog.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/492
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-05-09 19:07:55 +00:00
ab8a5ed505 Clear cache, configure cache size (#482)
decrease the compression to have better results

Move cache size outside of maxsize method. fix progress bar alignment for files

Add cache size to picasso

Use getAbsolutePath

Merge branch 'app-cache' of gitea.com:gitnex/GitNex into app-cache

Few imprvoements

Merge branch 'master' into app-cache

small improvement

Implement configure cache size and clear it

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/482
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-05-09 14:50:45 +00:00
a6b424f5ff Fix files layout bug (#485)
Fix files layout bug

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/485
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-05-04 17:16:36 +00:00
e5d6fd3b41 [New] Delete own comment (#478)
Code Reformat

Use return from 6543 commit

Fix typo

Move delete method to adapter to update the recyclerview

make it work

add to bottomsheet entry

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/478
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-30 10:42:22 +00:00
5d1efe0f3f Moving HighlightJS into app. (#477)
Final fixes and improvements.

Fixing crash of app in Android 5.0

Removing unused theme.

Moving HighlightJS to app.

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/477
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-30 06:28:27 +00:00
c41ab845fd Refactor Context (#469)
Merge branch 'master' into fix-refactor-context

reorder + space

fix

R E F A C T O R

set ctx and appCtx in LoginActivity

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/469
Reviewed-by: M M Arif <mmarif@swatian.com>
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-04-28 13:47:25 +00:00
e45dc4b311 Increasing usability and design of files diff. (#413)
Applying sizes.

Additional changes.

First changes.

Merge branch 'master' into diff-cleaner

Fixing formatting.

Merge branch 'master' into diff-cleaner

Final changes for working with custom themes.

Merge remote-tracking branch 'remotes/main/master' into diff-cleaner

First changes for working with custom themes.

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Adding custom COLOR_FONT.

Even smaller cleanups.

Merge remote-tracking branch 'remotes/main/master' into diff-cleaner

Small cleanups.

Fixing bug and adding maximum line limit.

Adding option to set cursor to end and small cleanup.

First aid.

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Merge branch 'master' into diff-cleaner

Few improvements.

Performance improvements and cleanups.

Minor improvements (code in order) and many bug fixes

Bug fix.

Combining cited code.

Adding code commenting option.

Renaming list_files_diffs_new to list_files_diffs

Moving ProcessBar into center

Increasing performance.

Applying size to all icons globally.

Removing another unused file.

Merge remote-tracking branch 'remotes/main/master' into diff-cleaner

Removing unused files.

Changing size of 'close'-button.

Major changes concerning design and bug fixes.

Temporary save point.

2

1

Co-authored-by: opyale <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/413
Reviewed-by: 6543 <6543@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-28 12:39:41 +00:00
7c53de363d Fix the context bug (#470)
Fix the context bug. done in activities

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/470
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-28 10:36:07 +00:00
f352f175dd Merge pull request 'Add phone os version and model' (#468) from add-phone-os-section into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/468
2020-04-28 06:34:43 +00:00
d1a5c9c897 Add phone os version and model 2020-04-28 06:33:39 +00:00
51a7bca889 Merge pull request 'Small refactor and cleanup' (#467) from refactor-cleanup into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/467
2020-04-28 06:20:35 +00:00
03528f653a small refactor and cleanup 2020-04-28 11:18:58 +05:00
9d182821d2 Hide new branch when current is selected (#451)
Hide is best approach here

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/451
Reviewed-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-28 02:08:12 +00:00
195bfc8fe2 Refactor commits (#452)
code reformat

check for same gitea version

change link to button `view in browser`

add search by commit hash

Fix crash for custom attr caused by context and clean up

Refactor commits, remove fastadapter

Co-authored-by: 6543 <6543@noreply.gitea.io>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/452
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-26 22:59:09 +00:00
2e89fb0054 Fix load more after using filter (#463)
Fix load more after using filter

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/463
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-04-26 21:21:15 +00:00
48abe71645 Split settings screen into different sections (#457)
add reports section

Add translation, fix change lang bug not taking affect

Add security section

Add file viewer section

Change settings screen into different sections

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/457
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-26 13:36:33 +00:00
eca46b7913 Notification icons (#458)
New notification icon with transparent background

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/458
Reviewed-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-26 11:13:56 +00:00
6736fa2f5d Fix repo url (#455)
Fix repo url

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/455
Reviewed-by: opyale <opyale@noreply.gitea.io>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-26 11:02:03 +00:00
bbf41988d5 Merge pull request 'Enhance statusbar color for light theme' (#453) from enhance-statusbar-color-in-light-theme into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/453
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-04-26 09:54:30 +00:00
aa3288e889 Enhance statusbar color for light theme 2020-04-25 20:41:17 +05:00
92a0d06b75 Merge pull request 'Fix newlines in Readme' (#447) from fix-readme-newlines into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/447
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-24 04:59:21 +00:00
4e7fd6295e Fix newlines in Readme
because of new Render rouls - linebreaks have to be fixed
2020-04-24 00:28:44 +00:00
0ee5b43996 Optimize fragments, add filters, fix search and clean up (#439)
Code Reformat

hide not found message

Refactor issues, remove fastadapter.

fix swipe back filter icon issue, fix crash on issues with faster swiping

Change filter icon based on selection, empty the list for progress bar, check for gitea version to pass limit and other improvements

Separate menu and interface for pr

Add filter bottom sheet to PRs, issues

Fix search/filter pull requests

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/439
Reviewed-by: opyale <opyale@noreply.gitea.io>
2020-04-23 20:40:13 +00:00
625e60f2e2 Merge pull request 'Create new screen for administration' (#442) from 438-admin-nav into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/442
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-23 16:11:06 +00:00
3fb063b0b1 Display Admin Menue Only If you are Admin 2020-04-23 18:04:32 +02:00
d7ef368f0b Create new screen for administration 2020-04-23 17:05:50 +05:00
dd1fce892a Replace textview with button for view commits in branches (#437)
Replace textview with button for view commits in branches

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/437
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-22 10:12:56 +00:00
f39357f596 update master (#436)
update changelog

update master

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/436
2020-04-22 05:05:35 +00:00
3bfc6b94a4 Merge pull request 'Crowdin [2020-04-21]' (#431) from 6543/GitNex:update-crowdin into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/431
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-21 13:52:51 +00:00
996d5d5fea Update from Crowdin 2020-04-21 10:40:54 +02:00
af6cbfdb66 [FrontPort #429] Dismiss bottom sheet on subscribe/unsubscribe to issue & Fix (#428)
Merge branch 'master' into 427-dismiss-bottom-sheet

Does not really fix the issue as there is way to handle this without a proper call.
And dismiss does not work properly either.

But added few improvements and fixed close/reopen issue along the way.

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/428
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-18 14:29:42 +00:00
01e451556e README: Add download for CI build apk (#424)
Merge branch 'master' into update-readme-add-ci-build

apply suggestions

Change "Download APK" option to gitnex.com download page

add download for CI build apk

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/424
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-18 13:58:38 +00:00
c3f4cbb186 Merge pull request 'Rc release' (#426) from prepare-rc-release into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/426
2020-04-18 05:21:39 +00:00
57ecf3b7d2 Rc release 2020-04-18 10:19:43 +05:00
03a9cd1bba Adding ability to login again when version check failes. (#417)
add own error message for this

Merge branch 'master' into login-fix

Merge branch 'master' into login-fix

Merge branch 'master' into login-fix

Adding ability to login again when version check failes.

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: 6543 <6543@noreply.gitea.io>
Co-authored-by: opyale <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/417
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-18 04:51:58 +00:00
aa85b99e84 FIX IssueComments moddel (#425)
Reformat Code

FIX IssueComments moddel

reformate Code

TimeHelper.formatTime dont crash on null date object

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/425
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-18 04:50:36 +00:00
0c6c596208 Integrate crash reporting (#418)
Disable minify to get proper logs

Enable it by default

Integrate crash reporting

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/418
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-17 23:39:49 +00:00
30165f27ba Merge pull request 'Fix crash caused by res shrinking and minification' (#421) from 420-fix-release-crash into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/421
2020-04-17 10:12:59 +00:00
b7abe65508 Fix crash caused by res shrinking and minification 2020-04-17 15:10:32 +05:00
31723008ed [CI] publish signed builds from master to nextcloud (#416)
publish builds from master

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/416
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-15 16:09:29 +00:00
a544e2ef56 Crowdin [2020-04-14] (#411)
Merge branch 'master' into crowdin-update

Update Crowdin 2020-04-14

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/411
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-15 06:33:38 +00:00
13dbbe3ec7 Fixing toasty bug. (#412)
Fixing toasty bug.

Co-authored-by: opyale <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/412
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-14 22:41:40 +00:00
9cbcb1f87b Merge pull request 'Prepare 2.5.0 rc release' (#410) from rc-release-fdroid into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/410
2020-04-14 21:31:36 +00:00
e7554819fd Prepare 2.5.0 rc release 2020-04-15 02:27:58 +05:00
7caecadb32 Refactor issues (#380)
new strings for tabs

Merge branch 'refactor-issues' of gitea.com:gitnex/GitNex into refactor-issues

Fix conflicts and files refactors

Merge branch 'master' into refactor-issues

Merge branch 'master' into refactor-issues

refactored closed issues in new tab

Added gitea ver check, minor ui fixes

Merge branch 'master' into refactor-issues

# Conflicts:
#	app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java

Refactored open issues

Added parent fragment

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/380
2020-04-14 20:55:04 +00:00
b8d8b34b0e Show ContributorsTab only if you have permission to (#402)
add isRepoAdmin

extend Adapters

add check to RepoDetails

refactor var names

reformat code

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/402
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-14 19:25:36 +00:00
ab47e409e9 update libs, enhance release builds (#408)
Merge branch 'master' into update-libs-enhance-release-build

update libs, enhance release builds

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/408
2020-04-14 08:50:12 +00:00
344284c1c1 Improving issue template. (#401)
Final changes.

Merge branch 'master' into bug-desc-improve

Merge branch 'master' into bug-desc-improve

Removing unnecessary bar.

Simplifying stuff.

Some more examples.

Further improvements.

Further improvements.

Improving issue template.

Co-authored-by: opyale <example@example.com>
Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/401
Reviewed-by: 6543 <6543@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-13 15:56:31 +00:00
b10df63c8a Merge pull request 'Adjusting size of text views in organizations list.' (#406) from opyale/GitNex:size-adj into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/406
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-13 15:55:17 +00:00
4cb0253b38 Adjusting size of text views in organizations list. 2020-04-13 17:31:39 +02:00
539c5be4b5 Themes for source code in file viewer (#403)
reformat code

move from else-if to switch-case

Merge branch 'master' into 396-themes-file-veiwer

Merge branch 'master' into 396-themes-file-veiwer

Make string translatable false

Themes for source code in file viewer

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/403
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-13 15:23:31 +00:00
008ffaa553 Merge pull request 'Fix of views being gone randomly' (#404) from 400-milestone-bug into master
Merging via app
2020-04-13 10:40:05 +00:00
9a5a774d8c Merge branch 'master' into 400-milestone-bug 2020-04-13 10:20:18 +00:00
2e452eaa81 Fix version API auth check (#399)
Merge branch 'master' into 389_alternate_version-api-auth

rm comment

get gitea Version Authentificated

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/399
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-13 08:01:56 +00:00
3b84ec46d1 Fix of views being gone randomly 2020-04-13 12:48:23 +05:00
4123e03f7d Applying changes of LabelWidthCalculator to LabelsAdapter. (#398)
Trying to find a compromise.

make them great again ;)

Applying changes of LabelWidthCalculator to LabelsAdapter.

Co-authored-by: opyale <example@example.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/398
Reviewed-by: 6543 <6543@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-13 07:25:39 +00:00
3a524c9f5d Remember-login-type (#394)
Merge branch 'master' into 372-remember-login-type

# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/LoginActivity.java

Use strings instead of boolean

Remember login type

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/394
2020-04-12 19:15:20 +00:00
e709aba3c2 Remember login type (#392)
Merge branch 'master' into 372-remember-login-type

Remember login type

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/392
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-12 19:04:02 +00:00
14bca1f4c4 Merge pull request 'Adding more reliable calculation of label width.' (#393) from opyale/GitNex:label-width-calc into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/393
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-12 18:53:44 +00:00
a7213add30 Adding more reliable calculation of label width. 2020-04-12 20:33:41 +02:00
df2bc91e9f Setting Manrope as default font. (#379)
Revert "store default if user didnt touch Font settings"

This reverts commit 9c5f9731

store default if user didnt touch Font settings

Setting translatable to false

Last changes.

Defaulting to Manrope in strings.xml

Default to Manrope in settings.

Changes in default value.

Automatic formatting.

Merge remote-tracking branch 'remotes/main/master' into manrope

# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/BaseActivity.java

Manrope just literally as default font.

Reformatting code.

Making optimizations.

Moving initialization to BaseActivity

Merge remote-tracking branch 'remotes/main/master' into manrope

Setting Manrope as default font.

Co-authored-by: opyale <example@example.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/379
Reviewed-by: 6543 <6543@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-12 15:19:33 +00:00
145043a515 Extend Merge Options (#217)
Merge branch 'master' into extend-merge-dialog

Minor fixes

format

? an AndroidStudio suggestion ?

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

add Title Text and some Fixes

add version check

Merge branch 'master' into extend-merge-dialog

Merge branch 'master' into extend-merge-dialog

use translation and revormat

make Merge Options Translateble
gitea locale revs:
* pulls.merge_pull_request
* pulls.rebase_merge_pull_request
* pulls.rebase_merge_commit_pull_request
* pulls.squash_merge_pull_request

Fix menu item

Make merge options work

Merge branch 'master' into merge-options

work - but UGLY UI

use enum for merge-modes

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/217
2020-04-11 20:20:26 +00:00
adb8a8bf04 Fix fab hide scroll issue and clean up (#381)
Merge branch 'fix-fab-scroll-issue' of gitea.com:gitnex/GitNex into fix-fab-scroll-issue

Merge branch 'master' into fix-fab-scroll-issue

Merge branch 'master' into fix-fab-scroll-issue

Fix fab hide scroll issue and clean up

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/381
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-11 20:17:24 +00:00
398cceed2f Merge pull request 'Close/reopen milestone' (#386) from 329-close-open-milestone into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/386
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-11 06:59:40 +00:00
1acbd7dc9f Merge branch 'master' into 329-close-open-milestone 2020-04-11 06:44:30 +00:00
f5d5264ef7 Implement auto switcher for light and dark theme (#388)
Remove import and add author

Implement auto switcher for light and dark theme. other ui fixes

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/388
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-11 06:06:39 +00:00
0caaa63b06 Close/reopen milestone 2020-04-08 23:31:27 +05:00
79944241fe Merge pull request 'Minor improvement and fixes for repo info tab' (#382) from fixes-repo-info into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/382
2020-04-07 21:23:38 +00:00
8b7c5e2873 Minor improvement and fix for repo info tab 2020-04-08 02:21:47 +05:00
e310a16bad Improving design of "Repository Meta" (#362)
Merge branch 'master' into details-design

Always open "Repository Meta"

Fixing bugs.

Merge remote-tracking branch 'remotes/main/master' into details-design

Typo removal.

Do not show pull requests when API returns null.

Replacing size by watchers

Removing unused imports.

Moving time formatting into TimeHelper.

Changing website icon and renaming button and dialog text.

Further contentDescription

Adding contentDescription

Adding support for "timeFormat"

Merge remote-tracking branch 'remotes/main/master' into details-design

Full support for translation.

Partially supporting translation.

Adding "view additional information".

Adding additional information.

Adding forks count.

First design changes.

Improving usability by including whole header in "Details".

Co-authored-by: opyale <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/362
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-07 21:17:12 +00:00
e07ee1aceb Enabling counter badges by default. (#378)
Merge remote-tracking branch 'remotes/main/master' into counter-badges

# Conflicts:
#	app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java

Moving to BaseActivity

Enabling counter badges by default.

Co-authored-by: opyale <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/378
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-07 20:45:40 +00:00
73950f9f2a Crowdin [2020-04-07] + add Polish (#377)
add Polish to settings and reformat code

add Polish locales

Crowdin Update

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/377
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-07 20:39:08 +00:00
7387c29077 Replacing bottom sheet item by floating action button. (#360)
Merge branch 'fab-button-issues' of https://gitea.com/opyale/GitNex into fab-button-issues

Merge remote-tracking branch 'remotes/main/master' into fab-button-issues

Merge branch 'master' into fab-button-issues

Adding onScrollListener.

Reply icon

Generalizing padding of floating action button.

Merge branch 'master' into fab-button-issues

Improving proportions.

Replacing bottom sheet item by floating action button and cleaning up code.

Co-authored-by: opyale <example@example.com>
Co-authored-by: anonTree1417 <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/360
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-07 20:06:39 +00:00
9bca299107 Merge pull request 'fix' (#375) from 6543/GitNex:issue-subscribe-take-theme-into-account into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/375
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-07 13:44:47 +00:00
ee88ee86cd Merge pull request 'Fix repos loading on switching accounts' (#371) from fix-repos-load-on-login into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/371
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-07 13:43:38 +00:00
ce51b9264a fix
Signed-off-by: 6543 <6543@obermui.de>
2020-04-07 15:18:14 +02:00
831e9d36ec Fix repos loading on switching accounts 2020-04-07 11:05:42 +05:00
da90005e42 hide ReleaseCounter Badge on old Gitea instances (#367)
Hide Release Count on old Gitea Instances

fix compareVersion

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/367
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-07 04:15:56 +00:00
d46db0475f Improving usability by including whole header in "Details". (#361)
Merge branch 'master' into usability-details

Improving usability by including whole header in "Details".

Co-authored-by: opyale <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/361
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-06 19:00:18 +00:00
9b9173e33b [Doc] update issue-template add pull-template (#359)
fix

add sugestions

fix Nr

fix what atom did wrong (automatism)

Add PR template

make link from contributing to the code-standards

Update issue_template

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/359
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-06 09:38:02 +00:00
1dc61af683 Add Issue Subscribtion (#203)
rename Context

move things to IssueActions

rm unused API func

get Context only one time

add repoWatch into tinyDB

add maginal Issue Un-/Subscription support

add Issue Subscribtion

 * api
 * layout

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/203
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-05 09:54:34 +00:00
d2490bf6f9 Crowdin [2020-04-04] + add Spanish (#353)
add spanish to config

Merge branch 'master' into add-lang-spanish

Update 2020-04-04

adde Spanish (42% translated)

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/353
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-04 19:29:44 +00:00
1da54e3d35 [UI] Add Pull & Release Counter Badge to TabLable (#350)
fix cp error

fix

reformat code

remove issuesCounter

check if API return new objects, make settings option more generic

Merge branch 'master' into 218-PR-Tab_OpenNumber

add Release Counter

Rename Issue Badge and add Pull Badge

Upgrade Gradle and delete a useles commend

Json Responce: add OpenPullCount and ReleaseCount

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/350
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-04 19:20:25 +00:00
c402046699 Introduce snackbar for toast messages (#352)
Merge branch 'master' into 302-snackbar

Added snackbar to login screen

Co-authored-by: 6543 <6543@noreply.gitea.io>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/352
2020-04-04 19:19:44 +00:00
36ebfff529 Merge pull request 'On Repo Lists: change comment-icon to issue-icon' (#351) from iconchange into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/351
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-04 06:41:55 +00:00
fe0654b9eb On Repo Lists: change comment-icon to issue-icon 2020-04-04 03:40:08 +02:00
9b3a9aada7 Adding caching to picasso service (#345)
Merge remote-tracking branch 'remotes/main/master' into picasso-img-cache

Some improvements including size management and easy customization.

Improvements to picasso cache

Making PicassoCache public

Moving PicassoCache to helpers/

Merge branch 'master' into picasso-img-cache

Adding options for customisation.

(Hopefully) final bug fixes.

Additional fixes.

Hotfix.

Prevent NullPointerException.

Formatting stuff.

Removing unnecessary permission.

Adding permission.

Adding PicassoCache.

Using max-stale now.

Adding caching to picasso service

Co-authored-by: anonTree1417 <example@example.com>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/345
Reviewed-by: 6543 <6543@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-03 17:02:46 +00:00
9e77e27177 Share comment of an issue (#348)
cleanup

Use html_url to fix issue/pr separation

Share comment of an issue

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/348
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-03 16:48:22 +00:00
51c281ca30 Merge pull request 'update libs and clean up' (#346) from update-libs into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/346
2020-04-03 06:29:57 +00:00
b9ca041c5b update libs and clean up 2020-04-03 11:28:24 +05:00
1d8dc445ec Merge pull request 'Support for self-signed certificates' (#318) from anonTree1417/GitNex:self-signed into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/318
Reviewed-by: 6543 <6543@noreply.gitea.io>
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-03 06:16:01 +00:00
63865fefec Merge remote-tracking branch 'remotes/main/master' into self-signed
# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/LoginActivity.java
2020-04-02 23:07:20 +02:00
8234ad77e3 Merge pull request 'Fix #341 - Store UserName on Login first' (#343) from 6543/GitNex:fix-341 into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/343
2020-04-02 20:11:18 +00:00
120c83a943 Merge branch 'master' into fix-341 2020-04-02 18:11:23 +00:00
59e8f6f94a Fixing popup bug. 2020-04-02 19:11:23 +02:00
fc532989e5 Fix repos load on initial login and clean ups 2020-04-02 22:04:54 +05:00
ae0009f553 Merge remote-tracking branch 'remotes/main/master' into self-signed
# Conflicts:
#	app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java
2020-04-02 18:50:26 +02:00
7fe583c816 Move WebInterace Calls to own Interface (#338)
optimize imports

Merge branch 'master' into moveWebInteraceCalls-2-ownInterface

Merge branch 'master' into moveWebInteraceCalls-2-ownInterface

move WebInterface calls to own interface

rename WEB api for getting PullDiff

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/338
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-02 16:00:03 +00:00
70581cd330 Updates to settings screen 2020-04-02 20:49:26 +05:00
20ce31fed8 add eng mesage 2020-04-02 17:17:53 +02:00
f53f122a15 add saveUserName step on login 2020-04-02 17:17:00 +02:00
c6125f83c7 Merge remote-tracking branch 'remotes/main/master' into self-signed
# Conflicts:
#	app/src/main/java/org/mian/gitnex/adapters/ExploreRepositoriesAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/RepositoriesByOrgAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/StarredReposListAdapter.java
2020-04-02 10:45:52 +02:00
8853b33c11 Merge pull request 'remove pointless if statements' (#340) from 6543/GitNex:refactor1 into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/340
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-04-02 08:12:45 +00:00
733acd0e0b Merge pull request 'Switch to bottomsheets for popup menus' (#333) from 304-popup-menus-to-bottomsheets into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/333
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-02 08:05:56 +00:00
b9eee16294 Adding resources. 2020-04-02 03:12:44 +02:00
abdfe8d9d1 Adding option to delete certificates. 2020-04-02 02:59:00 +02:00
f4c4b837de remove pointless if statements 2020-04-02 01:16:07 +02:00
ee0392e208 Very small improvements 2020-04-01 21:58:42 +02:00
b2f34f819c Removing library and commenting out logger. 2020-04-01 18:58:52 +02:00
faaa4db88b Removing option "ONCE" 2020-04-01 18:39:39 +02:00
4217db3e31 Add author to readme 2020-04-01 21:16:59 +05:00
d2f77cfcd0 Fix minor formattings, other improvements 2020-04-01 20:28:14 +05:00
9f6d8239f6 Adding author 2020-04-01 14:38:34 +02:00
0dda996444 Adding Picasso support for self-signed certificates. 2020-04-01 13:26:32 +02:00
c02d7f2df7 Merge branch 'master' of https://gitea.com/gitnex/GitNex into self-signed 2020-04-01 12:00:25 +02:00
9988649714 cleanup 2020-04-01 14:51:37 +05:00
1e52649b76 Added to labels, issue comment 2020-04-01 14:44:38 +05:00
ca37ad661d Changed repos list menus to bottom sheets 2020-04-01 11:38:14 +05:00
11b8bb8d83 Merge pull request 'Add placeholders for images' (#331) from improve-images-loading into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/331
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-04-01 06:09:02 +00:00
786ac3999a Merge branch 'master' into improve-images-loading 2020-03-31 20:40:08 +00:00
e5a656ce57 Many improvements and bug fixes. 2020-03-31 22:09:42 +02:00
5fdbc98d6e Text to resource. 2020-03-31 21:21:49 +02:00
b4996c0e6d Even more reformatting. 2020-03-31 21:14:49 +02:00
28d97f2d67 Merge branch 'master' of https://gitea.com/gitnex/GitNex into self-signed 2020-03-31 21:10:47 +02:00
a53a5d55bf Reformatting applied. 2020-03-31 21:04:53 +02:00
2125d38a66 Adding information at error and resetting button. 2020-03-31 21:04:08 +02:00
b46ad33dd3 Adjusting proportions of issue labels. (#325)
Merge remote-tracking branch 'remotes/main/master' into fab-issue

Adjusting sizes in LabelsAdapter

Adjusting proportions of issue labels.

Co-authored-by: anonTree1417 <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/325
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-03-31 18:53:36 +00:00
dd2339ec34 Small design changes (#327)
Merge remote-tracking branch 'remotes/main/master' into add-styling

Restoring branches_list.xml

Small design changes.

Co-authored-by: anonTree1417 <example@example.com>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/327
Reviewed-by: M M Arif <mmarif@swatian.com>
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-03-31 18:49:39 +00:00
0e365a6d49 Add placeholders for images 2020-03-31 23:46:42 +05:00
d1fe5bdda9 Merge branches 'add-styling', 'self-signed' and 'style-changes' of https://gitea.com/anonTree1417/GitNex into self-signed 2020-03-31 20:25:03 +02:00
5ee872dc6e Merge remote-tracking branch 'remotes/main/master' into self-signed
# Conflicts:
#	app/build.gradle
#	app/src/main/AndroidManifest.xml
#	app/src/main/res/values/strings.xml
2020-03-31 20:20:18 +02:00
d87bd3a8f7 Merge remote-tracking branch 'remotes/main/master' into add-styling 2020-03-31 20:09:06 +02:00
22010d953a Adjusting sizes in LabelsAdapter 2020-03-31 18:43:52 +02:00
f12219ace7 Restoring branches_list.xml 2020-03-31 16:52:39 +02:00
d2190ad189 Moving classes to helpers/ 2020-03-31 16:44:11 +02:00
e1ccb4e404 Fixed formatting. 2020-03-31 16:41:50 +02:00
39ad052ad5 Merge pull request 'Add Discord badge' (#330) from 6543/GitNex:readme-discord into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/330
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-03-31 13:25:52 +00:00
0f9025f925 Merge pull request 'Repository Commits' (#308) from 13-repo-commits into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/308
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-03-31 05:11:33 +00:00
60781ac4c3 Small design changes. 2020-03-31 05:14:24 +02:00
6b2be06eda Adjusting proportions of issue labels. 2020-03-31 04:04:11 +02:00
c2505d66b5 Merge branch 'master' into 13-repo-commits 2020-03-30 23:12:07 +00:00
9f30299cfa add Discord badge 2020-03-31 00:12:50 +02:00
2b6d22ed94 Modifying license headers. 2020-03-30 23:25:49 +02:00
aa697d11ad Adding, customizing and modifying MemorizingTrustManager. 2020-03-30 23:01:54 +02:00
6e0880e6d8 Handle reserved names & patterns on repo creation (#315)
correct var names

working solution

code format ...

first draft

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/315
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-03-29 18:57:19 +00:00
0820dc3480 Merge branch 'master' into 13-repo-commits
# Conflicts:
#	app/src/main/res/values/strings.xml
2020-03-29 19:27:56 +05:00
2fd291527f Enhance user ux to focus on input and trigger keyboard (#314)
Merge branch 'master' into 305-triiger-keyboard

Enhance user ux to focus on input and trigger keyboard

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/314
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-03-29 14:24:38 +00:00
d923585d9a Merge pull request 'Code style project wise' (#313) from 216-code-style into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/313
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-03-29 14:18:54 +00:00
e89f12f61e Merge pull request 'Changelog popup' (#296) from 262-changelog-popup into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/296
2020-03-29 14:18:20 +00:00
25c6a9558f simplify code 2020-03-29 16:04:04 +02:00
667d98329c Merge branch 'master' into 262-changelog-popup 2020-03-29 13:45:39 +00:00
3955b64efb Add to readme 2020-03-29 16:18:16 +05:00
6e7e3ef690 Code style as whichever is availability in idea 2020-03-29 11:09:51 +05:00
9717589427 Merge pull request 'Fix http protocol' (#311) from 307-fix-open-repo-url into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/311
2020-03-28 17:21:12 +00:00
2bda0dbe7e fix http protocol for open repo url 2020-03-28 21:08:11 +05:00
d52ff1557f Fix login issue with internet access. Better solution to check internet connection
with broadcast receiver. Prioritize token login.
2020-03-28 19:49:08 +05:00
6842ba1410 Remove commits tab, moved under branch. Commits are under branches now.
Fixes search ui along the way
2020-03-28 17:44:45 +05:00
21aae88e62 Refactor naming convention for better findings 2020-03-28 15:52:09 +05:00
ea9025296a final implementation and ui completion of commits list 2020-03-27 23:59:24 +05:00
e963d3483b Merge branch 'master' into 262-changelog-popup 2020-03-25 19:48:49 +05:00
c8164c56d0 Initial work on commits list using paging library 2020-03-25 19:43:40 +05:00
162e86f0c0 Merge pull request 'Fix encoding on login' (#306) from fix-encoding into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/306
2020-03-24 08:36:24 +00:00
fec0945be9 Fix encoding on login 2020-03-24 13:33:35 +05:00
c3c0749a7a show when update/install app 2020-03-21 23:52:52 +05:00
a9b8e15812 use StandardCharsets instead 2020-03-19 18:54:20 +05:00
c57d39e3f4 Merge branch 'master' into 262-changelog-popup 2020-03-19 18:52:57 +05:00
154065d43c Merge pull request 'hotfix for #297' (#298) from a671916c/GitNex:master into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/298
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-03-18 18:24:35 +00:00
0e7df87a60 hotfix for #297 2020-03-18 18:30:18 +01:00
e40eb5e6a1 changelog popup initial working draft 2020-03-17 20:56:37 +05:00
17e9e43454 Merge pull request 'Create repository from organization menu, refactors too' (#295) from 257-add-create-repo-to-org-menu into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/295
2020-03-17 10:39:31 +00:00
2b976f58ba Check if data really exists 2020-03-17 15:36:26 +05:00
7e8d2c6ec2 Create repository from organization menu, refactors too 2020-03-17 15:32:03 +05:00
b5b69f377e Merge pull request 'Show only issues' (#294) from 224-show-issues-only into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/294
2020-03-17 07:24:13 +00:00
614e053796 Show only issues 2020-03-17 12:19:59 +05:00
da16439975 Merge pull request 'Fix divider color in themes' (#293) from fix-divider-color-in-themes into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/293
2020-03-16 20:11:03 +00:00
6cb06d918d Fix divider color in themes 2020-03-17 01:07:23 +05:00
8df11645e8 Add file size to Files (#292)
Merge branch 'master' into 290-file-size

# Conflicts:
#	app/src/main/res/values/strings.xml

Generic word for size text

Add file size to Files

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/292
2020-03-16 20:01:49 +00:00
ef9a0d57c2 Merge pull request 'Share feature and some refactor to easily manage source code files' (#291) from 282-share-feature into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/291
2020-03-16 19:56:40 +00:00
79bd96f6a2 Share feature and some refactor to easily manage source code files 2020-03-17 00:28:03 +05:00
c2e80199ca Merge pull request 'Fix breadcrumb navigation' (#288) from 287-fix-files-breadcrumb-listner into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/288
2020-03-16 14:45:42 +00:00
8921543ef5 Fix breadcrumb navigation 2020-03-16 19:30:41 +05:00
e35846ab51 Merge pull request 'update libs, fix required bugs after update libs, bump app ver' (#286) from update-libs into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/286
2020-03-16 09:33:45 +00:00
375c12b192 update libs, fix required bugs after update libs, bump app ver 2020-03-16 14:25:15 +05:00
fe22d8ab42 Merge pull request 'crowdin update' (#284) from 6543/GitNex:crowdin_2020-03-15 into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/284
Reviewed-by: M M Arif <mmarif@swatian.com>
2020-03-15 18:44:08 +00:00
d16b1580dd crowdin update 2020-03-15 19:36:59 +01:00
c47c81e71f Prepare release 2.4.0 (#283)
Remove Translucent background

Fix missing theme colors, layouts using standard

Fix toolbar color

Prepare 2.4.0 release

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/283
2020-03-15 15:09:26 +00:00
c981ec2f16 Fixes for 2.4 release (#281)
Fix unnecessary reset for repositories

merge screen background color

Merge branch 'master' into fixes-2.4

Add bottom margin for smaller devices

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/281
2020-03-14 14:22:50 +00:00
26429ca6e7 Crowdin [2020-03-11] (#277)
update

update from crowdin

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/277
2020-03-13 19:51:29 +00:00
d06a439382 Merge pull request 'Add page and limit params to required API calls' (#279) from 273-add-page-limit-param into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/279
2020-03-13 19:30:11 +00:00
e7433fd67d Merge pull request '[Fileviewer] Download files, Don't render specific files' (#275) from 254-download-files into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/275
2020-03-13 19:29:24 +00:00
0467686cc3 Enhance diff view to not render all files (#274)
Merge branch 'master' into 269-dont-render-files

exlucde certain bin files

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/274
2020-03-13 19:28:29 +00:00
b0d5161c22 Merge pull request 'fix background color' (#280) from fixes-2.4 into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/280
2020-03-13 14:32:57 +00:00
64839fdc44 fix background color 2020-03-13 19:30:43 +05:00
d441833952 Add page and limit params to required API calls 2020-03-12 19:56:56 +05:00
a2672560da Merge branch 'master' into 254-download-files 2020-03-11 15:29:37 +00:00
f7d5ee9e7a Update for issue 267 2020-03-09 21:13:40 +05:00
3a481084b6 Merge branch 'master' into 254-download-files
# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java
2020-03-08 19:24:41 +05:00
4ac1f4f486 Single issue ui enhancements (#272)
Merge branch 'master' into 270-single-issue-ui-enhancements

improve single issue title

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/272
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-03-08 14:14:46 +00:00
d2f5f09c75 Merge pull request 'Theme and Icons' (#260) from light-theme into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/260
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-03-08 13:52:25 +00:00
181a94edbe download file and ask for permissions to write into storage 2020-03-08 12:46:31 +05:00
5b8c485883 Fix variable name 2020-03-08 10:54:33 +05:00
3794d7ff2b wip on download files 2020-03-08 10:53:00 +05:00
9a9b836c40 Fix file diff background 2020-03-07 13:30:45 +05:00
900b060c31 Use only one statement for new theme. 2020-03-07 01:07:54 +05:00
61f953d70d Fixes layout issue with themes, added pdf night mode switch in settings 2020-03-06 18:46:22 +05:00
14addf5ed0 added theme selection to settings, updated login layout. 2020-03-06 01:56:42 +05:00
b012a7058d Fixes to color styles and layouts 2020-03-05 20:23:15 +05:00
51ab3f7a92 updated all the layouts and activities 2020-03-05 00:37:28 +05:00
a8cc4c00b8 worked on repo info, files tabs and files activity 2020-03-04 21:15:57 +05:00
d557999a38 Merge branch 'master' into light-theme 2020-03-04 19:58:03 +05:00
1008b8611d Added custom attr to more files 2020-03-04 19:54:21 +05:00
3f4db112b1 Refactor assignee(s) API calls (#199)
Merge branch 'master' into refactor_issues_call

Remove credits, add donators (#268)

Merge branch 'master' into 264-remove-credits

Merge pull request 'Support for c header files' (#266) from 265-files-support-in-file-viewer into master

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/266

Remove credits, add donators

support for c header files

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/268

Merge pull request 'Support for c header files' (#266) from 265-files-support-in-file-viewer into master

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/266

support for c header files

fix

Merge branch 'master' into refactor_issues_call

Support pdf files in file viewer (#259)

auto convert EOL

this fix it for me

fix layout

implement support for pdf files in file viewer

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/259
Reviewed-by: 6543 <6543@noreply.gitea.io>

Make DueDate optional on MilestoneCreaton (#252)

Merge branch 'master' into milestone-DueDate-optional_240

add check again if gitea is older than 1.10.0 ...

Crowdin [2020-01-04] + add Latvian (#253)

update Translators

add Latvian

update Crowdin

Co-authored-by: 6543 <6543@obermui.de>

make DueDate optional on MilestoneCreaton

Co-authored-by: 6543 <6543@obermui.de>

Crowdin [2020-01-04] + add Latvian (#253)

update Translators

add Latvian

update Crowdin

Co-authored-by: 6543 <6543@obermui.de>

Merge branch '51-custom-fonts' of gitnex/GitNex into master

Reviewed-by: 6543 <6543@noreply.gitea.io>

Implement across the whole app

Implementation of custom fonts app wide

Merge branch 'crowdin_2019-12-25' of gitnex/GitNex into master

add user to the “new issue” assignees dialog

refactor.start()

update from crowdin

Merge branch 'backport-243' of gitnex/GitNex into master

backport url slashes fix

Merge branch 'fix-238' of gitnex/GitNex into master

fix

Merge branch 'backport-235' of gitnex/GitNex into master

backport fix #235

Merge branch 'backport-232' of gitnex/GitNex into master

show all issues and prs

Merge branch '206-repos-in-explore-screen' of gitnex/GitNex into master

Load default list of explore repositories

Merge branch '225-backport' of gitnex/GitNex into master

copy and support files backport - #225

Merge branch '226-backport' of gitnex/GitNex into master

fix alignments backport

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/199
2020-02-24 18:50:51 +00:00
5720c5f613 Remove credits, add donators (#268)
Merge branch 'master' into 264-remove-credits

Merge pull request 'Support for c header files' (#266) from 265-files-support-in-file-viewer into master

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/266

Remove credits, add donators

support for c header files

Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/268
2020-02-21 05:58:36 +00:00
e0b25c77a0 Merge pull request 'Support for c header files' (#266) from 265-files-support-in-file-viewer into master
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/266
2020-02-21 05:54:53 +00:00
2c163fdc9c support for c header files 2020-02-20 10:24:14 +05:00
acdb9ce682 updates to other files 2020-02-20 10:19:52 +05:00
dbcd80eace updated settings, star and my repos layouts 2020-02-04 19:19:39 +05:00
8b75cac9d8 New spinner style 2020-02-03 00:14:38 +05:00
1293e8be27 Support pdf files in file viewer (#259)
auto convert EOL

this fix it for me

fix layout

implement support for pdf files in file viewer

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/259
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-01-30 18:00:31 +00:00
50671907ba changed checkbox style and input background 2020-01-29 19:31:27 +05:00
ec62e3cebf Make DueDate optional on MilestoneCreaton (#252)
Merge branch 'master' into milestone-DueDate-optional_240

add check again if gitea is older than 1.10.0 ...

Crowdin [2020-01-04] + add Latvian (#253)

update Translators

add Latvian

update Crowdin

Co-authored-by: 6543 <6543@obermui.de>

make DueDate optional on MilestoneCreaton

Co-authored-by: 6543 <6543@obermui.de>
2020-01-14 12:52:34 +00:00
36774620db initial work on adding new theme 2020-01-07 17:27:05 +05:00
b3e67113f5 Crowdin [2020-01-04] + add Latvian (#253)
update Translators

add Latvian

update Crowdin

Co-authored-by: 6543 <6543@obermui.de>
2020-01-05 12:07:29 +00:00
d8de0effef Merge branch '51-custom-fonts' of gitnex/GitNex into master
Reviewed-by: 6543 <6543@noreply.gitea.io>
2020-01-02 14:40:28 +00:00
0533fd9ae5 Implement across the whole app 2020-01-02 12:51:10 +05:00
6d7308210b Implementation of custom fonts app wide 2020-01-02 01:03:53 +05:00
e9dcfc57f7 Merge branch 'crowdin_2019-12-25' of gitnex/GitNex into master 2019-12-26 02:07:36 +00:00
ab6f5d3364 update from crowdin 2019-12-25 20:48:52 +01:00
e422e3e254 Merge branch 'backport-243' of gitnex/GitNex into master 2019-12-25 19:18:17 +00:00
a00d76d0e2 backport url slashes fix 2019-12-26 00:14:33 +05:00
f68c26b70d Merge branch 'fix-238' of gitnex/GitNex into master 2019-12-24 19:22:14 +00:00
25cc2f27ee fix 2019-12-24 17:09:24 +01:00
72ccc06226 Merge branch 'backport-235' of gitnex/GitNex into master 2019-12-13 13:38:09 +00:00
9a66ea0fb6 backport fix #235 2019-12-13 13:55:58 +05:00
aab9ae9e35 Merge branch 'backport-232' of gitnex/GitNex into master 2019-12-04 18:41:19 +00:00
d922c21f70 show all issues and prs 2019-12-04 23:38:53 +05:00
6e02fc1827 Merge branch '206-repos-in-explore-screen' of gitnex/GitNex into master 2019-12-03 16:27:18 +00:00
536665be5f Load default list of explore repositories 2019-12-03 18:20:26 +05:00
29cc8a2ad4 Merge branch '225-backport' of gitnex/GitNex into master 2019-12-02 15:00:37 +00:00
7d4d7cfa69 copy and support files backport - #225 2019-12-02 19:58:36 +05:00
48638e93be Merge branch '226-backport' of gitnex/GitNex into master 2019-12-02 14:55:12 +00:00
584c08ff70 fix alignments backport 2019-12-02 19:52:11 +05:00
13a0b55612 Merge branch 'prepare-release-2.3' of gitnex/GitNex into master 2019-11-29 12:33:00 +00:00
94d4dbf440 add new sponsors 2019-11-29 17:31:19 +05:00
82034273c4 Crowdin [2019-11-29] + smal doc (#220) 2019-11-29 12:29:44 +00:00
cf22a5d5fa Merge branch 'allowRestrictedApi' of Unpublished/GitNex into master 2019-11-27 20:06:29 +00:00
fde33dbc3e Allow login if api is restricted 2019-11-27 20:27:31 +01:00
85a7fddc49 Merge branch '171-screens' of gitnex/GitNex into master 2019-11-27 18:05:55 +00:00
25fbc4b017 Add screens, update readme, f-droid desc 2019-11-27 22:55:09 +05:00
fc02b652f5 [Crowdin] 2019-11-27 + add Portuguese/Brazilian (#211) 2019-11-27 17:05:32 +00:00
a32e11c172 Merge branch '10-merge-pr' of gitnex/GitNex into master 2019-11-27 17:03:49 +00:00
51dc31ef15 merge pull request activity and call 2019-11-27 20:09:26 +05:00
5b4cb3ff8e Added interface and model 2019-11-25 19:19:13 +05:00
0daf0d1110 Merge branch '207-move-version-to-main-activity' of gitnex/GitNex into master 2019-11-25 13:14:33 +00:00
533be20f46 Move Gitea version to main activity 2019-11-25 18:12:44 +05:00
8b88dca833 Merge branch '205-refactor-version-code' of gitnex/GitNex into master 2019-11-25 13:06:52 +00:00
94d6334e52 refactor versions 2019-11-25 18:04:34 +05:00
79f6a2435b Crowdin [2019-11-25] + add Ukrainian (#204) 2019-11-25 12:12:11 +00:00
9f5eceff0e Repository PR List (#198) 2019-11-24 12:42:57 +00:00
f9550ad115 Merge branch '119-app-tokens' of gitnex/GitNex into master 2019-11-16 05:18:41 +00:00
7e8a2722ac Fix creating multiple tokens. The changes were from upstream API 2019-11-16 00:39:09 +05:00
51da8b9c4d Merge branch 'refactor-donate-credit-pages' of gitnex/GitNex into master 2019-11-14 17:00:24 +00:00
29fb2631cb refactored credit activtiy 2019-11-14 21:58:38 +05:00
126d1d0896 Refactor sponsors activity 2019-11-13 23:23:20 +05:00
b6c0e94ee9 Offline mode (#190) 2019-11-13 15:52:49 +00:00
80445952b1 Crowdin [2019-11-09] (#194) 2019-11-13 13:49:51 +00:00
d61fb8a0c6 Merge branch 'crowdin_2019-11-07' of gitnex/GitNex into master 2019-11-07 14:05:22 +00:00
51c88e9f45 update from crowdin 2019-11-07 13:31:35 +01:00
463961800f [File View] add highlight sourcecode (#187) 2019-11-05 08:34:22 +00:00
04073ac873 tocken name with Device ID (#184) 2019-11-01 06:01:30 +00:00
26b93a4280 Merge branch '182-fix-date-layout' of gitnex/GitNex into master 2019-10-31 14:29:48 +00:00
71be20b1b9 increase space for date and time 2019-10-31 18:23:36 +05:00
9f833259f7 Add limit to explore API 2019-10-31 18:16:11 +05:00
d184bdca12 Merge branch '175-fileview-support-images' of gitnex/GitNex into master 2019-10-30 18:00:03 +00:00
15b320f4bd Images support in file viewer. Android Q support. 2019-10-30 19:04:49 +05:00
fdc1514f5f Merge branch 'change-in-search-176' of gitnex/GitNex into master 2019-10-29 06:32:39 +00:00
67f4283cb9 Use search and magnify icon 2019-10-29 11:28:59 +05:00
fc2b09b91c Crowdin [2019-10-28] + Turkish support (#177) 2019-10-29 05:34:01 +00:00
eb38df745c Merge branch '94-login-via-token' of gitnex/GitNex into master 2019-10-26 18:38:58 +00:00
8787f8d9eb store loginUid on login 2019-10-26 18:01:14 +05:00
7e3eef90d2 radio buttons style to match the theme. error toast on failure 2019-10-25 23:19:16 +05:00
c4b0b596d3 fixes in fdroid repository description file 2019-10-25 10:55:00 +05:00
2aaf0eb103 refactor the strings and reuse them in login screen files 2019-10-25 08:38:35 +05:00
f9d51094e4 done with token logins, refactor some code 2019-10-24 22:42:09 +05:00
96ab992264 implement login via token 2019-10-24 20:48:00 +05:00
bc2b609585 Merge branch '166-improve-edit-button-api-calls' of gitnex/GitNex into master 2019-10-22 16:42:03 +00:00
2a05d4e24b improve edit button on tap 2019-10-22 21:37:11 +05:00
fb9d101283 Merge branch 'app-color-scheme' of gitnex/GitNex into master 2019-10-22 16:03:55 +00:00
ef2f5a9667 change color scheme 2019-10-22 21:00:55 +05:00
d14ecd9c68 Version Check before try to Login (#147) 2019-10-22 15:27:33 +00:00
d29b1901c0 Merge branch '158-fix-email-login' of gitnex/GitNex into master 2019-10-21 16:46:28 +00:00
6d7fcd8430 Fix login with email for my repositories 2019-10-21 20:39:42 +05:00
b6ca7bf2a4 Merge branch 'fix-empty-repo-bug' of gitnex/GitNex into master 2019-10-18 13:44:29 +00:00
24d56c625e Fix #154 2019-10-18 18:40:54 +05:00
67add714b3 Merge branch 'prepare-release-2.2' of gitnex/GitNex into master 2019-10-18 06:47:22 +00:00
5970995ef0 added file viewer 2019-10-18 10:28:18 +05:00
cf75c61704 release 2.2.0 2019-10-18 10:10:47 +05:00
8ac92a8b3c Merge branch '121-sub-dir-browsing' of gitnex/GitNex into master 2019-10-17 22:49:49 +00:00
f1f92ba494 make CI work 2019-10-18 00:46:19 +02:00
d7b1a226d0 implemented sub dir view 2019-10-17 22:47:27 +05:00
2bebe1e81d Merge branch 'crowdin_2019-10-17' of gitnex/GitNex into master 2019-10-17 15:54:59 +00:00
f5d560c601 Update Crowdin 2019-10-17 16:09:40 +02:00
d27000d481 Merge branch 'minor-fixes' of gitnex/GitNex into master 2019-10-17 13:57:55 +00:00
9aff1cb42a Minor ui fixes 2019-10-16 18:28:24 +05:00
7fe376fa44 Merge branch 'improve-ci' of gitnex/GitNex into master 2019-10-14 10:02:31 +00:00
6da4398369 dont run with empty task 2019-10-14 11:27:04 +02:00
dac0f690d8 more precise name 2019-10-14 11:06:46 +02:00
8a7031e7f5 Merge branch 'translation_add-Serbian' of 6543/GitNex into master 2019-10-14 05:11:31 +00:00
dd5f17d54d format code 2019-10-13 19:19:44 +02:00
505c930c32 first sr strings 2019-10-13 19:19:20 +02:00
edb6cdf154 add Serbian to Settings 2019-10-13 19:19:04 +02:00
687b66751f Merge branch 'crowdin_2019-10-13' of gitnex/GitNex into master 2019-10-13 12:51:24 +00:00
f14ae18324 Merge branch 'translation_add-Italian' of 6543/GitNex into master 2019-10-13 12:50:46 +00:00
ea52d6c6d2 dont run twice 2019-10-13 02:46:52 +02:00
40d12c3b97 Update Translation 2019-10-13 02:13:53 +02:00
32ebf31ef4 add first it strings 2019-10-13 02:08:46 +02:00
7fc4146c98 add Italian 2019-10-13 02:08:27 +02:00
e296a83aab Merge branch 'update-libs' of gitnex/GitNex into master 2019-10-12 17:13:43 +00:00
0fc7c67d0b update libs 2019-10-12 19:34:33 +05:00
143d680627 Merge branch '136-watch-a-repo' of gitnex/GitNex into master 2019-10-12 13:29:43 +00:00
69745b027e Implemented watch and unwatch a repository 2019-10-12 14:00:36 +05:00
7f3aed9bae fix star repo layout 2019-10-12 12:55:12 +05:00
5496401a77 Merge branch '130-star-a-repo' of gitnex/GitNex into master 2019-10-11 20:18:15 +00:00
4c0fd3c286 Implemented star/unstar a repository 2019-10-12 01:03:01 +05:00
40f924de2e Merge branch 'translation_add-Finnish' of 6543/GitNex into master 2019-10-11 19:24:49 +00:00
1953a9feff add Finnish 2019-10-11 20:14:59 +02:00
24c71b4beb Merge branch 'drone-rename-pipeline' of gitnex/GitNex into master 2019-10-11 18:08:52 +00:00
958606e476 add first strings 2019-10-11 20:07:50 +02:00
39d1007423 Drone Rename Pipeline
Rename Pipeline -> it does not loon nice and does not make sense
2019-10-11 18:02:40 +00:00
0e673bb256 Merge branch 'mentions' of 6543/GitNex into master 2019-10-11 16:53:11 +00:00
246ff6296a new line " " and italic 2019-10-11 18:34:22 +02:00
1d0b940c14 add sugestions + new translator 2019-10-11 18:15:19 +02:00
4d3fb54925 Merge branch 'lunny/add_ci_badge' of lunny/GitNex into master 2019-10-11 15:44:36 +00:00
cd81ff74bf add mentions 2019-10-11 16:57:53 +02:00
02843b4ca1 Add CI status badge on README 2019-10-11 13:15:05 +00:00
2189bd10bd Merge branch '100-bottomsheet-scroll' of gitnex/GitNex into master 2019-10-11 13:08:57 +00:00
35b9647709 improve bottomsheet with scroll and separater 2019-10-11 16:36:42 +05:00
2d2f486182 Merge branch '88-update-images' of gitnex/GitNex into master 2019-10-10 19:54:37 +00:00
640771d4fa update store images, update app description 2019-10-10 22:38:09 +05:00
2ba8a80b9f Merge branch 'repoSearch' of 6543/GitNex into master 2019-10-10 16:02:04 +00:00
2f55e7f5d1 enable to browse repository 2019-10-10 20:49:12 +05:00
d285115090 reset the adapter on new query 2019-10-10 19:01:15 +05:00
d5cffddc72 Implemented search ui and screen for exploring repositories. 2019-10-10 18:40:43 +05:00
9e2921697b Merge branch 'add-drone-ci' of gitnex/GitNex into master 2019-10-10 07:49:12 +00:00
e868364554 Merge branch 'crowdin_2019-10-10' of gitnex/GitNex into master 2019-10-10 07:48:27 +00:00
88a8303b1c Add Drone CI Config
* testing
       - test
       - build
2019-10-10 03:29:35 +02:00
ac1fc696ea complete france translation 2019-10-10 01:40:54 +02:00
2fe175223c combine commits
* add Explore Function
* define API
* Add Fragment + Code + String
* add to main activity (by @mmarif)
2019-10-10 01:21:34 +02:00
9cab502e84 Merge branch 'mv-org-update-links' of 6543/GitNex into master 2019-10-09 18:40:12 +00:00
88748998b3 update repo links 2019-10-09 16:09:07 +02:00
264ed393cb Merge branch 'readme-add-crowdin' of 6543/GitNex into master 2019-10-08 15:27:27 +00:00
821eef91a3 Merge branch 'crowdin_2019-10-07' of mmarif/GitNex into master 2019-10-08 15:26:56 +00:00
05afc9fc5a Merge branch 'crowdin-add-Persian' of 6543/GitNex into master 2019-10-08 15:26:18 +00:00
4cb6948288 Merge branch 'build-fix' of mmarif/GitNex into master 2019-10-08 14:48:28 +00:00
7012c2587c crowdin update 2019-10-08 02:54:18 +02:00
dbcbd076ea Build Fix 2019-10-08 02:41:39 +02:00
c633b62fdb show screenshots directly 2019-10-07 19:53:41 +02:00
1ce1a15955 mv Translation info (CONTRIBUTE -> README)
wil close https://gitea.com/mmarif/GitNex/issues/108
2019-10-07 19:53:30 +02:00
60b95e3c5d Add first Persian strings
got it from 243e53895b
2019-10-07 12:42:15 +02:00
48fb0cf91c add Persian to settings 2019-10-07 12:41:27 +02:00
8fcb05b0d2 Merge branch 'fixes' of mmarif/GitNex into master 2019-10-07 07:05:36 +00:00
074bbfe3cc Minor translation files fixes 2019-10-07 12:01:04 +05:00
84438b740a Merge branch '43-file-browser' of mmarif/GitNex into master 2019-10-07 06:32:42 +00:00
d4cd16a111 Merge branch 'master' into 43-file-browser 2019-10-07 11:26:24 +05:00
5ed053bba7 Merge branch 'crowdin-add-zh-CN' of mmarif/GitNex into master 2019-10-07 06:05:50 +00:00
598633a20a add first Chinese strings
@lunny thanks
2019-10-06 06:04:00 +02:00
8fe53dfd01 Settings: Languages: add Chinese and sort alphabetic 2019-10-06 06:01:48 +02:00
aadbcbd0c6 Merge branch 'crowdin-add-ar' into master 2019-10-04 19:25:53 +00:00
e3b901741a Add Untranslated Arabic 2019-10-04 20:56:29 +02:00
f8275cd7aa add Arabic to settings 2019-10-04 20:56:28 +02:00
c3afe1044c Merge branch 'crowdin' into master 2019-10-04 18:43:45 +00:00
a6503ba7c4 Crowdin Update 2019-10-04 20:26:20 +02:00
dddc9b0178 smal link fix for Translation 2019-10-04 20:24:44 +02:00
13bc50da40 git ignore crowdin config (crowdin.yml) 2019-10-04 20:23:43 +02:00
b32d291554 Merge branch 'translation-tool' of 6543/GitNex into master 2019-10-04 15:56:43 +00:00
c15e6e99f7 Added Arabic file 2019-10-04 20:46:56 +05:00
1512032f05 move corwdin Link to strings 2019-10-04 17:44:38 +02:00
e32ccde995 add info if lang is not listed 2019-10-04 16:55:09 +02:00
1be577cd3f add ClickListener to open Translation URL 2019-10-04 16:25:27 +02:00
7fa57621d9 change about layout 2019-10-04 16:20:46 +02:00
75ac6ff113 Add Crowdin Badge 2019-10-04 16:08:40 +02:00
9ef04b1287 change CONTRIBUTING.md for Crowdin 2019-10-04 16:08:17 +02:00
8c903b9658 remove some comments 2019-10-04 12:23:56 +05:00
08b8275546 translation files updates 2019-10-04 12:08:21 +05:00
5baacbd801 revert back 2019-10-04 00:21:34 +05:00
56b8b486df Merge branch 'release-2.1' into 43-file-browser 2019-10-04 00:06:03 +05:00
7abfdc9567 Merge branch 'fix-old-gitea-api' of mmarif/GitNex into release-2.1 2019-10-03 19:03:06 +00:00
0ab8784a7a another quick release and another old Gitea instances issue 2019-10-04 00:00:05 +05:00
e4ab2f64fc wip, need clean up 2019-10-03 23:50:57 +05:00
345d577fbf Merge branch 'release-2.1' into 43-file-browser 2019-10-03 21:53:38 +05:00
22b3802e73 Merge branch 'fixes-2.1.2' of mmarif/GitNex into release-2.1 2019-10-03 16:45:36 +00:00
07a1fa6aad Fix crashes on my repo, starred repos etc - 2.1.2 release 2019-10-03 21:43:33 +05:00
5c9b53f5ab api interface for sub dirs
Signed-off-by: M M Arif <mmarif@swatian.com>
2019-10-03 21:32:09 +05:00
572f93d35c Idea to use breadcrumb 2019-10-03 20:57:49 +05:00
a77716970b update gradle 2019-10-03 12:15:55 +05:00
4d998150a3 click listener checks for file, dir and unknwon files 2019-10-02 23:32:01 +05:00
90df3a31fe Merge branch 'release-2.1' into 43-file-browser 2019-10-02 22:47:46 +05:00
4904b5899f Merge branch 'fixes-2.1' of mmarif/GitNex into release-2.1 2019-10-02 17:26:30 +00:00
f19327431f fix bugs since 2.1.0 release 2019-10-02 22:24:02 +05:00
0bcbca8bdc Fix crash from gplay console, app crash when no avatar url node is present in API. old gitea instances. 2019-10-02 22:11:10 +05:00
b90b3c3320 Added reading file contentts 2019-10-02 21:32:59 +05:00
21097da995 filter files and dirs 2019-10-02 18:21:44 +05:00
06b71586c1 Sort by folder 1st approach 2019-10-02 17:58:29 +05:00
d2213c0c14 new file icon 2019-10-02 13:59:34 +05:00
4c3b735534 translation updates 2019-10-02 13:35:14 +05:00
90dce6fff8 added layout, view models, adapter and fragment 2019-10-02 13:30:07 +05:00
d9337a24d3 Fixes since 2.1.0 release, ms progress bar fix, create issue enable fix 2019-10-01 22:45:21 +05:00
45ec660ba1 Merge branch 'master' into 43-file-browser 2019-10-01 21:23:03 +05:00
bb24254e66 added files model 2019-10-01 20:07:37 +05:00
13e69cd09b files tab in repo tabs 2019-10-01 19:48:20 +05:00
71839bcfd6 clean up 2019-10-01 19:35:51 +05:00
619 changed files with 38872 additions and 11142 deletions

104
.drone.yml Normal file
View File

@ -0,0 +1,104 @@
---
kind: pipeline
type: docker
name: tests
steps:
- name: unit-tests
image: nextcloudci/android:android-49
depends_on: [ clone ]
commands:
- ./gradlew test
- name: check-formatting
image: zosiab/eclint:latest
depends_on: [ clone ]
commands:
- git pull origin master
- eclint check $(git diff --name-only origin/master)
# This may be used in the future, because it makes of intellij's native code inspection/formatting capabilities.
# Additional information: https://www.jetbrains.com/help/idea/command-line-formatter.html
#
# - name: do-or-check-formatting
# image: dlsniper/docker-intellij
# depends_on: [ clone ]
# commands:
# - /opt/intellij/bin/idea.sh inspect/format ...
#
# - name: do-or-check-formatting
# image: dlsniper/docker-intellij
# depends_on: [ clone ]
# commands:
# - /opt/intellij/bin/idea.sh format -s .idea/codeStyles/Project.xml -m *.java app/src/main/java
trigger:
event:
- pull_request
---
kind: pipeline
type: docker
name: code-analysis
steps:
- name: check-global-formatting
image: zosiab/eclint:latest
depends_on: [ clone ]
commands:
- eclint check $(git ls-files)
trigger:
event:
- push
branch:
- master
---
kind: pipeline
type: docker
name: build
steps:
- name: build
image: nextcloudci/android:android-49
commands:
- ./gradlew build
- name: sign
image: nextcloudci/android:android-49
environment:
BOT_TOKEN:
from_secret: BOT_TOKEN
KS_PASS:
from_secret: KS_PASS
KEY_PASS:
from_secret: KEY_PASS
OUTPUT: signed.apk
GITEA: https://gitea.com
KS_FILE: ci_keystore.jks
KS_REPO:
from_secret: KS_REPO
commands:
- ./scripts/sign-build.sh
- name: publish
image: vividboarder/drone-webdav
environment:
WEBDAV_USERNAME: GitNexBot
WEBDAV_PASSWORD:
from_secret: NC_TOKEN
PLUGIN_FILE: 'signed.apk'
PLUGIN_TIMEOUT: 180
PLUGIN_ATTEMPTS: 5
PLUGIN_DESTINATION: 'https://cloud.swatian.com/remote.php/dav/files/GitNexBot/gitnex/builds/latest.apk'
PLUGIN_CUSTOM_ARGUMENTS: '--progress-bar'
trigger:
event:
- push
branch:
- master

25
.editorconfig Normal file
View File

@ -0,0 +1,25 @@
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 150
[*.java]
indent_style = tab
line_comment = //
block_comment_start = /*
block_comment = *
block_comment_end = */
[*.json]
indent_size = 2
[{*.yml,*.yaml}]
indent_size = 2
[*.md]
trim_trailing_whitespace = false
insert_final_newline = false

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

32
.gitea/issue_template.md Normal file
View File

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

View File

@ -0,0 +1,8 @@
Please check the following:
1. Make sure you are targeting the `master` branch, pull requests on release branches are only allowed for bug fixes.
2. Read contributing guidelines: [CONTRIBUTING.md](https://gitea.com/GitNex/GitNex/src/branch/master/CONTRIBUTING.md)
3. Please follow the [Code-Standards](https://gitea.com/gitnex/GitNex/wiki/Code-Standards)
4. Describe what your pull request does and which issue youre targeting (create one if does not exist)
**You MUST delete the content above including this line before posting, otherwise your pull request will be invalid.**

7
.gitignore vendored
View File

@ -8,6 +8,9 @@
*.ap_
*.aab
# Release dir
app/release/*
# Files for the ART/Dalvik VM
*.dex
@ -48,6 +51,7 @@ captures/
.idea/dictionaries
.idea/libraries
.idea/caches
!.idea/codeStyles
# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
@ -180,6 +184,9 @@ crashlytics.properties
crashlytics-build.properties
fabric.properties
# Crowdin
crowdin.yml
### AndroidStudio Patch ###
!/gradle/wrapper/gradle-wrapper.jar

63
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,63 @@
stages:
- test
- build
- sign
- publish
test:
image: nextcloudci/android:android-49
stage: test
script:
- ./gradlew test
build:
image: nextcloudci/android:android-49
stage: build
only:
- master
script:
- ./gradlew build
artifacts:
paths:
- app/build/outputs/
expire_in: 15 minutes
sign:
image: nextcloudci/android:android-49
stage: sign
only:
- master
variables:
OUTPUT: "signed.apk"
GITEA: "https://gitea.com"
KS_FILE: "ci_keystore.jks"
script:
- ./scripts/sign-build.sh
artifacts:
paths:
- signed.apk
expire_in: 15 minutes
latest:
image: tutum/curl
stage: publish
only:
- master
variables:
WEBDAV_USERNAME: "GitNexBot"
PLUGIN_FILE: "signed.apk"
PLUGIN_DESTINATION: "https://cloud.swatian.com/remote.php/dav/files/GitNexBot/gitnex/builds/latest.apk"
script:
- curl -T "$PLUGIN_FILE" -u "$WEBDAV_USERNAME":"$WEBDAV_PASSWORD" "$PLUGIN_DESTINATION"
release:
image: tutum/curl
stage: publish
only:
- tags
variables:
WEBDAV_USERNAME: "GitNexBot"
PLUGIN_FILE: "signed.apk"
script:
- "[[ $CI_COMMIT_REF_NAME == *'-rc'* ]] && echo 'Upload blocked. Build seems to be a release candidate.' && exit 0"
- curl -T "$PLUGIN_FILE" -u "$WEBDAV_USERNAME":"$WEBDAV_PASSWORD" 'https://cloud.swatian.com/remote.php/dav/files/GitNexBot/gitnex/releases/'"$CI_COMMIT_REF_NAME"'.apk'

165
.idea/codeStyles/Project.xml generated Normal file
View File

@ -0,0 +1,165 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JavaCodeStyleSettings>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
<package name="androidx" withSubpackages="true" static="false" />
<package name="com" withSubpackages="true" static="false" />
<package name="junit" withSubpackages="true" static="false" />
<package name="net" withSubpackages="true" static="false" />
<package name="org" withSubpackages="true" static="false" />
<package name="java" withSubpackages="true" static="false" />
<package name="javax" withSubpackages="true" static="false" />
<package name="" withSubpackages="true" static="false" />
<package name="" withSubpackages="true" static="true" />
</value>
</option>
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="220" />
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="BLANK_LINES_BEFORE_METHOD_BODY" value="1" />
<option name="BLANK_LINES_AROUND_FIELD_IN_INTERFACE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="BLANK_LINES_AFTER_ANONYMOUS_CLASS_HEADER" value="1" />
<option name="BLANK_LINES_BEFORE_CLASS_END" value="1" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="3" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

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

View File

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

View File

@ -7,6 +7,11 @@ Patches, enhancements, features are always welcome. The PR should focus on the s
Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work.
**Code Standards**
Please follow the code standards, this will help other developers to understand your code too.
It also helps maintaining the code afterwards.
It is documented in the Wiki: [Code-Standards](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards)
**How to submit a PR**
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.
@ -20,10 +25,3 @@ Before creating an issue please take a moment and search the repository issues(o
In case you want to submit a bug report, please provide as much details as possible to better debug the problem. The important part is how to reproduce the bug and steps to reproduce are appreciated.
**Note:** Please contact the project directly via email(gitnex@swatian.com) if have to share sensitive and security related details.
## Translation
Help us translate GitNex to your native language.
Take a look [here](https://gitea.com/mmarif/GitNex/src/branch/master/app/src/main/res/values/strings.xml) for strings, please ignore the lines with `translatable="false"`. It is recommended to create a Pull Request with your changes.
Check the structure of other languages for example [French](https://gitea.com/mmarif/GitNex/src/branch/master/app/src/main/res/values-fr/strings.xml).

37
CONTRIBUTORS.md Normal file
View File

@ -0,0 +1,37 @@
# Contributors
This part lists all PUBLIC individuals having contributed content to the code.
* M M Arif (mmarif)
* 6543
* opyale
* Unpublished
# Translators
This part lists all PUBLIC individuals having contributed content to the translation.
*Entries are in alphabetical order*
* 6543
* acrylicpaintboy
* Antoine GIRARD (sapk)
* BaRaN6161_TURK
* ButterflyOfFire (BoFFire)
* dadosch
* erardiflorian
* IndeedNotJames
* jaqra
* Lafriks
* ljoonal
* Lunny Xiao (xiaolunwen)
* lxs
* Marcos de Oliveira (markkrj)
* mmarif
* Nadezhda Moiseeva (digitalkiller)
* Oleg Popenkov (FanHamMer)
* PsychotherapistSam
* Rodion Borisov (vintproykt)
* s4ne
* valeriezhao1013
* Vladislav Glinsky (cl0ne)
* Voyvode
**Thank you for all your work** :+1:

63
LICENSE
View File

@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@ -620,55 +620,18 @@ copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
GitNex is an Android client/application for Gitea.
Copyright (C) 2019 The GitNex Authors
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Mastalab is a Mastodon client for Android devices
Copyright (C) 2017 Thomas Schneider
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Mastalab Copyright (C) 2017 Thomas Schneider
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,25 +1,22 @@
[![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/mmarif/GitNex/releases&query=$[0].tag_name)](https://gitea.com/mmarif/GitNex/releases)
[![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)
[<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif) [<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate)
# GitNex - Android client for Gitea
GitNex is a free, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go.
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text.
No trackers are used and source code is available here for anyone to audit.
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. No trackers are used and source code is available here for anyone to audit.
## Downloads
[<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/)
[<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex)
[<img alt='Download APK' src='https://gitnex.com/img/download-apk.png' height="80"/>](https://gitea.com/mmarif/GitNex/releases)
[<img alt='Download builds and releases' src='assets/apk-badge.png' height="82"/>](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE)
## Note about Gitea version
Please make sure that you are on Gitea **1.9.x** stable release or later. Below this may not work as one would expect because of the newly added objects to the API at later versions. Please consider updating your Gitea server.
Please make sure that you are on latest stable release or later for better app experience.
Check the versions [compatibility page](https://gitea.com/mmarif/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio.
Check the versions [compatibility page](https://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.
@ -27,36 +24,50 @@ Option 1 - Download the source code, open it in Android Studio and build it ther
Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew build`.
## Features
- My Repositories
- Repositories list
- Organizations list
- Create repository
- Create organization
- Issues list
- [MANY MORE](https://gitea.com/mmarif/GitNex/wiki/Features)
- Repositories / issues/ org list
- File and directory browser
- File viewer
- Create files
- Explore repositories
- Pull requests
- Files diff for PRs
- Notifications
- Drafts
- [MANY MORE](https://codeberg.org/gitnex/GitNex/wiki/Features)
## Contributing
[CONTRIBUTING](https://gitea.com/mmarif/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://codeberg.org/gitnex/GitNex/issues) to add it to the project.
**Link: https://crowdin.com/project/GitNex**
## Screenshots:
[Screenshots](https://gitea.com/mmarif/GitNex/src/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots)
<img src="https://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://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/mmarif/GitNex/wiki/FAQ)
[Faq](https://codeberg.org/gitnex/GitNex/wiki/FAQ)
## Links
[Website](https://gitnex.com)
[Wiki](https://gitea.com/mmarif/GitNex/wiki/Home)
[Wiki](https://codeberg.org/gitnex/GitNex/wiki/Home)
[Website Repository](https://gitlab.com/mmarif4u/gitnex-website)
[Troubleshoot Guide](https://gitea.com/mmarif/GitNex/wiki/Troubleshoot-Guide)
[Troubleshoot Guide](https://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
@ -69,5 +80,15 @@ Open source libraries
- Abumoallim/android-multi-select-dialog
- Pes/materialcolorpicker
- Hendraanggrian/socialview
- HamidrezaAmz/BreadcrumbsView
- Chrisbanes/PhotoView
- Pddstudio/highlightjs-android
- Apache/commons-io
- Caverock/androidsvg
- Droidsonroids.gif/android-gif-drawable
- Barteksc/AndroidPdfViewer
- Ge0rg/MemorizingTrustManager
- Dimezis/BlurView
- mikaelhg/urlbuilder
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)

View File

@ -1,18 +1,22 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
compileSdkVersion 29
defaultConfig {
applicationId "org.mian.gitnex"
minSdkVersion 21
targetSdkVersion 28
versionCode 60
versionName "2.1.0"
targetSdkVersion 29
versionCode 300
versionName "3.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures {
viewBinding = true
}
buildTypes {
release {
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
@ -20,33 +24,44 @@ android {
//checkReleaseBuilds false
abortOnError false
}
compileOptions {
targetCompatibility = "8"
sourceCompatibility = "8"
}
}
configurations {
cleanedAnnotations
compile.exclude group: 'org.jetbrains', module: 'annotations'
}
dependencies {
def lifecycle_version = "2.2.0-alpha05"
final def markwon_version = "4.1.1"
def lifecycle_version = "2.3.0-alpha05"
def markwon_version = "4.4.0"
def work_version = "2.4.0"
def acra = "5.5.0"
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0-alpha10'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
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:3.12.1'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'
implementation 'org.ocpsoft.prettytime:prettytime:4.0.1.Final'
implementation "com.vdurmont:emoji-java:4.0.0"
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.8.0'
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.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.8.0'
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"
implementation "io.noties.markwon:core:$markwon_version"
implementation "io.noties.markwon:ext-latex:$markwon_version"
implementation "io.noties.markwon:ext-strikethrough:$markwon_version"
@ -61,11 +76,21 @@ dependencies {
implementation "io.noties.markwon:simple-ext:$markwon_version"
implementation "io.noties.markwon:syntax-highlight:$markwon_version"
implementation "com.caverock:androidsvg:1.4"
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.14"
implementation "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 "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
implementation "commons-io:commons-io:20030203.000550"
implementation "org.apache.commons:commons-lang3:3.10"
implementation "com.github.chrisbanes:PhotoView:2.3.0"
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
implementation "ch.acra:acra-mail:$acra"
implementation "ch.acra:acra-limiter:$acra"
implementation "ch.acra:acra-notification:$acra"
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor "androidx.room:room-compiler:2.2.5"
implementation "androidx.work:work-runtime:$work_version"
implementation "com.eightbitlab:blurview:1.6.3"
implementation "io.mikael:urlbuilder:2.0.9"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
}

View File

@ -1,18 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.mian.gitnex">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/app_logo"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:resizeableActivity="true"
android:roundIcon="@mipmap/app_logo_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
tools:targetApi="n">
<activity android:name=".activities.MergePullRequestActivity" />
<activity
android:name=".activities.NewFileActivity"
android:theme="@style/AppTheme.NoActionBar"></activity>
android:name=".activities.FileViewActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".activities.CreateFileActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".activities.RepoWatchersActivity"
android:theme="@style/AppTheme.NoActionBar" />
@ -32,16 +43,16 @@
<activity android:name=".activities.ProfileEmailActivity" />
<activity android:name=".activities.AddCollaboratorToRepositoryActivity" />
<activity android:name=".activities.CreateTeamByOrgActivity" />
<activity android:name=".activities.OrgTeamMembersActivity" />
<activity android:name=".activities.OrganizationTeamMembersActivity" />
<activity
android:name=".activities.OrgDetailActivity"
android:name=".activities.OrganizationDetailActivity"
android:label="@string/title_activity_org_detail"
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".activities.SponsorsActivity" />
<activity android:name=".activities.CreditsActivity" />
<activity android:name=".activities.CreateLabelActivity" />
<activity android:name=".activities.CreateIssueActivity" />
<activity android:name=".activities.NewMilestoneActivity" />
<activity android:name=".activities.CreateMilestoneActivity" />
<activity android:name=".activities.ReplyToIssueActivity" />
<activity
android:name=".activities.IssueDetailActivity"
@ -50,7 +61,7 @@
android:name=".activities.RepoDetailActivity"
android:label="@string/title_activity_repo_detail"
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".activities.MainActivity">
<activity android:name=".activities.MainActivity" android:theme="@android:style/Theme.NoTitleBar" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -59,13 +70,26 @@
</activity>
<activity
android:name=".activities.LoginActivity"
android:launchMode="singleTask" />
<activity android:name=".activities.NewRepoActivity" />
<activity android:name=".activities.NewOrganizationActivity" />
android:launchMode="singleTask" android:theme="@android:style/Theme.NoTitleBar"/>
<activity android:name=".activities.CreateRepoActivity" />
<activity android:name=".activities.CreateOrganizationActivity" />
<activity android:name=".activities.OpenRepoInBrowserActivity" />
<activity android:name=".activities.FileDiffActivity" />
<activity android:name=".activities.CommitsActivity" />
<activity android:name=".helpers.ssl.MemorizingActivity" android:theme="@android:style/Theme.Material.Dialog" />
<activity android:name=".activities.SettingsAppearanceActivity" />
<activity android:name=".activities.SettingsFileViewerActivity" />
<activity android:name=".activities.SettingsSecurityActivity" />
<activity android:name=".activities.SettingsTranslationActivity" />
<activity android:name=".activities.SettingsReportsActivity" />
<activity android:name=".activities.AddNewTeamMemberActivity" />
<activity android:name=".activities.SettingsDraftsActivity" />
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
<meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>
<!-- Version >= 3.0. DeX Dual Mode support -->
<meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="true"/>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
</manifest>

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,16 +2,16 @@ package org.mian.gitnex.actions;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.AddCollaboratorToRepositoryActivity;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Permission;
import org.mian.gitnex.util.TinyDB;
import androidx.annotation.NonNull;
import retrofit2.Call;
import retrofit2.Callback;
@ -35,7 +35,7 @@ public class CollaboratorActions {
Call<Collaborators> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, context)
.getApiInterface()
.deleteCollaborator(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, userName);
@ -105,7 +105,7 @@ public class CollaboratorActions {
Call<Permission> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, context)
.getApiInterface()
.addCollaborator(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, userName, permissionString);

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,154 @@
package org.mian.gitnex.actions;
import android.content.Context;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.AddNewTeamMemberActivity;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class TeamActions {
public static void removeTeamMember(final Context context, String userName, int teamId) {
final TinyDB tinyDb = new TinyDB(context);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl, context)
.getApiInterface()
.removeTeamMember(Authorization.returnAuthentication(context, loginUid, instanceToken), teamId, userName);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()) {
if(response.code() == 204) {
tinyDb.putBoolean("teamActionFlag", true);
Toasty.info(context, context.getString(R.string.memberRemovedMessage));
((AddNewTeamMemberActivity)context).finish();
}
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
Toasty.info(context, context.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(context, context.getString(R.string.apiNotFound));
}
else {
Toasty.info(context, context.getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
}
});
}
public static void addTeamMember(final Context context, String userName, int teamId) {
final TinyDB tinyDb = new TinyDB(context);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<JsonElement> call;
call = RetrofitClient
.getInstance(instanceUrl, context)
.getApiInterface()
.addTeamMember(Authorization.returnAuthentication(context, loginUid, instanceToken), teamId, userName);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.isSuccessful()) {
if(response.code() == 204) {
tinyDb.putBoolean("teamActionFlag", true);
Toasty.info(context, context.getString(R.string.memberAddedMessage));
((AddNewTeamMemberActivity)context).finish();
}
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
Toasty.info(context, context.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(context, context.getString(R.string.apiNotFound));
}
else {
Toasty.info(context, context.getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
}
});
}
}

View File

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

View File

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

View File

@ -1,25 +1,23 @@
package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.MultiSelectModel;
import org.mian.gitnex.models.UpdateIssueAssignee;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.models.UpdateIssueAssignees;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
@ -29,24 +27,30 @@ import retrofit2.Callback;
* Author M M Arif
*/
public class AddRemoveAssigneesActivity extends AppCompatActivity {
public class AddRemoveAssigneesActivity extends BaseActivity {
private ArrayList<MultiSelectModel> listOfCollaborators = new ArrayList<>();
private ArrayList<Integer> issueAssigneesIds = new ArrayList<>();
private Boolean assigneesFlag = false;
private MultiSelectDialog multiSelectDialogAssignees;
final Context ctx = this;
private Context appCtx;
@Override
protected void onCreate(Bundle savedInstanceState) {
protected int getLayoutResourceId(){
return R.layout.activity_add_remove_assignees;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_add_remove_assignees);
appCtx = getApplicationContext();
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
@ -62,12 +66,12 @@ public class AddRemoveAssigneesActivity extends AppCompatActivity {
private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@ -90,9 +94,9 @@ public class AddRemoveAssigneesActivity extends AppCompatActivity {
// get current issue assignees
Call<Issues> callSingleIssueAssignees = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
.getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueAssignees.enqueue(new Callback<Issues>() {
@ -135,11 +139,11 @@ public class AddRemoveAssigneesActivity extends AppCompatActivity {
.multiSelectList(listOfCollaborators)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
Log.i("selectedNames", String.valueOf(selectedNames));
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity();
}
@ -163,9 +167,9 @@ public class AddRemoveAssigneesActivity extends AppCompatActivity {
.multiSelectList(listOfCollaborators)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity();
@ -213,7 +217,7 @@ public class AddRemoveAssigneesActivity extends AppCompatActivity {
}
else {
Toasty.info(getApplicationContext(), getString(R.string.genericError));
Toasty.info(ctx, getString(R.string.genericError));
}
}
@ -234,14 +238,14 @@ public class AddRemoveAssigneesActivity extends AppCompatActivity {
private void updateIssueAssignees(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, int issueIndex, List<String> issueAssigneesList) {
UpdateIssueAssignee updateAssigneeJson = new UpdateIssueAssignee(issueAssigneesList);
UpdateIssueAssignees updateAssigneeJson = new UpdateIssueAssignees(issueAssigneesList);
Call<JsonElement> call3;
call3 = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.patchIssueAssignee(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson);
.patchIssueAssignees(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson);
call3.enqueue(new Callback<JsonElement>() {
@ -273,7 +277,7 @@ public class AddRemoveAssigneesActivity extends AppCompatActivity {
}
else {
Toasty.info(getApplicationContext(), getString(R.string.genericError));
Toasty.info(ctx, getString(R.string.genericError));
}

View File

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

View File

@ -1,14 +1,5 @@
package org.mian.gitnex.activities;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
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;
@ -20,37 +11,47 @@ 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.AdminUsersBottomSheetFragment;
import org.mian.gitnex.fragments.BottomSheetAdminUsersFragment;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.viewmodels.AdminGetUsersViewModel;
import java.util.List;
import java.util.Objects;
/**
* Author M M Arif
*/
public class AdminGetUsersActivity extends AppCompatActivity implements AdminUsersBottomSheetFragment.BottomSheetListener {
public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAdminUsersFragment.BottomSheetListener {
private View.OnClickListener onClickListener;
final Context ctx = this;
private Context appCtx;
private AdminGetUsersAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noDataUsers;
private Boolean searchFilter = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
protected int getLayoutResourceId(){
return R.layout.activity_admin_get_users;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_get_users);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -68,50 +69,43 @@ public class AdminGetUsersActivity extends AppCompatActivity implements AdminUse
closeActivity.setOnClickListener(onClickListener);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
AdminGetUsersViewModel.loadUsersList(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken));
}
}, 500);
}
});
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
fetchDataAsync(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken));
swipeRefresh.setRefreshing(false);
AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
}, 500));
fetchDataAsync(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
}
private void fetchDataAsync(Context ctx, String instanceUrl, String instanceToken) {
AdminGetUsersViewModel usersModel = ViewModelProviders.of(this).get(AdminGetUsersViewModel.class);
AdminGetUsersViewModel usersModel = new ViewModelProvider(this).get(AdminGetUsersViewModel.class);
usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
@Override
public void onChanged(@Nullable List<UserInfo> usersListMain) {
adapter = new AdminGetUsersAdapter(getApplicationContext(), usersListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setVisibility(View.VISIBLE);
mRecyclerView.setAdapter(adapter);
noDataUsers.setVisibility(View.GONE);
searchFilter = true;
}
else {
//adapter.notifyDataSetChanged();
//mRecyclerView.setAdapter(adapter);
mRecyclerView.setVisibility(View.GONE);
noDataUsers.setVisibility(View.VISIBLE);
}
usersModel.getUsersList(ctx, 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);
}
});
}
@ -122,37 +116,36 @@ public class AdminGetUsersActivity extends AppCompatActivity implements AdminUse
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(Objects.requireNonNull(getApplicationContext()));
if(searchFilter) {
inflater.inflate(R.menu.search_menu, menu);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
inflater.inflate(R.menu.search_menu, menu);
if(!connToInternet) {
return;
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
if(!connToInternet) {
return;
}
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) { return true; }
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
}
});
}
}, 500);
return true;
@ -168,7 +161,7 @@ public class AdminGetUsersActivity extends AppCompatActivity implements AdminUse
finish();
return true;
case R.id.genericMenu:
AdminUsersBottomSheetFragment bottomSheet = new AdminUsersBottomSheetFragment();
BottomSheetAdminUsersFragment bottomSheet = new BottomSheetAdminUsersFragment();
bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet");
return true;
default:
@ -189,12 +182,7 @@ public class AdminGetUsersActivity extends AppCompatActivity implements AdminUse
}
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
onClickListener = view -> finish();
}
}

View File

@ -0,0 +1,144 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import org.acra.ACRA;
import org.acra.BuildConfig;
import org.acra.annotation.AcraNotification;
import org.acra.config.CoreConfigurationBuilder;
import org.acra.config.LimiterConfigurationBuilder;
import org.acra.config.MailSenderConfigurationBuilder;
import org.acra.data.StringFormat;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.notifications.NotificationsMaster;
/**
* Author M M Arif
*/
@AcraNotification(resIcon = R.drawable.gitnex_transparent,
resTitle = R.string.crashTitle,
resChannelName = R.string.setCrashReports,
resText = R.string.crashMessage)
public abstract class BaseActivity extends AppCompatActivity {
private Context appCtx;
@Override
public void onCreate(Bundle savedInstanceState) {
appCtx = getApplicationContext();
final TinyDB tinyDb = new TinyDB(appCtx);
switch(tinyDb.getInt("themeId")) {
case 1:
setTheme(R.style.AppThemeLight);
break;
case 2:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
setTheme(R.style.AppTheme);
}
else {
setTheme(R.style.AppThemeLight);
}
break;
default:
setTheme(R.style.AppTheme);
break;
}
String appLocale = tinyDb.getString("locale");
AppUtil.setAppLocale(getResources(), appLocale);
super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId());
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/roboto.ttf");
break;
case 2:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/sourcecodeproregular.ttf");
break;
default:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/manroperegular.ttf");
break;
}
if(tinyDb.getInt("pollingDelayMinutes") == 0) {
tinyDb.putInt("pollingDelayMinutes", 15);
}
NotificationsMaster.hireWorker(appCtx);
// enabling counter badges by default
if(tinyDb.getString("enableCounterBadgesInit").isEmpty()) {
tinyDb.putBoolean("enableCounterBadges", true);
tinyDb.putString("enableCounterBadgesInit", "yes");
}
// enable crash reports by default
if(tinyDb.getString("crashReportingEnabledInit").isEmpty()) {
tinyDb.putBoolean("crashReportingEnabled", true);
tinyDb.putString("crashReportingEnabledInit", "yes");
}
// default cache setter
if(tinyDb.getString("cacheSizeStr").isEmpty()) {
tinyDb.putString("cacheSizeStr", getResources().getString(R.string.cacheSizeDataSelectionSelectedText));
}
if(tinyDb.getString("cacheSizeImagesStr").isEmpty()) {
tinyDb.putString("cacheSizeImagesStr", getResources().getString(R.string.cacheSizeImagesSelectionSelectedText));
}
// enable comment drafts by default
if(tinyDb.getString("draftsCommentsDeletionEnabledInit").isEmpty()) {
tinyDb.putBoolean("draftsCommentsDeletionEnabled", true);
tinyDb.putString("draftsCommentsDeletionEnabledInit", "yes");
}
if(!tinyDb.getString("instanceUrlWithProtocol").endsWith("/")) {
tinyDb.putString("instanceUrlWithProtocol", tinyDb.getString("instanceUrlWithProtocol") + "/");
}
if (tinyDb.getBoolean("crashReportingEnabled")) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);
ACRABuilder.setBuildConfigClass(BuildConfig.class).setReportFormat(StringFormat.KEY_VALUE_LIST);
ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class).setReportAsFile(true).setMailTo(getResources().getString(R.string.appEmail)).setSubject(getResources().getString(R.string.crashReportEmailSubject, AppUtil.getAppBuildNo(getApplicationContext()))).setEnabled(true);
ACRABuilder.getPluginConfigurationBuilder(LimiterConfigurationBuilder.class).setEnabled(true);
ACRA.init(getApplication(), ACRABuilder);
}
}
protected abstract int getLayoutResourceId();
}

View File

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

View File

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

View File

@ -1,10 +1,5 @@
package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.app.DatePickerDialog;
import android.content.Context;
import android.graphics.PorterDuff;
@ -12,6 +7,7 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
@ -19,6 +15,7 @@ import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
@ -26,26 +23,31 @@ import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.Labels;
import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.models.MultiSelectModel;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class CreateIssueActivity extends AppCompatActivity implements View.OnClickListener {
public class CreateIssueActivity extends BaseActivity implements View.OnClickListener {
private View.OnClickListener onClickListener;
MultiSelectDialog multiSelectDialog;
@ -61,6 +63,8 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
private boolean assigneesFlag;
private boolean labelsFlag;
final Context ctx = this;
private Context appCtx;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
List<Milestones> milestonesList = new ArrayList<>();
ArrayList<MultiSelectModel> listOfAssignees = new ArrayList<>();
@ -68,21 +72,35 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
private ArrayAdapter<Mention> defaultMentionAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
protected int getLayoutResourceId(){
return R.layout.activity_create_issue;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_issue);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String loginFullName = tinyDb.getString("userFullname");
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 gitea is 1.12 or higher use the new limit
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
ImageView closeActivity = findViewById(R.id.close);
assigneesList = findViewById(R.id.newIssueAssigneesList);
newIssueLabels = findViewById(R.id.newIssueLabels);
@ -92,6 +110,10 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
newIssueDescription = findViewById(R.id.newIssueDescription);
labelsIdHolder = findViewById(R.id.labelsIdHolder);
newIssueTitle.requestFocus();
assert imm != null;
imm.showSoftInput(newIssueTitle, InputMethodManager.SHOW_IMPLICIT);
defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList();
@ -106,10 +128,10 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner);
newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit);
getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName);
disableProcessButton();
@ -131,8 +153,8 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
private void processNewIssue() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(getApplicationContext());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
@ -153,21 +175,21 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (newIssueTitleForm.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty));
Toasty.info(ctx, getString(R.string.issueTitleEmpty));
return;
}
/*if (newIssueDescriptionForm.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty));
Toasty.info(ctx, getString(R.string.issueDescriptionEmpty));
return;
}*/
@ -206,7 +228,7 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
@ -217,9 +239,9 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@ -248,7 +270,7 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.getMessage());
Log.i("onFailure", t.toString());
}
});
@ -261,9 +283,9 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
Call<JsonElement> call3;
call3 = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.createNewIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createNewIssueJson);
.createNewIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, createNewIssueJson);
call3.enqueue(new Callback<JsonElement>() {
@ -274,10 +296,10 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
if(response2.code() == 201) {
//Log.i("isSuccessful1", String.valueOf(response2.body()));
TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("resumeIssues", true);
Toasty.info(getApplicationContext(), getString(R.string.issueCreated));
Toasty.info(ctx, getString(R.string.issueCreated));
enableProcessButton();
finish();
@ -295,7 +317,7 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
}
else {
Toasty.info(getApplicationContext(), getString(R.string.issueCreatedError));
Toasty.info(ctx, getString(R.string.issueCreatedError));
enableProcessButton();
//Log.i("isSuccessful2", String.valueOf(response2.body()));
@ -321,13 +343,13 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
};
}
private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) {
String msState = "open";
Call<List<Milestones>> call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState);
.getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState);
call.enqueue(new Callback<List<Milestones>>() {
@ -339,13 +361,13 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
List<Milestones> milestonesList_ = response.body();
milestonesList.add(new Milestones(0,"No milestone"));
milestonesList.add(new Milestones(0,getString(R.string.issueCreatedNoMilestone)));
assert milestonesList_ != null;
if(milestonesList_.size() > 0) {
for (int i = 0; i < milestonesList_.size(); i++) {
//String mStone = getString(R.string.spinnerMilestoneText, milestonesList_.get(i).getTitle(), milestonesList_.get(i).getState());
if(milestonesList_.get(i).getState().equals(getString(R.string.issueStatusOpen))) {
//Don't translate "open" is a enum
if(milestonesList_.get(i).getState().equals("open")) {
Milestones data = new Milestones(
milestonesList_.get(i).getId(),
milestonesList_.get(i).getTitle()
@ -356,7 +378,7 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
}
}
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(getApplicationContext(),
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreateIssueActivity.this,
R.layout.spinner_item, milestonesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
@ -376,12 +398,14 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
}
private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, String loginFullName) {
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
listOfAssignees.add(new MultiSelectModel(-1, loginFullName));
call.enqueue(new Callback<List<Collaborators>>() {
@ -420,7 +444,7 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
.multiSelectList(listOfAssignees)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
assigneesList.setText(dataString);
@ -449,9 +473,9 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
Call<List<Labels>> call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
.getlabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Labels>>() {
@ -483,7 +507,7 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
.multiSelectList(listOfLabels)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
newIssueLabels.setText(dataString.trim());
labelsIdHolder.setText(selectedIds.toString());
@ -517,7 +541,7 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog");
}
else {
Toasty.info(getApplicationContext(), getResources().getString(R.string.noAssigneesFound));
Toasty.info(ctx, getResources().getString(R.string.noAssigneesFound));
}
}
else if (v == newIssueLabels) {
@ -525,7 +549,7 @@ public class CreateIssueActivity extends AppCompatActivity implements View.OnCli
multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels");
}
else {
Toasty.info(getApplicationContext(), getResources().getString(R.string.noLabelsFound));
Toasty.info(ctx, getResources().getString(R.string.noLabelsFound));
}
}
else if (v == newIssueDueDate) {

View File

@ -1,52 +1,62 @@
package org.mian.gitnex.activities;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import retrofit2.Call;
import retrofit2.Callback;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.pes.androidmaterialcolorpickerdialog.ColorPicker;
import com.pes.androidmaterialcolorpickerdialog.ColorPickerCallback;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.CreateLabel;
import org.mian.gitnex.models.Labels;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.LabelsViewModel;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class CreateLabelActivity extends AppCompatActivity {
public class CreateLabelActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private TextView colorPicker;
private EditText labelName;
private Button createLabelButton;
final Context ctx = this;
private Context appCtx;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_label);
protected int getLayoutResourceId(){
return R.layout.activity_create_label;
}
final TinyDB tinyDb = new TinyDB(getApplicationContext());
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
final TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
@ -55,21 +65,25 @@ public class CreateLabelActivity extends AppCompatActivity {
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(getIntent().getStringExtra("labelAction") != null && getIntent().getStringExtra("labelAction").equals("delete")) {
if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("delete")) {
deleteLabel(instanceUrl, instanceToken, repoOwner, repoName, Integer.valueOf(getIntent().getStringExtra("labelId")), loginUid);
deleteLabel(instanceUrl, instanceToken, repoOwner, repoName, Integer.parseInt(Objects.requireNonNull(getIntent().getStringExtra("labelId"))), loginUid);
finish();
return;
}
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
ImageView closeActivity = findViewById(R.id.close);
colorPicker = findViewById(R.id.colorPicker);
labelName = findViewById(R.id.labelName);
createLabelButton = findViewById(R.id.createLabelButton);
labelName.requestFocus();
assert imm != null;
imm.showSoftInput(labelName, InputMethodManager.SHOW_IMPLICIT);
final ColorPicker cp = new ColorPicker(CreateLabelActivity.this, 235, 113, 33);
initCloseListener();
@ -92,7 +106,7 @@ public class CreateLabelActivity extends AppCompatActivity {
}
});
if(getIntent().getStringExtra("labelAction") != null && getIntent().getStringExtra("labelAction").equals("edit")) {
if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("edit")) {
labelName.setText(getIntent().getStringExtra("labelTitle"));
int labelColor_ = Color.parseColor("#" + getIntent().getStringExtra("labelColor"));
@ -139,8 +153,8 @@ public class CreateLabelActivity extends AppCompatActivity {
private void processUpdateLabel() {
final TinyDB tinyDb = new TinyDB(getApplicationContext());
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
@ -162,21 +176,21 @@ public class CreateLabelActivity extends AppCompatActivity {
if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if(updateLabelName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError));
Toasty.info(ctx, getString(R.string.labelEmptyError));
return;
}
if(!appUtil.checkStrings(updateLabelName)) {
Toasty.info(getApplicationContext(), getString(R.string.labelNameError));
Toasty.info(ctx, getString(R.string.labelNameError));
return;
}
@ -188,9 +202,9 @@ public class CreateLabelActivity extends AppCompatActivity {
private void processCreateLabel() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
@ -202,7 +216,7 @@ public class CreateLabelActivity extends AppCompatActivity {
String newLabelName = labelName.getText().toString();
String newLabelColor;
if(tinyDb.getString("labelColor").isEmpty()) {
newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(getApplicationContext(), R.color.releasePre)));
newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(ctx, R.color.releasePre)));
}
else {
newLabelColor = tinyDb.getString("labelColor");
@ -210,21 +224,21 @@ public class CreateLabelActivity extends AppCompatActivity {
if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if(newLabelName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError));
Toasty.info(ctx, getString(R.string.labelEmptyError));
return;
}
if(!appUtil.checkStrings(newLabelName)) {
Toasty.info(getApplicationContext(), getString(R.string.labelNameError));
Toasty.info(ctx, getString(R.string.labelNameError));
return;
}
@ -237,14 +251,14 @@ public class CreateLabelActivity extends AppCompatActivity {
private void createNewLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String newLabelName, String newLabelColor, String loginUid) {
CreateLabel createLabelFunc = new CreateLabel(newLabelName, newLabelColor);
final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
Call<CreateLabel> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.createLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createLabelFunc);
.createLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, createLabelFunc);
call.enqueue(new Callback<CreateLabel>() {
@ -253,7 +267,7 @@ public class CreateLabelActivity extends AppCompatActivity {
if(response.code() == 201) {
Toasty.info(getApplicationContext(), getString(R.string.labelCreated));
Toasty.info(ctx, getString(R.string.labelCreated));
tinyDb.putString("labelColor", "");
tinyDb.putBoolean("labelsRefresh", true);
finish();
@ -272,7 +286,7 @@ public class CreateLabelActivity extends AppCompatActivity {
enableProcessButton();
tinyDb.putString("labelColor", "");
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
Toasty.info(ctx, getString(R.string.labelGeneralError));
}
@ -291,14 +305,14 @@ public class CreateLabelActivity extends AppCompatActivity {
private void patchLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId, String loginUid) {
CreateLabel createLabelFunc = new CreateLabel(updateLabelName, updateLabelColor);
final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
Call<CreateLabel> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.patchLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc);
.patchLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc);
call.enqueue(new Callback<CreateLabel>() {
@ -308,7 +322,7 @@ public class CreateLabelActivity extends AppCompatActivity {
if(response.isSuccessful()) {
if(response.code() == 200) {
Toasty.info(getApplicationContext(), getString(R.string.labelUpdated));
Toasty.info(ctx, getString(R.string.labelUpdated));
tinyDb.putString("labelColor", "");
tinyDb.putBoolean("labelsRefresh", true);
tinyDb.putString("labelColorDefault", "");
@ -334,7 +348,7 @@ public class CreateLabelActivity extends AppCompatActivity {
enableProcessButton();
tinyDb.putString("labelColor", "");
tinyDb.putString("labelColorDefault", "");
Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
Toasty.info(ctx, getString(R.string.labelGeneralError));
}
@ -369,9 +383,9 @@ public class CreateLabelActivity extends AppCompatActivity {
Call<Labels> call;
call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.deleteLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId);
.deleteLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, labelId);
call.enqueue(new Callback<Labels>() {
@ -381,8 +395,8 @@ public class CreateLabelActivity extends AppCompatActivity {
if(response.isSuccessful()) {
if(response.code() == 204) {
Toasty.info(getApplicationContext(), getString(R.string.labelDeleteText));
LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName);
Toasty.info(ctx, getString(R.string.labelDeleteText));
LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, ctx);
getIntent().removeExtra("labelAction");
getIntent().removeExtra("labelId");
@ -398,7 +412,7 @@ public class CreateLabelActivity extends AppCompatActivity {
}
else {
Toasty.info(getApplicationContext(), getString(R.string.labelDeleteErrorText));
Toasty.info(ctx, getString(R.string.labelDeleteErrorText));
}
@ -432,4 +446,4 @@ public class CreateLabelActivity extends AppCompatActivity {
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,38 +1,39 @@
package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import retrofit2.Call;
import retrofit2.Callback;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Teams;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.util.Log;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class CreateTeamByOrgActivity extends AppCompatActivity implements View.OnClickListener {
public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClickListener {
final Context ctx = CreateTeamByOrgActivity.this;
private Context appCtx;
private View.OnClickListener onClickListener;
private TextView teamName;
private TextView teamDesc;
@ -44,6 +45,11 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
private String[] permissionList = {"Read", "Write", "Admin"};
public int permissionSelectedChoice = -1;
@Override
protected int getLayoutResourceId(){
return R.layout.activity_create_team_by_org;
}
private String[] accessControlsList = new String[] {
"Code",
"Issues",
@ -67,11 +73,14 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_team_by_org);
public void onCreate(Bundle savedInstanceState) {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
ImageView closeActivity = findViewById(R.id.close);
teamName = findViewById(R.id.teamName);
@ -82,6 +91,10 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
teamAccessControlsArray = findViewById(R.id.teamAccessControlsArray);
createTeamButton = findViewById(R.id.createTeamButton);
teamName.requestFocus();
assert imm != null;
imm.showSoftInput(teamName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
@ -89,7 +102,7 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
@Override
public void onClick(View view) {
AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog);
AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx);
pBuilder.setTitle(R.string.newTeamPermission);
if(permissionSelectedChoice != -1) {
@ -141,7 +154,7 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
teamAccessControlsArray.setText("");
pushAccessList = Arrays.asList(accessControlsList);
AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog);
AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(ctx);
aDialogBuilder.setMultiChoiceItems(accessControlsList, selectedAccessControlsTrueFalse, new DialogInterface.OnMultiChoiceClickListener() {
@ -237,13 +250,13 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
private void processCreateTeam() {
AppUtil appUtil = new AppUtil();
final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String orgName = tinyDb.getString("orgName");;
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String newTeamName = teamName.getText().toString();
String newTeamDesc = teamDesc.getText().toString();
String newTeamPermission = teamPermission.getText().toString().toLowerCase();
@ -251,21 +264,21 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (newTeamName.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.teamNameEmpty));
Toasty.info(ctx, getString(R.string.teamNameEmpty));
return;
}
if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
Toasty.info(getApplicationContext(), getString(R.string.teamNameError));
Toasty.info(ctx, getString(R.string.teamNameError));
return;
}
@ -273,12 +286,12 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
if(!newTeamDesc.equals("")) {
if(!appUtil.checkStrings(newTeamDesc)) {
Toasty.info(getApplicationContext(), getString(R.string.teamDescError));
Toasty.info(ctx, getString(R.string.teamDescError));
return;
}
if(newTeamDesc.length() > 100) {
Toasty.info(getApplicationContext(), getString(R.string.teamDescLimit));
Toasty.info(ctx, getString(R.string.teamDescLimit));
return;
}
@ -286,7 +299,7 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
if (newTeamPermission.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.teamPermissionEmpty));
Toasty.info(ctx, getString(R.string.teamPermissionEmpty));
return;
}
@ -308,9 +321,9 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
Call<Teams> call3;
call3 = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.createTeamsByOrg(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), orgName, createNewTeamJson);
.createTeamsByOrg(Authorization.returnAuthentication(ctx, loginUid, instanceToken), orgName, createNewTeamJson);
call3.enqueue(new Callback<Teams>() {
@ -320,10 +333,10 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
if(response2.isSuccessful()) {
if(response2.code() == 201) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("resumeTeams", true);
Toasty.info(getApplicationContext(), getString(R.string.teamCreated));
Toasty.info(ctx, getString(R.string.teamCreated));
finish();
}
@ -331,7 +344,7 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
}
else if(response2.code() == 404) {
Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
Toasty.info(ctx, getString(R.string.apiNotFound));
}
else if(response2.code() == 401) {
@ -344,7 +357,7 @@ public class CreateTeamByOrgActivity extends AppCompatActivity implements View.O
}
else {
Toasty.info(getApplicationContext(), getString(R.string.teamCreatedError));
Toasty.info(ctx, getString(R.string.teamCreatedError));
}

View File

@ -1,35 +1,60 @@
package org.mian.gitnex.activities;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.CreditsAdapter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Author M M Arif
*/
public class CreditsActivity extends AppCompatActivity {
public class CreditsActivity extends BaseActivity {
private View.OnClickListener onClickListener;
final Context ctx = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
protected int getLayoutResourceId(){
return R.layout.activity_credits;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_credits);
TextView creditKasun = findViewById(R.id.creditKasun);
ImageView closeActivity = findViewById(R.id.close);
creditKasun.setMovementMethod(LinkMovementMethod.getInstance());
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
Resources res = getResources();
CharSequence[] creditsInfo = res.getTextArray(R.array.creditsInfo);
List<CharSequence> creditsList = new ArrayList<>(Arrays.asList(creditsInfo));
RecyclerView mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
CreditsAdapter adapter = new CreditsAdapter(creditsList);
mRecyclerView.setAdapter(adapter);
}
private void initCloseListener() {

View File

@ -1,10 +1,5 @@
package org.mian.gitnex.activities;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.annotation.SuppressLint;
import android.app.DatePickerDialog;
import android.content.Context;
@ -13,6 +8,7 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
@ -20,6 +16,7 @@ import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
@ -27,28 +24,35 @@ import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class EditIssueActivity extends AppCompatActivity implements View.OnClickListener {
public class EditIssueActivity extends BaseActivity implements View.OnClickListener {
final Context ctx = this;
private Context appCtx;
private View.OnClickListener onClickListener;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private EditText editIssueTitle;
private SocialAutoCompleteTextView editIssueDescription;
@ -62,12 +66,19 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
private ArrayAdapter<Mention> defaultMentionAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
protected int getLayoutResourceId(){
return R.layout.activity_edit_issue;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_issue);
appCtx = getApplicationContext();
final TinyDB tinyDb = new TinyDB(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
@ -85,6 +96,15 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
editIssueDescription = findViewById(R.id.editIssueDescription);
editIssueDueDate = findViewById(R.id.editIssueDueDate);
// if gitea is 1.12 or higher use the new limit
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
editIssueTitle.requestFocus();
assert imm != null;
imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT);
defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList();
@ -100,18 +120,24 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
editIssueButton.setOnClickListener(this);
if(!tinyDb.getString("issueNumber").isEmpty()) {
toolbar_title.setText(getString(R.string.editIssueNavHeader, String.valueOf(issueIndex)));
if(tinyDb.getString("issueType").equalsIgnoreCase("Pull")) {
toolbar_title.setText(getString(R.string.editPrNavHeader, String.valueOf(issueIndex)));
}
else {
toolbar_title.setText(getString(R.string.editIssueNavHeader, String.valueOf(issueIndex)));
}
}
disableProcessButton();
getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex);
getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit);
}
public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
@ -122,9 +148,9 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@ -153,7 +179,7 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.getMessage());
Log.i("onFailure", t.toString());
}
});
@ -170,8 +196,8 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
private void processEditIssue() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(getApplicationContext());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
@ -191,21 +217,21 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (editIssueTitleForm.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty));
Toasty.info(ctx, getString(R.string.issueTitleEmpty));
return;
}
/*if (editIssueDescriptionForm.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty));
Toasty.info(ctx, getString(R.string.issueDescriptionEmpty));
return;
}*/
@ -224,14 +250,14 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int editIssueMilestoneId) {
final TinyDB tinyDb = new TinyDB(getApplicationContext());
final TinyDB tinyDb = new TinyDB(appCtx);
CreateIssue issueData = new CreateIssue(title, description, dueDate, editIssueMilestoneId);
Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.patchIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData);
.patchIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData);
call.enqueue(new Callback<JsonElement>() {
@ -240,7 +266,13 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
if(response.code() == 201) {
Toasty.info(getApplicationContext(), getString(R.string.editIssueSuccessMessage));
if(tinyDb.getString("issueType").equalsIgnoreCase("Pull")) {
Toasty.info(ctx, getString(R.string.editPrSuccessMessage));
}
else {
Toasty.info(ctx, getString(R.string.editIssueSuccessMessage));
}
tinyDb.putBoolean("issueEdited", true);
tinyDb.putBoolean("resumeIssues", true);
finish();
@ -258,7 +290,7 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
else {
enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.genericError));
Toasty.info(ctx, getString(R.string.genericError));
}
@ -304,12 +336,12 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
}
private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex) {
private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex, int resultLimit) {
Call<Issues> call = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
.getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
call.enqueue(new Callback<Issues>() {
@ -331,9 +363,9 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
if(response.body().getId() > 0) {
Call<List<Milestones>> call_ = RetrofitClient
.getInstance(instanceUrl)
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, msState);
.getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState);
final int finalMsId = msId;
@ -366,7 +398,7 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
}
}
ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(getApplicationContext(),
ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(EditIssueActivity.this,
R.layout.spinner_item, milestonesList);
adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item);
@ -410,7 +442,7 @@ public class EditIssueActivity extends AppCompatActivity implements View.OnClick
}
else {
Toasty.info(getApplicationContext(), getString(R.string.genericError));
Toasty.info(ctx, getString(R.string.genericError));
}

View File

@ -0,0 +1,181 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import 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.AppUtil;
import org.mian.gitnex.helpers.ParseDiff;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.FileDiffView;
import java.io.IOException;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class FileDiffActivity extends BaseActivity {
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
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
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");
ImageView closeActivity = findViewById(R.id.close);
toolbarTitle = findViewById(R.id.toolbar_title);
mListView = findViewById(R.id.listView);
mProgressBar = findViewById(R.id.progress_bar);
mListView.setDivider(null);
toolbarTitle.setText(R.string.processingText);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
mProgressBar.setVisibility(View.VISIBLE);
String pullIndex = tinyDb.getString("issueNumber");
boolean apiCall = true;
String instanceUrl = tinyDb.getString("instanceUrl");
// fallback for old gitea instances
if(new Version(tinyDb.getString("giteaVersion")).less("1.13.0")) {
apiCall = false;
instanceUrl = tinyDb.getString("instanceUrlWithProtocol");
}
getPullDiffContent(instanceUrl, repoOwner, repoName, pullIndex, instanceToken, apiCall);
}
private void getPullDiffContent(String instanceUrl, String owner, String repo, String pullIndex, String token, boolean apiCall) {
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);
}
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
if(response.code() == 200) {
try {
assert response.body() != null;
AppUtil appUtil = new AppUtil();
List<FileDiffView> fileContentsArray = ParseDiff.getFileDiffViewArray(response.body().string());
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)));
}
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, fileContentsArray);
mListView.setAdapter(adapter);
mProgressBar.setVisibility(View.GONE);
}
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();
}
};
}
}

View File

@ -0,0 +1,382 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Base64;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.util.FitPolicy;
import com.github.chrisbanes.photoview.PhotoView;
import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetFileViewerFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.highlightjs.HighlightJsView;
import org.mian.gitnex.helpers.highlightjs.models.Theme;
import org.mian.gitnex.models.Files;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class FileViewActivity extends BaseActivity implements BottomSheetFileViewerFragment.BottomSheetListener {
private View.OnClickListener onClickListener;
private TextView singleFileContents;
private LinearLayout singleFileContentsFrame;
private HighlightJsView singleCodeContents;
private PhotoView imageView;
final Context ctx = this;
private Context appCtx;
private ProgressBar mProgressBar;
private byte[] imageData;
private PDFView pdfView;
private LinearLayout pdfViewFrame;
private byte[] decodedPdf;
private Boolean pdfNightMode;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_file_view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName");
String repoBranch = tinyDb.getString("repoBranch");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
ImageView closeActivity = findViewById(R.id.close);
singleFileContents = findViewById(R.id.singleFileContents);
singleCodeContents = findViewById(R.id.singleCodeContents);
imageView = findViewById(R.id.imageView);
mProgressBar = findViewById(R.id.progress_bar);
pdfView = findViewById(R.id.pdfView);
pdfViewFrame = findViewById(R.id.pdfViewFrame);
singleFileContentsFrame = findViewById(R.id.singleFileContentsFrame);
String singleFileName = getIntent().getStringExtra("singleFileName");
TextView toolbar_title = findViewById(R.id.toolbar_title);
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
tinyDb.putString("downloadFileContents", "");
try {
singleFileName = URLDecoder.decode(singleFileName, "UTF-8");
singleFileName = singleFileName.replaceAll("//", "/");
singleFileName = singleFileName.startsWith("/") ? singleFileName.substring(1) : singleFileName;
}
catch(UnsupportedEncodingException e) {
assert singleFileName != null;
Log.i("singleFileName", singleFileName);
}
toolbar_title.setText(singleFileName);
getSingleFileContents(instanceUrl, instanceToken, repoOwner, repoName, singleFileName, repoBranch);
}
private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename, String ref) {
final TinyDB tinyDb = new TinyDB(appCtx);
Call<Files> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getSingleFileContents(token, owner, repo, filename, ref);
call.enqueue(new Callback<Files>() {
@Override
public void onResponse(@NonNull Call<Files> call, @NonNull retrofit2.Response<Files> response) {
if(response.code() == 200) {
AppUtil appUtil = new AppUtil();
assert response.body() != null;
if(!response.body().getContent().equals("")) {
String fileExtension = FileUtils.getExtension(filename);
mProgressBar.setVisibility(View.GONE);
// download file meta
tinyDb.putString("downloadFileName", filename);
tinyDb.putString("downloadFileContents", response.body().getContent());
if(appUtil.imageExtension(fileExtension)) { // file is image
singleFileContentsFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT);
Drawable imageDrawable = new BitmapDrawable(getResources(), BitmapFactory.decodeByteArray(imageData, 0, imageData.length));
imageView.setImageDrawable(imageDrawable);
}
else if(appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode
imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.VISIBLE);
switch(tinyDb.getInt("fileviewerSourceCodeThemeId")) {
case 1:
singleCodeContents.setTheme(Theme.ARDUINO_LIGHT);
break;
case 2:
singleCodeContents.setTheme(Theme.GITHUB);
break;
case 3:
singleCodeContents.setTheme(Theme.FAR);
break;
case 4:
singleCodeContents.setTheme(Theme.IR_BLACK);
break;
case 5:
singleCodeContents.setTheme(Theme.ANDROID_STUDIO);
break;
default:
singleCodeContents.setTheme(Theme.MONOKAI_SUBLIME);
}
singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent()));
}
else if(appUtil.pdfExtension(fileExtension)) { // file is pdf
imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.VISIBLE);
pdfNightMode = tinyDb.getBoolean("enablePdfMode");
decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT);
pdfView.fromBytes(decodedPdf).enableSwipe(true).swipeHorizontal(false).enableDoubletap(true).defaultPage(0).enableAnnotationRendering(false).password(null).scrollHandle(null).enableAntialiasing(true).spacing(0).autoSpacing(true).pageFitPolicy(FitPolicy.WIDTH).fitEachPage(true).pageSnap(false).pageFling(true).nightMode(pdfNightMode).load();
}
else if(appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded
imageView.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE);
singleFileContents.setText(getResources().getString(R.string.excludeFilesInFileviewer));
singleFileContents.setGravity(Gravity.CENTER);
singleFileContents.setTypeface(null, Typeface.BOLD);
}
else { // file type not known - plain text view
imageView.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE);
singleFileContents.setText(appUtil.decodeBase64(response.body().getContent()));
}
}
else {
singleFileContents.setText("");
mProgressBar.setVisibility(View.GONE);
}
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.info(ctx, getString(R.string.labelGeneralError));
}
}
@Override
public void onFailure(@NonNull Call<Files> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case android.R.id.home:
finish();
return true;
case R.id.genericMenu:
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onButtonClicked(String text) {
if("downloadFile".equals(text)) {
requestFileDownload();
}
}
private void requestFileDownload() {
final TinyDB tinyDb = new TinyDB(appCtx);
if(!tinyDb.getString("downloadFileContents").isEmpty()) {
int CREATE_REQUEST_CODE = 40;
File outputFileName = new File(tinyDb.getString("downloadFileName"));
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, outputFileName.getName());
startActivityForResult(intent, CREATE_REQUEST_CODE);
}
else {
Toasty.error(ctx, getString(R.string.waitLoadingDownloadFile));
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
final TinyDB tinyDb = new TinyDB(appCtx);
if (requestCode == 40 && resultCode == RESULT_OK) {
try {
assert data != null;
Uri uri = data.getData();
assert uri != null;
OutputStream outputStream = getContentResolver().openOutputStream(uri);
byte[] dataAsBytes = Base64.decode(tinyDb.getString("downloadFileContents"), 0);
assert outputStream != null;
outputStream.write(dataAsBytes);
outputStream.close();
Toasty.info(ctx, getString(R.string.downloadFileSaved));
}
catch (IOException e) {
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
}
}
}
private void initCloseListener() {
onClickListener = view -> {
getIntent().removeExtra("singleFileName");
finish();
};
}
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,10 +1,17 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.PathsHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.net.URI;
import java.net.URISyntaxException;
import io.mikael.urlbuilder.UrlBuilder;
/**
* Author M M Arif
@ -12,23 +19,33 @@ import org.mian.gitnex.util.TinyDB;
public class OpenRepoInBrowserActivity extends AppCompatActivity {
private Context appCtx;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
TinyDB tinyDb = new TinyDB(getApplicationContext());
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

@ -1,101 +0,0 @@
package org.mian.gitnex.activities;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.view.View;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.TeamMembersByOrgAdapter;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.TeamMembersByOrgViewModel;
import java.util.List;
/**
* Author M M Arif
*/
public class OrgTeamMembersActivity extends AppCompatActivity {
private TextView noDataMembers;
private View.OnClickListener onClickListener;
private TeamMembersByOrgAdapter adapter;
private GridView mGridView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_org_team_members);
TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
ImageView closeActivity = findViewById(R.id.close);
TextView toolbarTitle = findViewById(R.id.toolbar_title);
noDataMembers = findViewById(R.id.noDataMembers);
mGridView = findViewById(R.id.gridView);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
if(getIntent().getStringExtra("teamTitle") != null && !getIntent().getStringExtra("teamTitle").equals("")) {
toolbarTitle.setText(getIntent().getStringExtra("teamTitle"));
}
else {
toolbarTitle.setText(R.string.orgTeamMembers);
}
String teamId;
if(getIntent().getStringExtra("teamId") != null && !getIntent().getStringExtra("teamId").equals("")){
teamId = getIntent().getStringExtra("teamId");
}
else {
teamId = "0";
}
getIntent().getStringExtra("teamId");
//Log.i("teamId", getIntent().getStringExtra("teamId"));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), Integer.valueOf(teamId));
}
private void fetchDataAsync(String instanceUrl, String instanceToken, int teamId) {
TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class);
teamMembersModel.getMembersByOrgList(instanceUrl, instanceToken, teamId).observe(this, new Observer<List<UserInfo>>() {
@Override
public void onChanged(@Nullable List<UserInfo> teamMembersListMain) {
adapter = new TeamMembersByOrgAdapter(getApplicationContext(), teamMembersListMain);
if(adapter.getCount() > 0) {
mGridView.setAdapter(adapter);
noDataMembers.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mGridView.setAdapter(adapter);
noDataMembers.setVisibility(View.VISIBLE);
}
}
});
}
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
}
}

View File

@ -1,53 +1,102 @@
package org.mian.gitnex.activities;
import com.google.android.material.tabs.TabLayout;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.google.android.material.tabs.TabLayout;
import org.mian.gitnex.R;
import org.mian.gitnex.fragments.BottomSheetOrganizationFragment;
import org.mian.gitnex.fragments.MembersByOrgFragment;
import org.mian.gitnex.fragments.OrgBottomSheetFragment;
import org.mian.gitnex.fragments.OrganizationInfoFragment;
import org.mian.gitnex.fragments.RepositoriesByOrgFragment;
import org.mian.gitnex.fragments.TeamsByOrgFragment;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.TinyDB;
import java.util.Objects;
/**
* Author M M Arif
*/
public class OrgDetailActivity extends AppCompatActivity implements OrgBottomSheetFragment.BottomSheetListener {
public class OrganizationDetailActivity extends BaseActivity implements BottomSheetOrganizationFragment.BottomSheetListener {
final Context ctx = this;
private Context appCtx;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_org_detail);
protected int getLayoutResourceId(){
return R.layout.activity_org_detail;
}
TinyDB tinyDb = new TinyDB(getApplicationContext());
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
TinyDB tinyDb = new TinyDB(appCtx);
String orgName = tinyDb.getString("orgName");
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(orgName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
OrgDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrgDetailActivity.SectionsPagerAdapter(getSupportFragmentManager());
OrganizationDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrganizationDetailActivity.SectionsPagerAdapter(getSupportFragmentManager());
ViewPager mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf");
break;
}
toolbarTitle.setTypeface(myTypeface);
toolbarTitle.setText(orgName);
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildCount = vgTab.getChildCount();
for (int i = 0; i < tabChildCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(myTypeface);
}
}
}
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
@ -71,7 +120,7 @@ public class OrgDetailActivity extends AppCompatActivity implements OrgBottomShe
finish();
return true;
case R.id.repoMenu:
OrgBottomSheetFragment bottomSheet = new OrgBottomSheetFragment();
BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment();
bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet");
return true;
default:
@ -83,9 +132,15 @@ public class OrgDetailActivity extends AppCompatActivity implements OrgBottomShe
@Override
public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(appCtx);
switch (text) {
case "repository":
tinyDb.putBoolean("organizationAction", true);
startActivity(new Intent(OrganizationDetailActivity.this, CreateRepoActivity.class));
break;
case "team":
startActivity(new Intent(OrgDetailActivity.this, CreateTeamByOrgActivity.class));
startActivity(new Intent(OrganizationDetailActivity.this, CreateTeamByOrgActivity.class));
break;
}
//Log.i("clicked", text);
@ -95,16 +150,16 @@ public class OrgDetailActivity extends AppCompatActivity implements OrgBottomShe
public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
TinyDB tinyDb = new TinyDB(appCtx);
String orgName;
if(getIntent().getStringExtra("orgName") != null || !getIntent().getStringExtra("orgName").equals("")) {
if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) {
orgName = getIntent().getStringExtra("orgName");
}
else {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,33 +1,61 @@
package org.mian.gitnex.activities;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.SponsorsAdapter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Author M M Arif
*/
public class SponsorsActivity extends AppCompatActivity {
public class SponsorsActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private Context appCtx;
@Override
protected void onCreate(Bundle savedInstanceState) {
protected int getLayoutResourceId(){
return R.layout.activity_sponsors;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sponsors);
appCtx = getApplicationContext();
ImageView closeActivity = findViewById(R.id.close);
TextView liberaPaySponsorsThomas = findViewById(R.id.liberaPaySponsorsThomas);
liberaPaySponsorsThomas.setMovementMethod(LinkMovementMethod.getInstance());
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
Resources res = getResources();
CharSequence[] sponsorsInfo = res.getTextArray(R.array.sponsorsInfo);
List<CharSequence> sponsorsList = new ArrayList<>(Arrays.asList(sponsorsInfo));
RecyclerView mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(appCtx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
SponsorsAdapter adapter = new SponsorsAdapter(sponsorsList);
mRecyclerView.setAdapter(adapter);
}
private void initCloseListener() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,59 @@
package org.mian.gitnex.adapters;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import java.util.List;
/**
* Author M M Arif
*/
public class CreditsAdapter extends RecyclerView.Adapter<CreditsAdapter.CreditsViewHolder> {
private List<CharSequence> creditsList;
static class CreditsViewHolder extends RecyclerView.ViewHolder {
private TextView creditText;
private CreditsViewHolder(View itemView) {
super(itemView);
creditText = itemView.findViewById(R.id.creditText);
}
}
public CreditsAdapter(List<CharSequence> creditsListMain) {
this.creditsList = creditsListMain;
}
@NonNull
@Override
public CreditsAdapter.CreditsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.credits, parent, false);
return new CreditsAdapter.CreditsViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull CreditsAdapter.CreditsViewHolder holder, int position) {
SpannableStringBuilder strBuilder = new SpannableStringBuilder(creditsList.get(position));
holder.creditText.setText((strBuilder));
holder.creditText.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
public int getItemCount() {
return creditsList.size();
}
}

View File

@ -0,0 +1,138 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.database.models.DraftWithRepository;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.List;
/**
* Author M M Arif
*/
public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsViewHolder> {
private List<DraftWithRepository> draftsList;
private Context mCtx;
class DraftsViewHolder extends RecyclerView.ViewHolder {
private TextView draftText;
private TextView repoInfo;
private TextView repoId;
private TextView draftId;
private TextView issueNumber;
private TextView issueType;
private TextView repoOwner;
private TextView repoName;
private DraftsViewHolder(View itemView) {
super(itemView);
draftText = itemView.findViewById(R.id.draftText);
repoInfo = itemView.findViewById(R.id.repoInfo);
repoId = itemView.findViewById(R.id.repoId);
draftId = itemView.findViewById(R.id.draftId);
issueNumber = itemView.findViewById(R.id.issueNumber);
issueType = itemView.findViewById(R.id.issueType);
repoOwner = itemView.findViewById(R.id.repoOwner);
repoName = itemView.findViewById(R.id.repoName);
ImageView deleteDraft = itemView.findViewById(R.id.deleteDraft);
deleteDraft.setOnClickListener(itemDelete -> {
int getDraftId = Integer.parseInt(draftId.getText().toString());
deleteDraft(getAdapterPosition());
DraftsApi draftsApi = new DraftsApi(mCtx);
draftsApi.deleteSingleDraft(getDraftId);
});
itemView.setOnClickListener(itemEdit -> {
Intent intent = new Intent(mCtx, ReplyToIssueActivity.class);
intent.putExtra("commentBody", draftText.getText().toString());
intent.putExtra("issueNumber", issueNumber.getText().toString());
intent.putExtra("repositoryId", repoId.getText().toString());
intent.putExtra("draftTitle", repoInfo.getText().toString());
TinyDB tinyDb = new TinyDB(mCtx);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putLong("repositoryId", Long.parseLong(repoId.getText().toString()));
//tinyDb.putString("issueType", issueType.getText().toString());
mCtx.startActivity(intent);
});
}
}
public DraftsAdapter(Context mCtx, List<DraftWithRepository> draftsListMain) {
this.mCtx = mCtx;
this.draftsList = draftsListMain;
}
private void deleteDraft(int position) {
draftsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, draftsList.size());
Toasty.info(mCtx, mCtx.getResources().getString(R.string.draftsSingleDeleteSuccess));
}
@NonNull
@Override
public DraftsAdapter.DraftsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_drafts, parent, false);
return new DraftsViewHolder(v);
}
@SuppressLint("DefaultLocale")
@Override
public void onBindViewHolder(@NonNull DraftsAdapter.DraftsViewHolder holder, int position) {
DraftWithRepository currentItem = draftsList.get(position);
holder.repoId.setText(String.valueOf(currentItem.getRepositoryId()));
holder.draftId.setText(String.valueOf(currentItem.getDraftId()));
holder.issueNumber.setText(String.valueOf(currentItem.getIssueId()));
holder.issueType.setText(currentItem.getDraftType());
holder.repoOwner.setText(currentItem.getRepositoryOwner());
holder.repoName.setText(currentItem.getRepositoryName());
holder.draftText.setText(currentItem.getDraftText());
String issueNumber = "<font color='" + mCtx.getResources().getColor(R.color.lightGray) + "'>" + mCtx.getResources().getString(R.string.hash) + currentItem.getIssueId() + "</font>";
holder.repoInfo.setText(Html.fromHtml(issueNumber + " " + currentItem.getRepositoryOwner() + " / " + currentItem.getRepositoryName()));
}
@Override
public int getItemCount() {
return draftsList.size();
}
public void updateList(List<DraftWithRepository> list) {
draftsList = list;
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,293 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepositoriesAdapter.ReposSearchViewHolder> {
private List<UserRepositories> searchedReposList;
private Context mCtx;
public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context mCtx) {
this.mCtx = mCtx;
this.searchedReposList = dataList;
}
static class ReposSearchViewHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView repoName;
private TextView repoDescription;
private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic;
private TextView repoStars;
private TextView repoForks;
private TextView repoOpenIssuesCount;
private TextView repoType;
private LinearLayout archiveRepo;
private TextView repoBranch;
private ReposSearchViewHolder(View itemView) {
super(itemView);
repoName = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription);
image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch);
itemView.setOnClickListener(v -> {
Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName);
Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", repoFullName.getText().toString());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
tinyDb.putString("repoBranch", repoBranch.getText().toString());
String[] parts = fullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
//RepositoriesRepository.deleteRepositoriesByAccount(currentActiveAccountId);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
//store if user is watching this repo
{
final String instanceUrl = tinyDb.getString("instanceUrl");
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchInfo watch = new WatchInfo();
Call<WatchInfo> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchInfo>() {
@Override
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
}
}
@Override
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
});
}
context.startActivity(intent);
});
reposDropdownMenu.setOnClickListener(v -> {
final Context context = v.getContext();
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
BottomSheetDialog dialog = new BottomSheetDialog(context);
dialog.setContentView(view);
dialog.show();
repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
});
repoStargazers.setOnClickListener(stargazers -> {
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
dialog.dismiss();
});
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
});
}
}
@NonNull
@Override
public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories, parent, false);
return new ExploreRepositoriesAdapter.ReposSearchViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull final ExploreRepositoriesAdapter.ReposSearchViewHolder holder, int position) {
UserRepositories currentItem = searchedReposList.get(position);
holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch());
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
if(currentItem.getAvatar_url() != null) {
if(!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
}
else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
holder.repoName.setText(currentItem.getName());
if(!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription());
}
holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate);
}
else {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic);
}
holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
if(currentItem.isArchived()) {
holder.archiveRepo.setVisibility(View.VISIBLE);
}
else {
holder.archiveRepo.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return searchedReposList.size();
}
}

View File

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

View File

@ -0,0 +1,267 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.helpers.DiffTextView;
import org.mian.gitnex.models.FileDiffView;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
/**
* Author opyale
*/
public class FilesDiffAdapter extends BaseAdapter {
private static Map<Long, View> selectedViews;
private static final int MAXIMUM_LINES = 5000;
private static int COLOR_ADDED;
private static int COLOR_REMOVED;
private static int COLOR_NORMAL;
private static int COLOR_SELECTED;
private static int COLOR_FONT;
private Context context;
private List<FileDiffView> fileDiffViews;
public FilesDiffAdapter(Context context, List<FileDiffView> fileDiffViews) {
this.context = context;
this.fileDiffViews = fileDiffViews;
selectedViews = new ConcurrentSkipListMap<>();
COLOR_ADDED = getColorFromAttribute(R.attr.diffAddedColor);
COLOR_REMOVED = getColorFromAttribute(R.attr.diffRemovedColor);
COLOR_NORMAL = getColorFromAttribute(R.attr.primaryBackgroundColor);
COLOR_SELECTED = getColorFromAttribute(R.attr.diffSelectedColor);
COLOR_FONT = getColorFromAttribute(R.attr.inputTextColor);
}
@Override
public int getCount() {
return fileDiffViews.size();
}
@Override
public Object getItem(int position) {
return fileDiffViews.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint({"ViewHolder", "InflateParams"})
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_files_diffs, null, false);
TextView headerFileName = convertView.findViewById(R.id.headerFileName);
TextView headerFileInfo = convertView.findViewById(R.id.headerFileInfo);
ImageView footerImage = convertView.findViewById(R.id.footerImage);
LinearLayout diffStats = convertView.findViewById(R.id.diff_stats);
LinearLayout diffLines = convertView.findViewById(R.id.diffLines);
FileDiffView data = (FileDiffView) getItem(position);
headerFileName.setText(data.getFileName());
if(data.isFileBinary()) {
diffStats.setVisibility(View.GONE);
diffLines.addView(getMessageView(context.getResources().getString(R.string.binaryFileError)));
}
else {
diffStats.setVisibility(View.VISIBLE);
headerFileInfo.setText(data.getFileInfo());
String[] codeLines = getLines(data.toString());
if(MAXIMUM_LINES > codeLines.length) {
for(int l=0; l<codeLines.length; l++) {
if(codeLines[l].length() > 0) {
int uniquePosition = l + (position * MAXIMUM_LINES);
DiffTextView diffTextView = new DiffTextView(context);
diffTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
diffTextView.setPadding(15, 2, 15, 2);
diffTextView.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf"));
diffTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
diffTextView.setPosition(uniquePosition);
boolean isSelected = false;
for(View view : selectedViews.values()) {
if(((DiffTextView) view).getPosition() == uniquePosition) {
diffTextView.setBackgroundColor(COLOR_SELECTED);
isSelected = true;
break;
}
}
if(codeLines[l].startsWith("+")) {
diffTextView.setText(codeLines[l]);
diffTextView.setTextColor(COLOR_FONT);
if(!isSelected) {
diffTextView.setInitialBackgroundColor(COLOR_ADDED);
}
}
else if(codeLines[l].startsWith("-")) {
diffTextView.setText(codeLines[l]);
diffTextView.setTextColor(COLOR_FONT);
if(!isSelected) {
diffTextView.setInitialBackgroundColor(COLOR_REMOVED);
}
}
else {
diffTextView.setText(codeLines[l]);
diffTextView.setTextColor(COLOR_FONT);
if(!isSelected) {
diffTextView.setInitialBackgroundColor(COLOR_NORMAL);
}
}
diffTextView.setOnClickListener(v -> {
if(((DiffTextView) v).getCurrentBackgroundColor() != COLOR_SELECTED) {
selectedViews.put(((DiffTextView) v).getPosition(), v);
v.setBackgroundColor(COLOR_SELECTED);
}
else {
selectedViews.remove(((DiffTextView) v).getPosition());
v.setBackgroundColor(((DiffTextView) v).getInitialBackgroundColor());
}
});
diffTextView.setOnLongClickListener(v -> {
if(((DiffTextView) v).getCurrentBackgroundColor() == COLOR_SELECTED) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("```\n");
for(View view : selectedViews.values()) {
stringBuilder.append(((DiffTextView) view).getText());
stringBuilder.append("\n");
}
stringBuilder.append("```\n\n");
selectedViews.clear();
Intent intent = new Intent(context, ReplyToIssueActivity.class);
intent.putExtra("commentBody", stringBuilder.toString());
intent.putExtra("cursorToEnd", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
return true;
});
diffLines.addView(diffTextView);
}
}
}
else {
diffLines.addView(getMessageView(context.getResources().getString(R.string.fileTooLarge)));
}
}
return convertView;
}
private TextView getMessageView(String message) {
TextView textView = new TextView(context);
textView.setTextColor(COLOR_FONT);
textView.setBackgroundColor(COLOR_NORMAL);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
textView.setPadding(15, 15, 15, 15);
textView.setTypeface(Typeface.DEFAULT);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setText(message);
return textView;
}
private String[] getLines(String content) {
return content.split("\\R");
}
private int getColorFromAttribute(int resid) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(resid, typedValue, true);
return typedValue.data;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,125 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.models.NotificationThread;
import java.util.List;
/**
* Author opyale
*/
public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.NotificationsViewHolder> {
private Context context;
private List<NotificationThread> notificationThreads;
private OnMoreClickedListener onMoreClickedListener;
private OnNotificationClickedListener onNotificationClickedListener;
public NotificationsAdapter(Context context, List<NotificationThread> notificationThreads, OnMoreClickedListener onMoreClickedListener, OnNotificationClickedListener onNotificationClickedListener) {
this.context = context;
this.notificationThreads = notificationThreads;
this.onMoreClickedListener = onMoreClickedListener;
this.onNotificationClickedListener = onNotificationClickedListener;
}
static class NotificationsViewHolder extends RecyclerView.ViewHolder {
private LinearLayout frame;
private TextView subject;
private TextView repository;
private ImageView type;
private ImageView pinned;
private ImageView more;
public NotificationsViewHolder(@NonNull View itemView) {
super(itemView);
frame = itemView.findViewById(R.id.frame);
subject = itemView.findViewById(R.id.subject);
repository = itemView.findViewById(R.id.repository);
type = itemView.findViewById(R.id.type);
pinned = itemView.findViewById(R.id.pinned);
more = itemView.findViewById(R.id.more);
}
}
@NonNull
@Override
public NotificationsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.list_notifications, parent, false);
return new NotificationsAdapter.NotificationsViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull NotificationsViewHolder holder, int position) {
NotificationThread notificationThread = notificationThreads.get(position);
String url = notificationThread.getSubject().getUrl();
String subjectId = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources()
.getString(R.string.hash) + url.substring(url.lastIndexOf("/") + 1) + "</font>";
holder.subject.setText(Html.fromHtml(subjectId + " " + notificationThread.getSubject().getTitle()));
holder.repository.setText(notificationThread.getRepository().getFullname());
if(notificationThread.isPinned()) {
holder.pinned.setVisibility(View.VISIBLE);
}
else {
holder.pinned.setVisibility(View.GONE);
}
switch(notificationThread.getSubject().getType()) {
case "Pull":
holder.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_pull_request, null));
break;
case "Issue":
holder.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_issue, null));
break;
default:
holder.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_question, null));
break;
}
holder.frame.setOnClickListener(v -> onNotificationClickedListener.onNotificationClicked(notificationThread));
holder.more.setOnClickListener(v -> onMoreClickedListener.onMoreClicked(notificationThread));
}
@Override
public int getItemCount() {
return notificationThreads.size();
}
public interface OnNotificationClickedListener {
void onNotificationClicked(NotificationThread notificationThread);
}
public interface OnMoreClickedListener {
void onMoreClicked(NotificationThread notificationThread);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,255 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.PullRequests;
import java.util.List;
import java.util.Locale;
/**
* Author M M Arif
*/
public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private final int TYPE_LOAD = 0;
private List<PullRequests> prList;
private PullRequestsAdapter.OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
public PullRequestsAdapter(Context context, List<PullRequests> prListMain) {
this.context = context;
this.prList = prListMain;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD) {
return new PullRequestsAdapter.PullRequestsHolder(inflater.inflate(R.layout.list_pr, parent, false));
}
else {
return new PullRequestsAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((PullRequestsAdapter.PullRequestsHolder) holder).bindData(prList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(prList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return prList.size();
}
class PullRequestsHolder extends RecyclerView.ViewHolder {
private TextView prNumber;
private TextView prMergeable;
private TextView prHeadBranch;
private TextView prIsFork;
private TextView prForkFullName;
private ImageView assigneeAvatar;
private TextView prTitle;
private TextView prCreatedTime;
private TextView prCommentsCount;
PullRequestsHolder(View itemView) {
super(itemView);
prNumber = itemView.findViewById(R.id.prNumber);
prMergeable = itemView.findViewById(R.id.prMergeable);
prHeadBranch = itemView.findViewById(R.id.prHeadBranch);
prIsFork = itemView.findViewById(R.id.prIsFork);
prForkFullName = itemView.findViewById(R.id.prForkFullName);
assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
prTitle = itemView.findViewById(R.id.prTitle);
prCommentsCount = itemView.findViewById(R.id.prCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
prCreatedTime = itemView.findViewById(R.id.prCreatedTime);
prTitle.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", prNumber.getText());
intent.putExtra("prMergeable", prMergeable.getText());
intent.putExtra("prHeadBranch", prHeadBranch.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", prNumber.getText().toString());
tinyDb.putString("prMergeable", prMergeable.getText().toString());
tinyDb.putString("prHeadBranch", prHeadBranch.getText().toString());
tinyDb.putString("prIsFork", prIsFork.getText().toString());
tinyDb.putString("prForkFullName", prForkFullName.getText().toString());
tinyDb.putString("issueType", "Pull");
context.startActivity(intent);
});
frameCommentsCount.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", prNumber.getText());
intent.putExtra("prMergeable", prMergeable.getText());
intent.putExtra("prHeadBranch", prHeadBranch.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", prNumber.getText().toString());
tinyDb.putString("prMergeable", prMergeable.getText().toString());
tinyDb.putString("prHeadBranch", prHeadBranch.getText().toString());
tinyDb.putString("prIsFork", prIsFork.getText().toString());
tinyDb.putString("prForkFullName", prForkFullName.getText().toString());
tinyDb.putString("issueType", "Pull");
context.startActivity(intent);
});
}
@SuppressLint("SetTextI18n")
void bindData(PullRequests prModel) {
final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
if(!prModel.getUser().getFull_name().equals("")) {
assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getFull_name(), context));
}
else {
assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getLogin(), context));
}
if(prModel.getUser().getAvatar_url() != null) {
PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
}
else {
PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
}
String prNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + prModel.getNumber() + "</font>";
prTitle.setText(Html.fromHtml(prNumber_ + " " + prModel.getTitle()));
prNumber.setText(String.valueOf(prModel.getNumber()));
prMergeable.setText(String.valueOf(prModel.isMergeable()));
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));
if(timeFormat.equals("pretty")) {
prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context));
}
}
}
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(PullRequestsAdapter.OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void updateList(List<PullRequests> list) {
prList = list;
notifyDataSetChanged();
}
}

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.helpers.TinyDB;
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()));
}
}
@ -80,7 +104,7 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
@NonNull
@Override
public ReleasesAdapter.ReleasesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.releases_list, parent, false);
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_releases, parent, false);
return new ReleasesAdapter.ReleasesViewHolder(v);
}
@ -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_chevron_down);
holder.downloads.setVisibility(View.VISIBLE);
}
else {
holder.downloadDropdownIcon.setImageResource(R.drawable.ic_chevron_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

@ -2,15 +2,17 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.UserInfo;
import java.util.List;
@ -23,7 +25,7 @@ public class RepoStargazersAdapter extends BaseAdapter {
private List<UserInfo> stargazersList;
private Context mCtx;
private class ViewHolder {
private static class ViewHolder {
private ImageView memberAvatar;
private TextView memberName;
@ -61,8 +63,8 @@ public class RepoStargazersAdapter extends BaseAdapter {
RepoStargazersAdapter.ViewHolder viewHolder;
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.repo_stargazers_list, null);
viewHolder = new RepoStargazersAdapter.ViewHolder(finalView);
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_repo_stargazers, null);
viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder);
}
else {
@ -77,13 +79,34 @@ public class RepoStargazersAdapter extends BaseAdapter {
private void initData(RepoStargazersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = stargazersList.get(position);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.memberAvatar);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
final TinyDB tinyDb = new TinyDB(mCtx);
Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
break;
}
if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname());
viewHolder.memberName.setTypeface(myTypeface);
}
else {
viewHolder.memberName.setText(currentItem.getLogin());
viewHolder.memberName.setTypeface(myTypeface);
}
}

View File

@ -2,15 +2,17 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.UserInfo;
import java.util.List;
@ -23,7 +25,7 @@ public class RepoWatchersAdapter extends BaseAdapter {
private List<UserInfo> watchersList;
private Context mCtx;
private class ViewHolder {
private static class ViewHolder {
private ImageView memberAvatar;
private TextView memberName;
@ -61,8 +63,8 @@ public class RepoWatchersAdapter extends BaseAdapter {
RepoWatchersAdapter.ViewHolder viewHolder;
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.repo_watchers_list, null);
viewHolder = new RepoWatchersAdapter.ViewHolder(finalView);
finalView = LayoutInflater.from(mCtx).inflate(R.layout.list_repo_watchers, null);
viewHolder = new ViewHolder(finalView);
finalView.setTag(viewHolder);
}
else {
@ -77,13 +79,34 @@ public class RepoWatchersAdapter extends BaseAdapter {
private void initData(RepoWatchersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = watchersList.get(position);
Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.memberAvatar);
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
final TinyDB tinyDb = new TinyDB(mCtx);
Typeface myTypeface;
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/roboto.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(mCtx.getAssets(), "fonts/manroperegular.ttf");
break;
}
if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname());
viewHolder.memberName.setTypeface(myTypeface);
}
else {
viewHolder.memberName.setText(currentItem.getLogin());
viewHolder.memberName.setTypeface(myTypeface);
}
}

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