Compare commits

...

91 Commits
1.5.0 ... 2.1.1

Author SHA1 Message Date
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
8b26355fc0 Merge branch 'prepare-release' of mmarif/GitNex into master 2019-10-01 15:35:05 +00:00
8effad46f8 app release 2.1.0 2019-10-01 20:31:01 +05:00
53efd8b777 Merge branch '79-repo-avatar' of mmarif/GitNex into master 2019-10-01 13:59:59 +00:00
19cd5b6c5e added repos avatars 2019-10-01 18:56:20 +05:00
69082b424a Merge branch '54-enable-disable-create-issue' of mmarif/GitNex into master 2019-10-01 13:07:58 +00:00
d8b3477940 check if repo issues is enalbed or disabled 2019-10-01 18:05:09 +05:00
34892e7f43 Merge branch 'fix-ms-bar' of mmarif/GitNex into master 2019-10-01 10:26:03 +00:00
d64b035d4a fix ms progress bar 2019-10-01 15:23:49 +05:00
e2fa79b2a9 Merge branch 'master' of gitea.com:mmarif/GitNex 2019-10-01 15:06:46 +05:00
9e658aa38c 63-ms-ui (#82) 2019-10-01 10:05:26 +00:00
e4700ffd69 Merge branch 'master' of gitea.com:mmarif/GitNex 2019-10-01 11:44:45 +05:00
e53ef41fc1 ui-improvements (#81) 2019-10-01 06:42:56 +00:00
c05e69cfe9 t 2019-10-01 10:23:50 +05:00
5c6d5177fb r 2019-10-01 10:14:54 +05:00
62a5452437 Merge branch 'master' of gitea.com:mmarif/GitNex
# Conflicts:
#	app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java
#	app/src/main/java/org/mian/gitnex/activities/MainActivity.java
#	app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/MembersByOrgAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/ProfileFollowersAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/ProfileFollowingAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/RepositoriesByOrgAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/StarredReposListAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java
#	app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java
#	app/src/main/java/org/mian/gitnex/fragments/OrganizationInfoFragment.java
#	app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java
#	app/src/main/res/layout/activity_issue_detail.xml
#	app/src/main/res/layout/admin_users_list.xml
#	app/src/main/res/layout/fragment_profile.xml
#	app/src/main/res/layout/issue_comments.xml
#	app/src/main/res/layout/my_repos_list.xml
#	app/src/main/res/layout/nav_header.xml
#	app/src/main/res/layout/organizations_list.xml
#	app/src/main/res/layout/profile_followers_list.xml
#	app/src/main/res/layout/profile_following_list.xml
#	app/src/main/res/layout/repos_list.xml
#	app/src/main/res/layout/repositories_by_org_list.xml
#	app/src/main/res/layout/starred_repos_list.xml
2019-10-01 10:14:45 +05:00
5f402c2c60 merge 2019-10-01 10:12:18 +05:00
85140fbee0 Merge branch '77-ui-changes' of mmarif/GitNex into master 2019-09-30 18:16:24 +00:00
d350fe96d9 Merge branch 'master' into 77-ui-changes 2019-09-30 23:14:04 +05:00
61a1a4446f Merge branch '62-improve-issues-ui' of mmarif/GitNex into master 2019-09-30 18:09:47 +00:00
c1e27c9776 Merge branch 'issue-copy-nr' of 6543/GitNex into master 2019-09-30 18:07:25 +00:00
03ec591643 more ui changes 2019-09-30 22:48:52 +05:00
3ebc1ae3e0 avatars improvements 2019-09-30 22:39:33 +05:00
3c8fb5bc60 markdown code cleanup 2019-09-30 21:21:51 +05:00
5503fe9951 Redid the issues list ui and some clean up 2019-09-30 21:12:45 +05:00
7f417da6b3 update libs, switch to io.notis for md. refactor all the markdown code 2019-09-29 21:44:42 +05:00
4e8a961643 copyIssue -> copyIssueUrl 2019-09-29 00:56:48 +02:00
bf5527a82d issue -> issueUrl 2019-09-29 00:10:28 +02:00
c31cf53023 Merge branch 'milestoneProgress' of 6543/GitNex into master 2019-09-28 18:15:41 +00:00
0ac2a27549 all milestones look similar 2019-09-27 23:58:23 +02:00
dcabfa4f14 add Progress Bar function 2019-09-27 23:32:31 +02:00
9688c75106 add progress bar to layout 2019-09-27 22:52:29 +02:00
71bb8cc75d add copy function 2019-09-27 21:17:28 +02:00
dcd28e845a add Copy to Clipboard String 2019-09-27 19:12:19 +02:00
b3e88b0a9d add content copy icon 2019-09-27 18:50:05 +02:00
ce67f59753 Merge branch '67-filter-icon' of mmarif/GitNex into master 2019-09-26 19:09:16 +00:00
d0b6730de4 change search icon/text to filter 2019-09-26 23:58:36 +05:00
f5e18ed5cc Merge branch 'dl-apk-buton' of 6543/GitNex into master 2019-09-23 18:38:31 +00:00
88394e1c25 Merge branch 'translate_german' of IndeedNotJames/GitNex into master 2019-09-23 18:19:01 +00:00
a9030eb8c9 Bump requred Gitea Version 2019-09-22 18:05:54 +02:00
fff307d45a test look 2019-09-22 17:48:41 +02:00
b64ee37edd add release badge 2019-09-22 17:40:18 +02:00
b4b3c2f5ee add download apk sing from website 2019-09-22 16:49:07 +02:00
8f3ef29f44 complete german translation 2019-09-21 20:50:33 +02:00
d00691d71b Merge branch 'new-font-testing' of mmarif/GitNex into master 2019-09-19 06:35:28 +00:00
4867524b4f Merge branch 'master' into new-font-testing 2019-09-19 11:28:07 +05:00
a59e818aa2 Merge branch 'master' into new-font-testing 2019-09-19 11:27:09 +05:00
aeca4a0edb Merge branch 'fix-open-issue-tab' of mmarif/GitNex into master 2019-09-19 06:22:57 +00:00
2c60f092f1 Fix open issues tab color bug, dim color for info tab headers 2019-09-19 11:21:15 +05:00
fe0b3a77cc Merge branch 'minor-enhancements' of mmarif/GitNex into master 2019-09-19 05:38:26 +00:00
43c014948a Repo label and info tabs fixes 2019-09-19 10:36:55 +05:00
a497e0a284 new font 2019-09-19 10:10:12 +05:00
da268b017e Merge branch 'prepare-2-0-release' of mmarif/GitNex into master 2019-09-18 10:27:06 +00:00
4451adb01c prepare for release 2019-09-18 15:02:33 +05:00
0cd4e36a66 Merge branch '16-create-files' of mmarif/GitNex into master 2019-09-18 09:51:27 +00:00
742b1894e6 finished work on creating new file 2019-09-18 14:49:29 +05:00
8d1b47de8e wip on creating new file. still has to do branches section for old and new. 2019-09-18 13:25:49 +05:00
c38d249571 new file layout and bottomsheet link 2019-09-17 11:17:05 +05:00
c3da1900a0 add donator to sponsor page, file icon 2019-09-17 09:24:32 +05:00
b4c0745b40 reduce large links in branches and releases to small text with links.
Signed-off-by: M M Arif <mmarif@swatian.com>
2019-09-16 20:28:34 +05:00
e8e0cf904b Merge branch '37-fix-crash-within-tabs' of mmarif/GitNex into master 2019-09-14 09:43:54 +00:00
99718bc0c8 fix branches hash url 2019-09-14 14:40:47 +05:00
d4a5d5ee8c fix url linking for repo website 2019-09-14 13:22:01 +05:00
efffc05a89 fix crash on tabs, other ui fixes 2019-09-14 13:20:00 +05:00
a78018fd08 Merge branch '36-open-repo-in-browser' of mmarif/GitNex into master 2019-09-14 07:41:00 +00:00
33d1373f6e added open in browser 2019-09-14 12:38:41 +05:00
b15394e97d Add browser icon and xml element in menu 2019-09-14 12:26:20 +05:00
2bdeee5429 Merge branch '24-list-repo-watchers' of mmarif/GitNex into master 2019-09-14 06:55:22 +00:00
39c1ec36a7 Added repo watchers/subscribrs list 2019-09-14 11:29:20 +05:00
6866154714 Merge branch '25-list-repo-stargazers' of mmarif/GitNex into master 2019-09-13 16:03:29 +00:00
df260f05d2 added stargazers and other fixes and enhancements 2019-09-13 20:56:30 +05:00
d24e7ffc3b Add dotted menu 2019-09-13 12:21:52 +05:00
481451c791 Merge branch '23-fixes' of mmarif/GitNex into master 2019-09-12 08:32:00 +00:00
914d5cfa26 libs update, fixes search tap crashing. remove depricated classes 2019-09-12 13:30:07 +05:00
6710aa0810 clean up unwanted namespaces from layouts 2019-09-12 10:29:41 +05:00
87376a2104 Fix collaborator not found text 2019-09-12 10:21:53 +05:00
1ec7ac4f9f Merge branch 'open-repo-web' of 6543/GitNex into master 2019-09-11 06:26:58 +00:00
25f8277f0a translate missing with deepl 2019-09-10 19:56:54 +02:00
498bf7a72c spelling corection 2019-09-10 19:51:43 +02:00
20f687e30e add sugestions of mmarif
* delete OpenWebRepoActivity (function is handled in RepoDetailActivity )
 * add&handle case "openWebRepo" in RepoDetailActivity
 * add new Value "instanceUrlWithProtocol" to tinyDb
2019-09-10 19:48:44 +02:00
83e3564c13 try to implement OpenWebRepoActivity 2019-09-06 01:01:46 +02:00
7977aaa2be shorter text 2019-09-05 22:19:26 +02:00
6bc13ad4fe ues language icon also to indicate webbrowser open action 2019-09-05 22:06:23 +02:00
1f6f50977e Merge branch 'german-translation' of 6543/GitNex into master 2019-09-05 10:09:51 +00:00
1ce1278095 tiny lang. changes 2019-09-03 16:55:51 +02:00
ce63cde4ee add menue entry and strings 2019-09-03 16:46:38 +02:00
f23c4074f3 Merge branch 'master' of PsychotherapistSam/GitNex into master 2019-07-18 10:43:17 +00:00
ace9111225 Update 'app/src/main/res/values-de/strings.xml'
Updated some of the german translations :)
2019-07-18 03:44:16 +00:00
4aeeb95308 Merge branch 'fix-contribute-file' of mmarif/GitNex into master 2019-06-24 10:04:55 +00:00
056413e0b0 fix wordings 2019-06-24 02:33:30 +05:00
147 changed files with 3444 additions and 1077 deletions

View File

@ -3,14 +3,14 @@
Please take a few minutes to read this document to make the process of contribution more easy and healthy for all involved. Please take a few minutes to read this document to make the process of contribution more easy and healthy for all involved.
## Pull Requests ## Pull Requests
Patches, enhancements, features are always welcome. The MR should focus on the scope of work and avoid many unnecessary commits. Please provide as much detail and context as possible to explain the work submitted. Patches, enhancements, features are always welcome. The PR should focus on the scope of work and avoid many unnecessary commits. Please provide as much detail and context as possible to explain the work submitted.
Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work. Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work.
**How to submit MR/PR** **How to submit a PR**
Fork this repository. Pull the forked repository from your namespace to your local machine. Create new branch and work on the bug/feature/enhancement you would like to submit. Push it to your forked version. From there create Pull Request(PR) against **master** branch. Fork this repository. Pull the forked repository from your namespace to your local machine. Create new branch and work on the bug/feature/enhancement you would like to submit. Push it to your forked version. From there create Pull Request(PR) against **master** branch.
**IMPORTANT:** By submitting MR, you agree to allow GitNex to license your work under the same license as that used by GitNex. **IMPORTANT:** By submitting PR, you agree to allow GitNex to license your work under the same license as that used by GitNex.
## Issues and Reports ## Issues and Reports
*1st of please be polite and gentle while commenting or creating new issue to maintain a healthy environment.* *1st of please be polite and gentle while commenting or creating new issue to maintain a healthy environment.*

View File

@ -1,6 +1,8 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![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)
[<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif) [<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"/>](https://liberapay.com/mmarif/donate) [<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif)
[<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate)
# GitNex - Android client for Gitea # GitNex - Android client for Gitea
@ -10,10 +12,12 @@ GitNex is licensed under GPLv3 License. See the LICENSE file for the full licens
No trackers are used and source code is available here for anyone to audit. No trackers are used and source code is available here for anyone to audit.
## Downloads ## Downloads
[<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/) [<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex) [Download APK](https://gitea.com/mmarif/GitNex/releases) [<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/)
[<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex)
[<img alt='Download APK' src='https://gitnex.com/img/download-apk.png' height="80"/>](https://gitea.com/mmarif/GitNex/releases)
## Note about Gitea version ## Note about Gitea version
Please make sure that you are on Gitea **1.7.x** stable release or later. Below this may not work as one would expect because of the newly added objects to the API at later versions. Please consider updating your Gitea server. Please make sure that you are on Gitea **1.9.x** stable release or later. Below this may not work as one would expect because of the newly added objects to the API at later versions. Please consider updating your Gitea server.
Check the versions [compatibility page](https://gitea.com/mmarif/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio. Check the versions [compatibility page](https://gitea.com/mmarif/GitNex/wiki/Compatibility) which lists all the supported versions with compatibility ratio.

View File

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

View File

@ -2,9 +2,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mian.gitnex"> package="org.mian.gitnex">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/app_logo" android:icon="@mipmap/app_logo"
@ -13,7 +10,16 @@
android:roundIcon="@mipmap/app_logo_round" android:roundIcon="@mipmap/app_logo_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity android:name=".activities.AdminGetUsersActivity"></activity> <activity
android:name=".activities.NewFileActivity"
android:theme="@style/AppTheme.NoActionBar"></activity>
<activity
android:name=".activities.RepoWatchersActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".activities.RepoStargazersActivity"
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".activities.AdminGetUsersActivity" />
<activity <activity
android:name=".activities.AddRemoveAssigneesActivity" android:name=".activities.AddRemoveAssigneesActivity"
android:theme="@style/Theme.AppCompat.Light.Dialog" /> android:theme="@style/Theme.AppCompat.Light.Dialog" />
@ -56,6 +62,10 @@
android:launchMode="singleTask" /> android:launchMode="singleTask" />
<activity android:name=".activities.NewRepoActivity" /> <activity android:name=".activities.NewRepoActivity" />
<activity android:name=".activities.NewOrganizationActivity" /> <activity android:name=".activities.NewOrganizationActivity" />
<activity android:name=".activities.OpenRepoInBrowserActivity" />
</application> </application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest> </manifest>

View File

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

View File

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

View File

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

View File

@ -194,16 +194,20 @@ public class LoginActivity extends AppCompatActivity implements View.OnClickList
instanceHost = instanceUrl; instanceHost = instanceUrl;
} }
String instanceUrlWithProtocol;
if(protocol.toLowerCase().equals("https")) { if(protocol.toLowerCase().equals("https")) {
instanceUrl = "https://" + instanceHost + "/api/v1/"; instanceUrl = "https://" + instanceHost + "/api/v1/";
instanceUrlWithProtocol = "https://" + instanceHost;
} }
else { else {
instanceUrl = "http://" + instanceHost + "/api/v1/"; instanceUrl = "http://" + instanceHost + "/api/v1/";
instanceUrlWithProtocol = "https://" + instanceHost;
} }
tinyDb.putString("instanceUrlRaw", instanceHost); tinyDb.putString("instanceUrlRaw", instanceHost);
tinyDb.putString("loginUid", loginUid); tinyDb.putString("loginUid", loginUid);
tinyDb.putString("instanceUrl", instanceUrl); tinyDb.putString("instanceUrl", instanceUrl);
tinyDb.putString("instanceUrlWithProtocol", instanceUrlWithProtocol);
if(connToInternet) { if(connToInternet) {

View File

@ -148,7 +148,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
userAvatar = hView.findViewById(R.id.userAvatar); userAvatar = hView.findViewById(R.id.userAvatar);
if (!userAvatarNav.equals("")) { if (!userAvatarNav.equals("")) {
Picasso.get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).transform(new RoundedTransformation(100, 0)).resize(180, 180).centerCrop().into(userAvatar); Picasso.get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(userAvatar);
} }
} else { } else {
@ -330,6 +330,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
if (response.code() == 200) { if (response.code() == 200) {
assert userDetails != null; assert userDetails != null;
if(userDetails.getIs_admin() != null) {
tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin());
}
tinyDb.putString("userLogin", userDetails.getLogin()); tinyDb.putString("userLogin", userDetails.getLogin());
tinyDb.putInt("userId", userDetails.getId()); tinyDb.putInt("userId", userDetails.getId());
if(!userDetails.getFullname().equals("")) { if(!userDetails.getFullname().equals("")) {
@ -351,7 +354,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
userAvatar = hView.findViewById(R.id.userAvatar); userAvatar = hView.findViewById(R.id.userAvatar);
if (!Objects.requireNonNull(userDetails).getAvatar().equals("")) { if (!Objects.requireNonNull(userDetails).getAvatar().equals("")) {
Picasso.get().load(userDetails.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(180, 180).centerCrop().into(userAvatar); Picasso.get().load(userDetails.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(userAvatar);
} else { } else {
userAvatar.setImageResource(R.mipmap.ic_launcher_round); userAvatar.setImageResource(R.mipmap.ic_launcher_round);
} }

View File

@ -0,0 +1,335 @@
package org.mian.gitnex.activities;
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.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
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.Authorization;
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;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class NewFileActivity extends AppCompatActivity {
public ImageView closeActivity;
private View.OnClickListener onClickListener;
private Button newFileCreate;
private EditText newFileName;
private EditText newFileContent;
private EditText newFileBranchName;
private EditText newFileCommitMessage;
private Spinner newFileBranchesSpinner;
final Context ctx = this;
List<Branches> branchesList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_file);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
closeActivity = findViewById(R.id.close);
newFileName = findViewById(R.id.newFileName);
newFileContent = findViewById(R.id.newFileContent);
newFileBranchName = findViewById(R.id.newFileBranchName);
newFileCommitMessage = findViewById(R.id.newFileCommitMessage);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
newFileCreate = findViewById(R.id.newFileCreate);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
newFileBranchesSpinner = findViewById(R.id.newFileBranchesSpinner);
newFileBranchesSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
newFileBranchesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> arg0,
View arg1, int arg2, long arg3)
{
Branches bModelValue = (Branches) newFileBranchesSpinner.getSelectedItem();
Log.i("bModelSelected", bModelValue.toString());
if(bModelValue.toString().equals("No branch")) {
newFileBranchName.setEnabled(true);
}
else {
newFileBranchName.setEnabled(false);
newFileBranchName.setText("");
}
}
public void onNothingSelected(AdapterView<?> arg0) {}
});
disableProcessButton();
if(!connToInternet) {
newFileCreate.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
newFileCreate.setBackground(shape);
} else {
newFileCreate.setOnClickListener(createFileListener);
}
}
private View.OnClickListener createFileListener = new View.OnClickListener() {
public void onClick(View v) {
processNewFile();
}
};
private void processNewFile() {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
String newFileName_ = newFileName.getText().toString();
String newFileContent_ = newFileContent.getText().toString();
String newFileBranchName_ = newFileBranchName.getText().toString();
String newFileCommitMessage_ = newFileCommitMessage.getText().toString();
Branches currentBranch = (Branches) newFileBranchesSpinner.getSelectedItem();
if(!connToInternet) {
Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return;
}
if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.newFileRequiredFields));
return;
}
if(currentBranch.toString().equals("No branch")) {
if(newFileBranchName_.equals("")) {
Toasty.info(getApplicationContext(), getString(R.string.newFileRequiredFieldNewBranchName));
return;
}
else {
if(!appUtil.checkStringsWithDash(newFileBranchName_)) {
Toasty.info(getApplicationContext(), getString(R.string.newFileInvalidBranchName));
return;
}
}
}
if(appUtil.charactersLength(newFileCommitMessage_) > 255) {
Toasty.info(getApplicationContext(), getString(R.string.newFileCommitMessageError));
}
else {
disableProcessButton();
createNewFile(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newFileName_, appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString());
}
}
private void createNewFile(final String instanceUrl, final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileBranchName, String fileCommitMessage, String currentBranch) {
NewFile createNewFileJsonStr;
if(currentBranch.equals("No branch")) {
createNewFileJsonStr = new NewFile("", fileContent, fileCommitMessage, fileBranchName);
}
else {
createNewFileJsonStr = new NewFile(currentBranch, fileContent, fileCommitMessage, "");
}
Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 201) {
enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.newFileSuccessMessage));
finish();
}
else if(response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
if(response.code() == 404) {
enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
}
else {
enableProcessButton();
Toasty.info(getApplicationContext(), getString(R.string.orgCreatedError));
}
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
enableProcessButton();
}
});
}
private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
Call<List<Branches>> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getBranches(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Branches>>() {
@Override
public void onResponse(@NonNull Call<List<Branches>> call, @NonNull retrofit2.Response<List<Branches>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
List<Branches> branchesList_ = response.body();
branchesList.add(new Branches("No branch"));
assert branchesList_ != null;
if(branchesList_.size() > 0) {
for (int i = 0; i < branchesList_.size(); i++) {
Branches data = new Branches(
branchesList_.get(i).getName()
);
branchesList.add(data);
}
}
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
newFileBranchesSpinner.setAdapter(adapter);
enableProcessButton();
}
}
}
@Override
public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
}
private void disableProcessButton() {
newFileCreate.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
newFileCreate.setBackground(shape);
}
private void enableProcessButton() {
newFileCreate.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
newFileCreate.setBackground(shape);
}
}

View File

@ -0,0 +1,35 @@
package org.mian.gitnex.activities;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import org.mian.gitnex.util.TinyDB;
/**
* Author M M Arif
*/
public class OpenRepoInBrowserActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TinyDB tinyDb = new TinyDB(getApplicationContext());
String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw");
if (!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol");
}
String repoFullNameBrowser = getIntent().getStringExtra("repoFullNameBrowser");
Uri url = Uri.parse(instanceUrlWithProtocol + "/" + repoFullNameBrowser);
Intent i = new Intent(Intent.ACTION_VIEW, url);
startActivity(i);
finish();
}
}

View File

@ -3,9 +3,8 @@ package org.mian.gitnex.activities;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.GridView; import android.widget.GridView;
import android.widget.ImageView; import android.widget.ImageView;
@ -63,7 +62,7 @@ public class OrgTeamMembersActivity extends AppCompatActivity {
} }
getIntent().getStringExtra("teamId"); getIntent().getStringExtra("teamId");
Log.i("teamId", getIntent().getStringExtra("teamId")); //Log.i("teamId", getIntent().getStringExtra("teamId"));
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), Integer.valueOf(teamId)); fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), Integer.valueOf(teamId));
@ -71,7 +70,7 @@ public class OrgTeamMembersActivity extends AppCompatActivity {
private void fetchDataAsync(String instanceUrl, String instanceToken, int teamId) { private void fetchDataAsync(String instanceUrl, String instanceToken, int teamId) {
TeamMembersByOrgViewModel teamMembersModel = ViewModelProviders.of(this).get(TeamMembersByOrgViewModel.class); TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class);
teamMembersModel.getMembersByOrgList(instanceUrl, instanceToken, teamId).observe(this, new Observer<List<UserInfo>>() { teamMembersModel.getMembersByOrgList(instanceUrl, instanceToken, teamId).observe(this, new Observer<List<UserInfo>>() {
@Override @Override

View File

@ -10,7 +10,9 @@ import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -35,6 +37,7 @@ import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.Objects; import java.util.Objects;
import android.net.Uri;
/** /**
* Author M M Arif * Author M M Arif
@ -79,13 +82,19 @@ public class RepoDetailActivity extends AppCompatActivity implements RepoBottomS
if(tinyDb.getBoolean("enableCounterIssueBadge")) { if(tinyDb.getBoolean("enableCounterIssueBadge")) {
View tabHeader = LayoutInflater.from(this).inflate(R.layout.badge, null); @SuppressLint("InflateParams") View tabHeader = LayoutInflater.from(this).inflate(R.layout.badge, null);
textViewBadge = tabHeader.findViewById(R.id.counterBadge); textViewBadge = tabHeader.findViewById(R.id.counterBadge);
if(!tinyDb.getString("issuesCounter").isEmpty()) { if(!tinyDb.getString("issuesCounter").isEmpty()) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
} }
Objects.requireNonNull(tabLayout.getTabAt(1)).setCustomView(tabHeader); Objects.requireNonNull(tabLayout.getTabAt(1)).setCustomView(tabHeader);
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);
} }
} }
@ -107,7 +116,6 @@ public class RepoDetailActivity extends AppCompatActivity implements RepoBottomS
} }
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
@ -153,6 +161,20 @@ public class RepoDetailActivity extends AppCompatActivity implements RepoBottomS
case "createRelease": case "createRelease":
startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class)); startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
break; 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;
} }
} }
@ -160,7 +182,7 @@ public class RepoDetailActivity extends AppCompatActivity implements RepoBottomS
public class SectionsPagerAdapter extends FragmentStatePagerAdapter { public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) { SectionsPagerAdapter(FragmentManager fm) {
super(fm); super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
} }
@NonNull @NonNull

View File

@ -0,0 +1,95 @@
package org.mian.gitnex.activities;
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 org.mian.gitnex.R;
import org.mian.gitnex.adapters.RepoStargazersAdapter;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.RepoStargazersViewModel;
import java.util.List;
/**
* Author M M Arif
*/
public class RepoStargazersActivity extends AppCompatActivity {
private TextView noDataStargazers;
private View.OnClickListener onClickListener;
private RepoStargazersAdapter adapter;
private GridView mGridView;
private ProgressBar mProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_repo_stargazers);
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);
noDataStargazers = findViewById(R.id.noDataStargazers);
mGridView = findViewById(R.id.gridView);
mProgressBar = findViewById(R.id.progress_bar);
String repoFullNameForStars = getIntent().getStringExtra("repoFullNameForStars");
String[] parts = repoFullNameForStars.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
toolbarTitle.setText(R.string.repoStargazersInMenu);
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
}
private void fetchDataAsync(String instanceUrl, String instanceToken, String repoOwner, String repoName) {
RepoStargazersViewModel repoStargazersModel = new ViewModelProvider(this).get(RepoStargazersViewModel.class);
repoStargazersModel.getRepoStargazers(instanceUrl, instanceToken, repoOwner, repoName).observe(this, new Observer<List<UserInfo>>() {
@Override
public void onChanged(@Nullable List<UserInfo> stargazersListMain) {
adapter = new RepoStargazersAdapter(getApplicationContext(), stargazersListMain);
if(adapter.getCount() > 0) {
mGridView.setAdapter(adapter);
noDataStargazers.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mGridView.setAdapter(adapter);
noDataStargazers.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
});
}
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
}
}

View File

@ -0,0 +1,95 @@
package org.mian.gitnex.activities;
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 org.mian.gitnex.R;
import org.mian.gitnex.adapters.RepoWatchersAdapter;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.viewmodels.RepoWatchersViewModel;
import java.util.List;
/**
* Author M M Arif
*/
public class RepoWatchersActivity extends AppCompatActivity {
private TextView noDataWatchers;
private View.OnClickListener onClickListener;
private RepoWatchersAdapter adapter;
private GridView mGridView;
private ProgressBar mProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_repo_watchers);
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);
noDataWatchers = findViewById(R.id.noDataWatchers);
mGridView = findViewById(R.id.gridView);
mProgressBar = findViewById(R.id.progress_bar);
String repoFullNameForWatchers = getIntent().getStringExtra("repoFullNameForWatchers");
String[] parts = repoFullNameForWatchers.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
toolbarTitle.setText(R.string.repoWatchersInMenu);
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
}
private void fetchDataAsync(String instanceUrl, String instanceToken, String repoOwner, String repoName) {
RepoWatchersViewModel repoWatchersModel = new ViewModelProvider(this).get(RepoWatchersViewModel.class);
repoWatchersModel.getRepoWatchers(instanceUrl, instanceToken, repoOwner, repoName).observe(this, new Observer<List<UserInfo>>() {
@Override
public void onChanged(@Nullable List<UserInfo> watchersListMain) {
adapter = new RepoWatchersAdapter(getApplicationContext(), watchersListMain);
if(adapter.getCount() > 0) {
mGridView.setAdapter(adapter);
noDataWatchers.setVisibility(View.GONE);
}
else {
adapter.notifyDataSetChanged();
mGridView.setAdapter(adapter);
noDataWatchers.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
});
}
private void initCloseListener() {
onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
}
}

View File

@ -2,8 +2,10 @@ package org.mian.gitnex.activities;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
/** /**
@ -20,6 +22,9 @@ public class SponsorsActivity extends AppCompatActivity {
setContentView(R.layout.activity_sponsors); setContentView(R.layout.activity_sponsors);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
TextView liberaPaySponsorsThomas = findViewById(R.id.liberaPaySponsorsThomas);
liberaPaySponsorsThomas.setMovementMethod(LinkMovementMethod.getInstance());
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);

View File

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

View File

@ -1,12 +1,13 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.content.Context; import android.content.Context;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.UrlHelper;
import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.Branches;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.List; import java.util.List;
@ -66,7 +67,9 @@ public class BranchesAdapter extends RecyclerView.Adapter<BranchesAdapter.Branch
holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getUsername())); holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getUsername()));
} }
holder.branchCommitHash.setText(mCtx.getResources().getString(R.string.commitHash, UrlHelper.cleanUrl(instanceUrl), currentItem.getCommit().getUrl())); holder.branchCommitHash.setText(
Html.fromHtml("<a href='" + currentItem.getCommit().getUrl() + "'>" + mCtx.getResources().getString(R.string.commitLinkBranchesTab) + "</a> "));
holder.branchCommitHash.setMovementMethod(LinkMovementMethod.getInstance());
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter; import android.widget.Filter;
@ -12,13 +13,21 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
/** /**
@ -39,7 +48,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
private TextView fullNameMy; private TextView fullNameMy;
private ImageView repoPrivatePublicMy; private ImageView repoPrivatePublicMy;
private TextView repoStarsMy; private TextView repoStarsMy;
private TextView repoWatchersMy; private TextView repoForksMy;
private TextView repoOpenIssuesCountMy; private TextView repoOpenIssuesCountMy;
private MyReposViewHolder(View itemView) { private MyReposViewHolder(View itemView) {
@ -50,8 +59,9 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
fullNameMy = itemView.findViewById(R.id.repoFullNameMy); fullNameMy = itemView.findViewById(R.id.repoFullNameMy);
repoPrivatePublicMy = itemView.findViewById(R.id.imageRepoTypeMy); repoPrivatePublicMy = itemView.findViewById(R.id.imageRepoTypeMy);
repoStarsMy = itemView.findViewById(R.id.repoStarsMy); repoStarsMy = itemView.findViewById(R.id.repoStarsMy);
repoWatchersMy = itemView.findViewById(R.id.repoWatchersMy); repoForksMy = itemView.findViewById(R.id.repoForksMy);
repoOpenIssuesCountMy = itemView.findViewById(R.id.repoOpenIssuesCountMy); repoOpenIssuesCountMy = itemView.findViewById(R.id.repoOpenIssuesCountMy);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
itemView.setOnClickListener(new View.OnClickListener() { itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -70,6 +80,69 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
} }
}); });
reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext();
Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
PopupMenu popupMenu = new PopupMenu(context_, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
} catch (Exception e) {
popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.repoStargazers:
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullNameMy.getText());
context.startActivity(intent);
break;
case R.id.repoWatchers:
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullNameMy.getText());
context.startActivity(intentW);
break;
case R.id.repoOpenInBrowser:
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullNameMy.getText());
context.startActivity(intentOpenInBrowser);
break;
}
return false;
}
});
popupMenu.show();
}
});
} }
} }
@ -94,19 +167,24 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
String charac = String.valueOf(currentItem.getName().charAt(0)); String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
.useFont(Typeface.DEFAULT) .useFont(Typeface.DEFAULT)
.fontSize(16) .fontSize(18)
.toUpperCase() .toUpperCase()
.width(28) .width(28)
.height(28) .height(28)
.endConfig() .endConfig()
.buildRound(charac, color); .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);
}
holder.imageMy.setImageDrawable(drawable);
holder.mTextView1My.setText(currentItem.getName()); holder.mTextView1My.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.mTextView2My.setVisibility(View.VISIBLE); holder.mTextView2My.setVisibility(View.VISIBLE);
@ -120,7 +198,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_public); holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_public);
} }
holder.repoStarsMy.setText(currentItem.getStars_count()); holder.repoStarsMy.setText(currentItem.getStars_count());
holder.repoWatchersMy.setText(currentItem.getWatchers_count()); holder.repoForksMy.setText(currentItem.getForks_count());
holder.repoOpenIssuesCountMy.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCountMy.setText(currentItem.getOpen_issues_count());
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,91 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
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.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserInfo;
import java.util.List;
/**
* Author M M Arif
*/
public class RepoStargazersAdapter extends BaseAdapter {
private List<UserInfo> stargazersList;
private Context mCtx;
private class ViewHolder {
private ImageView memberAvatar;
private TextView memberName;
ViewHolder(View v) {
memberAvatar = v.findViewById(R.id.memberAvatar);
memberName = v.findViewById(R.id.memberName);
}
}
public RepoStargazersAdapter(Context mCtx, List<UserInfo> membersListMain) {
this.mCtx = mCtx;
this.stargazersList = membersListMain;
}
@Override
public int getCount() {
return stargazersList.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@SuppressLint("InflateParams")
@Override
public View getView(int position, View finalView, ViewGroup parent) {
RepoStargazersAdapter.ViewHolder viewHolder;
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.repo_stargazers_list, null);
viewHolder = new RepoStargazersAdapter.ViewHolder(finalView);
finalView.setTag(viewHolder);
}
else {
viewHolder = (RepoStargazersAdapter.ViewHolder) finalView.getTag();
}
initData(viewHolder, position);
return finalView;
}
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);
if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname());
}
else {
viewHolder.memberName.setText(currentItem.getLogin());
}
}
}

View File

@ -0,0 +1,91 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
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.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserInfo;
import java.util.List;
/**
* Author M M Arif
*/
public class RepoWatchersAdapter extends BaseAdapter {
private List<UserInfo> watchersList;
private Context mCtx;
private class ViewHolder {
private ImageView memberAvatar;
private TextView memberName;
ViewHolder(View v) {
memberAvatar = v.findViewById(R.id.memberAvatar);
memberName = v.findViewById(R.id.memberName);
}
}
public RepoWatchersAdapter(Context mCtx, List<UserInfo> membersListMain) {
this.mCtx = mCtx;
this.watchersList = membersListMain;
}
@Override
public int getCount() {
return watchersList.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@SuppressLint("InflateParams")
@Override
public View getView(int position, View finalView, ViewGroup parent) {
RepoWatchersAdapter.ViewHolder viewHolder;
if (finalView == null) {
finalView = LayoutInflater.from(mCtx).inflate(R.layout.repo_watchers_list, null);
viewHolder = new RepoWatchersAdapter.ViewHolder(finalView);
finalView.setTag(viewHolder);
}
else {
viewHolder = (RepoWatchersAdapter.ViewHolder) finalView.getTag();
}
initData(viewHolder, position);
return finalView;
}
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);
if(!currentItem.getFullname().equals("")) {
viewHolder.memberName.setText(currentItem.getFullname());
}
else {
viewHolder.memberName.setText(currentItem.getLogin());
}
}
}

View File

@ -4,8 +4,11 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter; import android.widget.Filter;
@ -14,10 +17,16 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -39,10 +48,11 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
private TextView fullName; private TextView fullName;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoWatchers; private TextView repoForks;
private TextView repoOpenIssuesCount; private TextView repoOpenIssuesCount;
private ReposViewHolder(View itemView) { private ReposViewHolder(View itemView) {
super(itemView); super(itemView);
mTextView1 = itemView.findViewById(R.id.repoName); mTextView1 = itemView.findViewById(R.id.repoName);
mTextView2 = itemView.findViewById(R.id.repoDescription); mTextView2 = itemView.findViewById(R.id.repoDescription);
@ -50,15 +60,16 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars); repoStars = itemView.findViewById(R.id.repoStars);
repoWatchers = itemView.findViewById(R.id.repoWatchers); repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount); repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
itemView.setOnClickListener(new View.OnClickListener() { itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
TextView repoFullName = (TextView) v.findViewById(R.id.repoFullName); TextView repoFullName = v.findViewById(R.id.repoFullName);
Intent intent = new Intent(context, RepoDetailActivity.class); Intent intent = new Intent(context, RepoDetailActivity.class);
intent.putExtra("repoFullName", repoFullName.getText().toString()); intent.putExtra("repoFullName", repoFullName.getText().toString());
@ -70,6 +81,70 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
} }
}); });
reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext();
Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
PopupMenu popupMenu = new PopupMenu(context_, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
} catch (Exception e) {
popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.repoStargazers:
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
break;
case R.id.repoWatchers:
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
break;
case R.id.repoOpenInBrowser:
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
break;
}
return false;
}
});
popupMenu.show();
}
});
} }
} }
@ -94,19 +169,29 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
String charac = String.valueOf(currentItem.getName().charAt(0)); String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
.useFont(Typeface.DEFAULT) .useFont(Typeface.DEFAULT)
.fontSize(16) .fontSize(18)
.toUpperCase() .toUpperCase()
.width(28) .width(28)
.height(28) .height(28)
.endConfig() .endConfig()
.buildRound(charac, color); .buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) {
Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else {
holder.image.setImageDrawable(drawable);
}
}
else {
holder.image.setImageDrawable(drawable);
}
holder.image.setImageDrawable(drawable);
holder.mTextView1.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
@ -120,7 +205,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public); holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoWatchers.setText(currentItem.getWatchers_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
} }

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter; import android.widget.Filter;
@ -12,13 +13,21 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
/** /**
@ -39,7 +48,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
private TextView fullName; private TextView fullName;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoWatchers; private TextView repoForks;
private TextView repoOpenIssuesCount; private TextView repoOpenIssuesCount;
private OrgReposViewHolder(View itemView) { private OrgReposViewHolder(View itemView) {
@ -50,8 +59,9 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars); repoStars = itemView.findViewById(R.id.repoStars);
repoWatchers = itemView.findViewById(R.id.repoWatchers); repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount); repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
itemView.setOnClickListener(new View.OnClickListener() { itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -70,6 +80,69 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
} }
}); });
reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext();
Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
PopupMenu popupMenu = new PopupMenu(context_, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
} catch (Exception e) {
popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.repoStargazers:
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
break;
case R.id.repoWatchers:
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
break;
case R.id.repoOpenInBrowser:
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
break;
}
return false;
}
});
popupMenu.show();
}
});
} }
} }
@ -95,19 +168,24 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
String charac = String.valueOf(currentItem.getName().charAt(0)); String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
.useFont(Typeface.DEFAULT) .useFont(Typeface.DEFAULT)
.fontSize(16) .fontSize(18)
.toUpperCase() .toUpperCase()
.width(28) .width(28)
.height(28) .height(28)
.endConfig() .endConfig()
.buildRound(charac, color); .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.image);
} else {
holder.image.setImageDrawable(drawable);
}
holder.image.setImageDrawable(drawable);
holder.mTextView1.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
@ -121,7 +199,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public); holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoWatchers.setText(currentItem.getWatchers_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
} }

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter; import android.widget.Filter;
@ -12,13 +13,21 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
/** /**
@ -39,7 +48,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
private TextView fullName; private TextView fullName;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoWatchers; private TextView repoForks;
private TextView repoOpenIssuesCount; private TextView repoOpenIssuesCount;
private StarredReposViewHolder(View itemView) { private StarredReposViewHolder(View itemView) {
@ -50,8 +59,9 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars); repoStars = itemView.findViewById(R.id.repoStars);
repoWatchers = itemView.findViewById(R.id.repoWatchers); repoForks = itemView.findViewById(R.id.repoForks);
repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount); repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
itemView.setOnClickListener(new View.OnClickListener() { itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -70,6 +80,69 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
} }
}); });
reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext();
Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
PopupMenu popupMenu = new PopupMenu(context_, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
} catch (Exception e) {
popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.repoStargazers:
Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent);
break;
case R.id.repoWatchers:
Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW);
break;
case R.id.repoOpenInBrowser:
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText());
context.startActivity(intentOpenInBrowser);
break;
}
return false;
}
});
popupMenu.show();
}
});
} }
} }
@ -95,19 +168,24 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
String charac = String.valueOf(currentItem.getName().charAt(0)); String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
.useFont(Typeface.DEFAULT) .useFont(Typeface.DEFAULT)
.fontSize(16) .fontSize(18)
.toUpperCase() .toUpperCase()
.width(28) .width(28)
.height(28) .height(28)
.endConfig() .endConfig()
.buildRound(charac, color); .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.image);
} else {
holder.image.setImageDrawable(drawable);
}
holder.image.setImageDrawable(drawable);
holder.mTextView1.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.mTextView2.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
@ -121,7 +199,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
holder.repoPrivatePublic.setImageResource(R.drawable.ic_public); holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoWatchers.setText(currentItem.getWatchers_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
} }

View File

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

View File

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

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -125,7 +125,7 @@ public class BranchesFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
BranchesViewModel branchesModel = ViewModelProviders.of(this).get(BranchesViewModel.class); BranchesViewModel branchesModel = new ViewModelProvider(this).get(BranchesViewModel.class);
branchesModel.getBranchesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Branches>>() { branchesModel.getBranchesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Branches>>() {
@Override @Override

View File

@ -263,6 +263,7 @@ public class ClosedIssuesFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;

View File

@ -6,11 +6,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.GridView; import android.widget.GridView;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.adapters.CollaboratorsAdapter; import org.mian.gitnex.adapters.CollaboratorsAdapter;
@ -26,6 +27,7 @@ import java.util.List;
public class CollaboratorsFragment extends Fragment { public class CollaboratorsFragment extends Fragment {
private ProgressBar mProgressBar;
private CollaboratorsAdapter adapter; private CollaboratorsAdapter adapter;
private GridView mGridView; private GridView mGridView;
private TextView noDataCollaborators; private TextView noDataCollaborators;
@ -69,6 +71,8 @@ public class CollaboratorsFragment extends Fragment {
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
noDataCollaborators = v.findViewById(R.id.noDataCollaborators); noDataCollaborators = v.findViewById(R.id.noDataCollaborators);
mProgressBar = v.findViewById(R.id.progress_bar);
mGridView = v.findViewById(R.id.gridView); mGridView = v.findViewById(R.id.gridView);
fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
@ -94,7 +98,7 @@ public class CollaboratorsFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
CollaboratorsViewModel collaboratorsModel = ViewModelProviders.of(this).get(CollaboratorsViewModel.class); CollaboratorsViewModel collaboratorsModel = new ViewModelProvider(this).get(CollaboratorsViewModel.class);
collaboratorsModel.getCollaboratorsList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Collaborators>>() { collaboratorsModel.getCollaboratorsList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Collaborators>>() {
@Override @Override
@ -109,6 +113,7 @@ public class CollaboratorsFragment extends Fragment {
mGridView.setAdapter(adapter); mGridView.setAdapter(adapter);
noDataCollaborators.setVisibility(View.VISIBLE); noDataCollaborators.setVisibility(View.VISIBLE);
} }
mProgressBar.setVisibility(View.GONE);
} }
}); });

View File

@ -262,6 +262,7 @@ public class IssuesFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -142,7 +142,7 @@ public class LabelsFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
LabelsViewModel labelsModel = ViewModelProviders.of(this).get(LabelsViewModel.class); LabelsViewModel labelsModel = new ViewModelProvider(this).get(LabelsViewModel.class);
labelsModel.getLabelsList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Labels>>() { labelsModel.getLabelsList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Labels>>() {
@Override @Override

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -81,7 +81,7 @@ public class MembersByOrgFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) {
MembersByOrgViewModel membersModel = ViewModelProviders.of(this).get(MembersByOrgViewModel.class); MembersByOrgViewModel membersModel= new ViewModelProvider(this).get(MembersByOrgViewModel.class);
membersModel.getMembersList(instanceUrl, instanceToken, owner).observe(this, new Observer<List<UserInfo>>() { membersModel.getMembersList(instanceUrl, instanceToken, owner).observe(this, new Observer<List<UserInfo>>() {
@Override @Override
@ -112,6 +112,7 @@ public class MembersByOrgFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;
@ -125,7 +126,9 @@ public class MembersByOrgFragment extends Fragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText); if(mGridView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false; return false;
} }
}); });

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -46,6 +46,7 @@ public class MilestonesFragment extends Fragment {
private String repoName; private String repoName;
private String repoOwner; private String repoOwner;
private String msState = "all";
private OnFragmentInteractionListener mListener; private OnFragmentInteractionListener mListener;
@ -103,7 +104,7 @@ public class MilestonesFragment extends Fragment {
@Override @Override
public void run() { public void run() {
swipeRefresh.setRefreshing(false); swipeRefresh.setRefreshing(false);
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, msState);
} }
}, 50); }, 50);
} }
@ -127,7 +128,7 @@ public class MilestonesFragment extends Fragment {
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("milestoneCreated")) { if(tinyDb.getBoolean("milestoneCreated")) {
MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, msState);
tinyDb.putBoolean("milestoneCreated", false); tinyDb.putBoolean("milestoneCreated", false);
} }
} }
@ -150,9 +151,9 @@ public class MilestonesFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
MilestonesViewModel msModel = ViewModelProviders.of(this).get(MilestonesViewModel.class); MilestonesViewModel msModel = new ViewModelProvider(this).get(MilestonesViewModel.class);
msModel.getMilestonesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Milestones>>() { msModel.getMilestonesList(instanceUrl, instanceToken, owner, repo, msState).observe(this, new Observer<List<Milestones>>() {
@Override @Override
public void onChanged(@Nullable List<Milestones> msListMain) { public void onChanged(@Nullable List<Milestones> msListMain) {
adapter = new MilestonesAdapter(getContext(), msListMain); adapter = new MilestonesAdapter(getContext(), msListMain);
@ -182,6 +183,7 @@ public class MilestonesFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;
@ -195,7 +197,9 @@ public class MilestonesFragment extends Fragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText); if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false; return false;
} }
}); });

View File

@ -7,7 +7,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -171,7 +171,7 @@ public class MyRepositoriesFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String username) { private void fetchDataAsync(String instanceUrl, String instanceToken, String username) {
MyRepositoriesViewModel myRepoModel = ViewModelProviders.of(this).get(MyRepositoriesViewModel.class); MyRepositoriesViewModel myRepoModel = new ViewModelProvider(this).get(MyRepositoriesViewModel.class);
myRepoModel.getCurrentUserRepositories(instanceUrl, instanceToken, username).observe(this, new Observer<List<UserRepositories>>() { myRepoModel.getCurrentUserRepositories(instanceUrl, instanceToken, username).observe(this, new Observer<List<UserRepositories>>() {
@Override @Override
@ -203,6 +203,7 @@ public class MyRepositoriesFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;
@ -216,7 +217,9 @@ public class MyRepositoriesFragment extends Fragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText); if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false; return false;
} }
}); });

View File

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

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -141,7 +141,7 @@ public class OrganizationsFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken) { private void fetchDataAsync(String instanceUrl, String instanceToken) {
OrganizationListViewModel orgModel = ViewModelProviders.of(this).get(OrganizationListViewModel.class); OrganizationListViewModel orgModel = new ViewModelProvider(this).get(OrganizationListViewModel.class);
orgModel.getUserOrgs(instanceUrl, instanceToken).observe(this, new Observer<List<UserOrganizations>>() { orgModel.getUserOrgs(instanceUrl, instanceToken).observe(this, new Observer<List<UserOrganizations>>() {
@Override @Override
@ -173,6 +173,7 @@ public class OrganizationsFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;
@ -186,7 +187,9 @@ public class OrganizationsFragment extends Fragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText); if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false; return false;
} }
}); });

View File

@ -5,7 +5,7 @@ import android.os.Bundle;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -109,7 +109,7 @@ public class ProfileEmailsFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken) { private void fetchDataAsync(String instanceUrl, String instanceToken) {
ProfileEmailsViewModel profileEmailModel = ViewModelProviders.of(this).get(ProfileEmailsViewModel.class); ProfileEmailsViewModel profileEmailModel = new ViewModelProvider(this).get(ProfileEmailsViewModel.class);
profileEmailModel.getEmailsList(instanceUrl, instanceToken).observe(this, new Observer<List<Emails>>() { profileEmailModel.getEmailsList(instanceUrl, instanceToken).observe(this, new Observer<List<Emails>>() {
@Override @Override

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -108,7 +108,7 @@ public class ProfileFollowersFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken) { private void fetchDataAsync(String instanceUrl, String instanceToken) {
ProfileFollowersViewModel pfModel = ViewModelProviders.of(this).get(ProfileFollowersViewModel.class); ProfileFollowersViewModel pfModel = new ViewModelProvider(this).get(ProfileFollowersViewModel.class);
pfModel.getFollowersList(instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() { pfModel.getFollowersList(instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
@Override @Override

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -108,7 +108,7 @@ public class ProfileFollowingFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken) { private void fetchDataAsync(String instanceUrl, String instanceToken) {
ProfileFollowingViewModel pfModel = ViewModelProviders.of(this).get(ProfileFollowingViewModel.class); ProfileFollowingViewModel pfModel = new ViewModelProvider(this).get(ProfileFollowingViewModel.class);
pfModel.getFollowingList(instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() { pfModel.getFollowingList(instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
@Override @Override

View File

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

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -141,7 +141,7 @@ public class ReleasesFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
ReleasesViewModel releasesModel = ViewModelProviders.of(this).get(ReleasesViewModel.class); ReleasesViewModel releasesModel = new ViewModelProvider(this).get(ReleasesViewModel.class);
releasesModel.getReleasesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Releases>>() { releasesModel.getReleasesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Releases>>() {
@Override @Override

View File

@ -8,6 +8,7 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.util.TinyDB;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -24,11 +25,15 @@ public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.repo_bottom_sheet_layout, container, false); View v = inflater.inflate(R.layout.repo_bottom_sheet_layout, container, false);
final TinyDB tinyDb = new TinyDB(getContext());
TextView createLabel = v.findViewById(R.id.createLabel); TextView createLabel = v.findViewById(R.id.createLabel);
TextView createIssue = v.findViewById(R.id.createNewIssue); TextView createIssue = v.findViewById(R.id.createNewIssue);
TextView createMilestone = v.findViewById(R.id.createNewMilestone); TextView createMilestone = v.findViewById(R.id.createNewMilestone);
TextView addCollaborator = v.findViewById(R.id.addCollaborator); TextView addCollaborator = v.findViewById(R.id.addCollaborator);
TextView createRelease = v.findViewById(R.id.createRelease); TextView createRelease = v.findViewById(R.id.createRelease);
TextView openWebRepo = v.findViewById(R.id.openWebRepo);
TextView newFile = v.findViewById(R.id.newFile);
createLabel.setOnClickListener(new View.OnClickListener() { createLabel.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -38,13 +43,19 @@ public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
} }
}); });
createIssue.setOnClickListener(new View.OnClickListener() { if(tinyDb.getBoolean("hasIssues")) {
@Override createIssue.setVisibility(View.VISIBLE);
public void onClick(View v) { createIssue.setOnClickListener(new View.OnClickListener() {
bmListener.onButtonClicked("newIssue"); @Override
dismiss(); public void onClick(View v) {
} bmListener.onButtonClicked("newIssue");
}); dismiss();
}
});
}
else {
createIssue.setVisibility(View.GONE);
}
createMilestone.setOnClickListener(new View.OnClickListener() { createMilestone.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -70,6 +81,22 @@ public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
} }
}); });
openWebRepo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("openWebRepo");
dismiss();
}
});
newFile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("newFile");
dismiss();
}
});
return v; return v;
} }

View File

@ -1,26 +1,31 @@
package org.mian.gitnex.fragments; package org.mian.gitnex.fragments;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import okhttp3.OkHttpClient; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.AsyncDrawable;
import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import ru.noties.markwon.AbstractMarkwonPlugin; import android.text.Spanned;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import ru.noties.markwon.ext.tables.TablePlugin;
import ru.noties.markwon.ext.tables.TableTheme;
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
import ru.noties.markwon.html.HtmlPlugin;
import ru.noties.markwon.image.ImagesPlugin;
import ru.noties.markwon.image.gif.GifPlugin;
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -42,6 +47,8 @@ import org.mian.gitnex.util.TinyDB;
import org.ocpsoft.prettytime.PrettyTime; import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
@ -208,6 +215,8 @@ public class RepoInfoFragment extends Fragment {
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) { private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) {
final TinyDB tinyDb = new TinyDB(getContext());
Call<UserRepositories> call = RetrofitClient Call<UserRepositories> call = RetrofitClient
.getInstance(instanceUrl) .getInstance(instanceUrl)
.getApiInterface() .getApiInterface()
@ -220,53 +229,59 @@ public class RepoInfoFragment extends Fragment {
UserRepositories repoInfo = response.body(); UserRepositories repoInfo = response.body();
if (response.isSuccessful()) { if (isAdded()) {
if (response.code() == 200) { if (response.isSuccessful()) {
assert repoInfo != null; if (response.code() == 200) {
repoNameInfo.setText(repoInfo.getName());
repoOwnerInfo.setText(owner);
repoDescriptionInfo.setText(repoInfo.getDescription());
repoWebsiteInfo.setText(repoInfo.getWebsite());
repoSizeInfo.setText(AppUtil.formatFileSize(repoInfo.getSize()));
repoDefaultBranchInfo.setText(repoInfo.getDefault_branch());
repoSshUrlInfo.setText(repoInfo.getSsh_url());
repoCloneUrlInfo.setText(repoInfo.getClone_url());
repoRepoUrlInfo.setText(repoInfo.getHtml_url());
repoForksCountInfo.setText(repoInfo.getForks_count());
switch (timeFormat) { assert repoInfo != null;
case "pretty": { repoNameInfo.setText(repoInfo.getName());
PrettyTime prettyTime = new PrettyTime(new Locale(locale)); repoOwnerInfo.setText(owner);
String createdTime = prettyTime.format(repoInfo.getCreated_at()); repoDescriptionInfo.setText(repoInfo.getDescription());
repoCreatedAtInfo.setText(createdTime); repoWebsiteInfo.setText(repoInfo.getWebsite());
repoCreatedAtInfo.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), getContext())); repoSizeInfo.setText(AppUtil.formatFileSize(repoInfo.getSize()));
break; repoDefaultBranchInfo.setText(repoInfo.getDefault_branch());
} repoSshUrlInfo.setText(repoInfo.getSsh_url());
case "normal": { repoCloneUrlInfo.setText(repoInfo.getClone_url());
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale)); repoRepoUrlInfo.setText(repoInfo.getHtml_url());
String createdTime = formatter.format(repoInfo.getCreated_at()); repoForksCountInfo.setText(repoInfo.getForks_count());
repoCreatedAtInfo.setText(createdTime);
break; tinyDb.putBoolean("hasIssues", repoInfo.getHas_issues());
}
case "normal1": { switch (timeFormat) {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale)); case "pretty": {
String createdTime = formatter.format(repoInfo.getCreated_at()); PrettyTime prettyTime = new PrettyTime(new Locale(locale));
repoCreatedAtInfo.setText(createdTime); String createdTime = prettyTime.format(repoInfo.getCreated_at());
break; repoCreatedAtInfo.setText(createdTime);
repoCreatedAtInfo.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), getContext()));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(repoInfo.getCreated_at());
repoCreatedAtInfo.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(repoInfo.getCreated_at());
repoCreatedAtInfo.setText(createdTime);
break;
}
} }
mProgressBar.setVisibility(View.GONE);
pageContent.setVisibility(View.VISIBLE);
} }
mProgressBar.setVisibility(View.GONE); }
pageContent.setVisibility(View.VISIBLE); else {
Log.e("onFailure", String.valueOf(response.code()));
} }
} }
else {
Log.e("onFailure", String.valueOf(response.code()));
}
} }
@ -292,12 +307,51 @@ public class RepoInfoFragment extends Fragment {
@Override @Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
if (response.code() == 200) { if (isAdded()) {
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext())) if (response.code() == 200) {
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext()))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
.usePlugin(ImagesPlugin.createWithAssets(getContext())) @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 = getContext().getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
getContext().getPackageName());
final Drawable drawable = getContext().getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
}
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(getContext().getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getContext().getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
}))
.usePlugin(new AbstractMarkwonPlugin() { .usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) { public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
@ -310,40 +364,39 @@ public class RepoInfoFragment extends Fragment {
.usePlugin(TablePlugin.create(getContext())) .usePlugin(TablePlugin.create(getContext()))
.usePlugin(TaskListPlugin.create(getContext())) .usePlugin(TaskListPlugin.create(getContext()))
.usePlugin(HtmlPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(GifPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build(); .build();
CharSequence bodyWithMD = null; Spanned bodyWithMD = null;
if (response.body() != null) { if (response.body() != null) {
bodyWithMD = markwon.toMarkdown(response.body()); bodyWithMD = markwon.toMarkdown(response.body());
}
assert bodyWithMD != null;
markwon.setParsedMarkdown(repoFileContents, bodyWithMD);
} 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) {
fileContentsFrameHeader.setVisibility(View.GONE);
fileContentsFrame.setVisibility(View.GONE);
} else {
Toasty.info(getContext(), getString(R.string.genericError));
} }
repoFileContents.setText(bodyWithMD);
}
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) {
fileContentsFrameHeader.setVisibility(View.GONE);
fileContentsFrame.setVisibility(View.GONE);
}
else {
Toasty.info(getContext(), getString(R.string.genericError));
} }
} }

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -123,7 +123,7 @@ public class RepositoriesByOrgFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) {
RepositoriesByOrgViewModel orgRepoModel = ViewModelProviders.of(this).get(RepositoriesByOrgViewModel.class); RepositoriesByOrgViewModel orgRepoModel = new ViewModelProvider(this).get(RepositoriesByOrgViewModel.class);
orgRepoModel.getRepositoriesByOrg(instanceUrl, instanceToken, owner).observe(this, new Observer<List<UserRepositories>>() { orgRepoModel.getRepositoriesByOrg(instanceUrl, instanceToken, owner).observe(this, new Observer<List<UserRepositories>>() {
@Override @Override
@ -155,6 +155,7 @@ public class RepositoriesByOrgFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;
@ -168,7 +169,9 @@ public class RepositoriesByOrgFragment extends Fragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText); if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false; return false;
} }
}); });

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -144,7 +144,7 @@ public class RepositoriesFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken) { private void fetchDataAsync(String instanceUrl, String instanceToken) {
RepositoriesListViewModel repoModel = ViewModelProviders.of(this).get(RepositoriesListViewModel.class); RepositoriesListViewModel repoModel = new ViewModelProvider(this).get(RepositoriesListViewModel.class);
repoModel.getUserRepositories(instanceUrl, instanceToken).observe(this, new Observer<List<UserRepositories>>() { repoModel.getUserRepositories(instanceUrl, instanceToken).observe(this, new Observer<List<UserRepositories>>() {
@Override @Override
@ -176,6 +176,7 @@ public class RepositoriesFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;
@ -189,7 +190,9 @@ public class RepositoriesFragment extends Fragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText); if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false; return false;
} }
}); });

View File

@ -185,10 +185,6 @@ public class SettingsFragment extends Fragment {
tinyDb.putInt("codeBlockId", i); tinyDb.putInt("codeBlockId", i);
switch (codeBlockList[i]) { switch (codeBlockList[i]) {
case "Green - Black":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break;
case "White - Black": case "White - Black":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white)); tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
@ -248,9 +244,6 @@ public class SettingsFragment extends Fragment {
tinyDb.putInt("langId", i); tinyDb.putInt("langId", i);
switch (langList[i]) { switch (langList[i]) {
case "English":
tinyDb.putString("locale", "en");
break;
case "French": case "French":
tinyDb.putString("locale", "fr"); tinyDb.putString("locale", "fr");
break; break;
@ -309,16 +302,10 @@ public class SettingsFragment extends Fragment {
tinyDb.putString("timeStr", timeList[i]); tinyDb.putString("timeStr", timeList[i]);
tinyDb.putInt("timeId", i); tinyDb.putInt("timeId", i);
switch (timeList[i]) { if ("Normal".equals(timeList[i])) {
case "Pretty": tinyDb.putString("dateFormat", "normal");
tinyDb.putString("dateFormat", "pretty"); } else {
break; tinyDb.putString("dateFormat", "pretty");
case "Normal":
tinyDb.putString("dateFormat", "normal");
break;
default:
tinyDb.putString("dateFormat", "pretty");
break;
} }
dialogInterfaceTime.dismiss(); dialogInterfaceTime.dismiss();

View File

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

View File

@ -7,7 +7,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -166,7 +166,7 @@ public class StarredRepositoriesFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken) { private void fetchDataAsync(String instanceUrl, String instanceToken) {
StarredRepositoriesViewModel starredRepoModel = ViewModelProviders.of(this).get(StarredRepositoriesViewModel.class); StarredRepositoriesViewModel starredRepoModel = new ViewModelProvider(this).get(StarredRepositoriesViewModel.class);
starredRepoModel.getUserStarredRepositories(instanceUrl, instanceToken).observe(this, new Observer<List<UserRepositories>>() { starredRepoModel.getUserStarredRepositories(instanceUrl, instanceToken).observe(this, new Observer<List<UserRepositories>>() {
@Override @Override
@ -198,6 +198,7 @@ public class StarredRepositoriesFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;
@ -211,7 +212,9 @@ public class StarredRepositoriesFragment extends Fragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText); if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false; return false;
} }
}); });

View File

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -124,7 +124,7 @@ public class TeamsByOrgFragment extends Fragment {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) {
TeamsByOrgViewModel teamModel = ViewModelProviders.of(this).get(TeamsByOrgViewModel.class); TeamsByOrgViewModel teamModel = new ViewModelProvider(this).get(TeamsByOrgViewModel.class);
teamModel.getTeamsByOrg(instanceUrl, instanceToken, owner).observe(this, new Observer<List<Teams>>() { teamModel.getTeamsByOrg(instanceUrl, instanceToken, owner).observe(this, new Observer<List<Teams>>() {
@Override @Override
@ -156,6 +156,7 @@ public class TeamsByOrgFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint(getContext().getString(R.string.strFilter));
if(!connToInternet) { if(!connToInternet) {
return; return;
@ -169,7 +170,9 @@ public class TeamsByOrgFragment extends Fragment {
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText); if(mRecyclerView.getAdapter() != null) {
adapter.getFilter().filter(newText);
}
return false; return false;
} }
}); });

View File

@ -3,6 +3,7 @@ package org.mian.gitnex.interfaces;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.models.AddEmail; import org.mian.gitnex.models.AddEmail;
import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.NewFile;
import org.mian.gitnex.models.UpdateIssueAssignee; import org.mian.gitnex.models.UpdateIssueAssignee;
import org.mian.gitnex.models.UpdateIssueState; import org.mian.gitnex.models.UpdateIssueState;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
@ -98,7 +99,7 @@ public interface ApiInterface {
Call<Issues> replyCommentToIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex, @Body Issues jsonStr); Call<Issues> replyCommentToIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex, @Body Issues jsonStr);
@GET("repos/{owner}/{repo}/milestones") // get milestones by repo @GET("repos/{owner}/{repo}/milestones") // get milestones by repo
Call<List<Milestones>> getMilestones(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName); Call<List<Milestones>> getMilestones(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Query("state") String state);
@GET("repos/{owner}/{repo}/branches") // get branches @GET("repos/{owner}/{repo}/branches") // get branches
Call<List<Branches>> getBranches(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName); Call<List<Branches>> getBranches(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@ -204,4 +205,13 @@ public interface ApiInterface {
@GET("admin/users") // get all users @GET("admin/users") // get all users
Call<List<UserInfo>> adminGetUsers(@Header("Authorization") String token); Call<List<UserInfo>> adminGetUsers(@Header("Authorization") String token);
@GET("repos/{owner}/{repo}/stargazers") // get all repo stars
Call<List<UserInfo>> getRepoStargazers(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@GET("repos/{owner}/{repo}/subscribers") // get all repo watchers
Call<List<UserInfo>> getRepoWatchers(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
@POST("repos/{owner}/{repo}/contents/{file}") // create new file
Call<JsonElement> createNewFile(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("file") String fileName, @Body NewFile jsonStr);
} }

View File

@ -0,0 +1,99 @@
package org.mian.gitnex.models;
/**
* Author M M Arif
*/
public class NewFile {
private String branch;
private String content;
private String message;
private String new_branch;
private authorObject author;
private committerObject committer;
public String getBranch() {
return branch;
}
public void setBranch(String branch) {
this.branch = branch;
}
public String getContents() {
return content;
}
public void setContents(String contents) {
this.content = contents;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getNew_branch() {
return new_branch;
}
public void setNew_branch(String new_branch) {
this.new_branch = new_branch;
}
public class authorObject {
private String email;
private String name;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class committerObject {
private String email;
private String name;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public NewFile(String branch, String content, String message, String new_branch) {
this.branch = branch;
this.content = content;
this.message = message;
this.new_branch = new_branch;
}
}

View File

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

View File

@ -7,9 +7,11 @@ import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.util.Base64;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Locale; import java.util.Locale;
@ -77,6 +79,10 @@ public class AppUtil {
return str.matches("^[\\w.-]+$"); return str.matches("^[\\w.-]+$");
} }
public Boolean checkStringsWithDash(String str) { // [a-zA-Z0-9-_. ]
return str.matches("^[\\w-]+$");
}
public Boolean checkIntegers(String str) { public Boolean checkIntegers(String str) {
return str.matches("\\d+"); return str.matches("\\d+");
} }
@ -180,4 +186,28 @@ public class AppUtil {
} }
public String encodeBase64(String str) {
String base64Str = str;
if(!str.equals("")) {
byte[] data = str.getBytes(StandardCharsets.UTF_8);
base64Str = Base64.encodeToString(data, Base64.DEFAULT);
}
return base64Str;
}
public String decodeBase64(String str) {
String base64Str = str;
if(!str.equals("")) {
byte[] data = Base64.decode(base64Str, Base64.DEFAULT);
base64Str = new String(data, StandardCharsets.UTF_8);
}
return base64Str;
}
} }

View File

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

View File

@ -0,0 +1,60 @@
package org.mian.gitnex.viewmodels;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.models.UserInfo;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class RepoStargazersViewModel extends ViewModel {
private static MutableLiveData<List<UserInfo>> stargazersList;
public LiveData<List<UserInfo>> getRepoStargazers(String instanceUrl, String token, String repoOwner, String repoName) {
stargazersList = new MutableLiveData<>();
loadRepoStargazers(instanceUrl, token, repoOwner, repoName);
return stargazersList;
}
public static void loadRepoStargazers(String instanceUrl, String token, String repoOwner, String repoName) {
Call<List<UserInfo>> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getRepoStargazers(token, repoOwner, repoName);
call.enqueue(new Callback<List<UserInfo>>() {
@Override
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
stargazersList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserInfo>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

@ -0,0 +1,60 @@
package org.mian.gitnex.viewmodels;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.models.UserInfo;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class RepoWatchersViewModel extends ViewModel {
private static MutableLiveData<List<UserInfo>> watchersList;
public LiveData<List<UserInfo>> getRepoWatchers(String instanceUrl, String token, String repoOwner, String repoName) {
watchersList = new MutableLiveData<>();
loadRepoWatchers(instanceUrl, token, repoOwner, repoName);
return watchersList;
}
public static void loadRepoWatchers(String instanceUrl, String token, String repoOwner, String repoName) {
Call<List<UserInfo>> call = RetrofitClient
.getInstance(instanceUrl)
.getApiInterface()
.getRepoWatchers(token, repoOwner, repoName);
call.enqueue(new Callback<List<UserInfo>>() {
@Override
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
watchersList.postValue(response.body());
}
}
}
@Override
public void onFailure(@NonNull Call<List<UserInfo>> call, Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6L6,2zM13,9L13,3.5L18.5,9L13,9z"/>
</vector>

View File

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

View File

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

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h4v-2L5,18L5,8h14v10h-4v2h4c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.89,-2 -2,-2zM12,10l-4,4h3v6h2v-6h3l-4,-4z"/>
</vector>

View File

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

View File

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

Binary file not shown.

Binary file not shown.

View File

@ -10,7 +10,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -72,7 +71,7 @@
android:textSize="20sp" android:textSize="20sp"
android:visibility="gone" /> android:visibility="gone" />
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" <ProgressBar
android:id="@+id/progress_bar" android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar" style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -10,8 +10,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -11,8 +11,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -44,10 +42,8 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <ScrollView
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/backgroundColor"> android:background="@color/backgroundColor">
<LinearLayout <LinearLayout

View File

@ -11,8 +11,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -44,10 +42,8 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <ScrollView
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/backgroundColor"> android:background="@color/backgroundColor">
<LinearLayout <LinearLayout

View File

@ -10,8 +10,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -43,10 +41,8 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <ScrollView
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/backgroundColor"> android:background="@color/backgroundColor">
<LinearLayout <LinearLayout

View File

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

View File

@ -8,7 +8,6 @@
android:gravity="center"> android:gravity="center">
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
@ -62,7 +61,6 @@
android:padding="10dp" android:padding="10dp"
android:textSize="14sp" android:textSize="14sp"
tools:ignore="Autofill" tools:ignore="Autofill"
android:labelFor="@+id/instance_url"
android:background="@drawable/shape_inputs" android:background="@drawable/shape_inputs"
android:drawableStart="@drawable/ic_link_24dp" android:drawableStart="@drawable/ic_link_24dp"
android:drawablePadding="10dp" android:drawablePadding="10dp"
@ -80,7 +78,6 @@
android:padding="10dp" android:padding="10dp"
android:textSize="14sp" android:textSize="14sp"
tools:ignore="Autofill" tools:ignore="Autofill"
android:labelFor="@+id/login_uid"
android:background="@drawable/shape_inputs" android:background="@drawable/shape_inputs"
android:drawableStart="@drawable/ic_person_24dp" android:drawableStart="@drawable/ic_person_24dp"
android:drawablePadding="10dp" android:drawablePadding="10dp"
@ -98,7 +95,6 @@
android:padding="10dp" android:padding="10dp"
android:textSize="14sp" android:textSize="14sp"
tools:ignore="Autofill" tools:ignore="Autofill"
android:labelFor="@+id/login_passwd"
android:background="@drawable/shape_inputs" android:background="@drawable/shape_inputs"
android:drawableStart="@drawable/ic_lock_24dp" android:drawableStart="@drawable/ic_lock_24dp"
android:drawablePadding="10dp" android:drawablePadding="10dp"
@ -116,7 +112,6 @@
android:padding="10dp" android:padding="10dp"
android:textSize="14sp" android:textSize="14sp"
tools:ignore="Autofill" tools:ignore="Autofill"
android:labelFor="@+id/otpCode"
android:background="@drawable/shape_inputs" android:background="@drawable/shape_inputs"
android:drawableStart="@drawable/ic_otp" android:drawableStart="@drawable/ic_otp"
android:drawablePadding="10dp" android:drawablePadding="10dp"

View File

@ -0,0 +1,229 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/colorPrimary">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
tools:ignore="UnusedAttribute">
<ImageView
android:id="@+id/close"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="15dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:contentDescription="@string/close"
android:src="@drawable/ic_close" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/pageTitleNewFile"
android:textColor="@color/white"
android:maxLines="1"
android:textSize="20sp" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:paddingBottom="30dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/newFileNameTintCopy"
android:textColor="@color/colorWhite"
android:textSize="16sp" />
<EditText
android:id="@+id/newFileName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="10dp"
android:textSize="14sp"
tools:ignore="Autofill"
android:labelFor="@+id/newFileName"
android:background="@drawable/shape_inputs"
android:textColor="@color/colorWhite"
android:textColorHint="@color/colorWhite"
android:inputType="textCapSentences|text"
android:textColorHighlight="@color/colorWhite"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/newFileNameHintMessage"
android:textColor="@color/hintColor"
android:textSize="12sp"
android:paddingStart="10dp"
android:paddingEnd="5dp"
android:gravity="end" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/newFileContentTintCopy"
android:textColor="@color/colorWhite"
android:textSize="16sp"
android:layout_marginTop="10dp" />
<EditText
android:id="@+id/newFileContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="10dp"
android:background="@drawable/shape_inputs"
android:maxLines="16"
android:minLines="14"
tools:ignore="Autofill"
android:labelFor="@+id/newFileContent"
android:scrollbars="vertical"
android:gravity="top|start"
android:textSize="14sp"
android:textColor="@color/colorWhite"
android:textColorHint="@color/colorWhite"
android:inputType="textCapSentences|textMultiLine"
android:textColorHighlight="@color/colorWhite"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/newFileOldBranches"
android:textColor="@color/colorWhite"
android:textSize="16sp"
android:layout_marginTop="10dp"/>
<Spinner
android:id="@+id/newFileBranchesSpinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:spinnerMode="dropdown"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingStart="5dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/newFileCurrentBranchMessage"
android:textColor="@color/hintColor"
android:textSize="12sp"
android:paddingStart="10dp"
android:paddingEnd="5dp"
android:gravity="end" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/newFileBranchTintCopy"
android:textColor="@color/colorWhite"
android:textSize="16sp"
android:layout_marginTop="10dp" />
<EditText
android:id="@+id/newFileBranchName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="10dp"
android:textSize="14sp"
tools:ignore="Autofill"
android:labelFor="@+id/newFileBranchName"
android:background="@drawable/shape_inputs"
android:textColor="@color/colorWhite"
android:textColorHint="@color/colorWhite"
android:inputType="textCapSentences|text"
android:textColorHighlight="@color/colorWhite"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/newFileNewBranchMessage"
android:textColor="@color/hintColor"
android:textSize="12sp"
android:paddingStart="10dp"
android:paddingEnd="5dp"
android:gravity="end" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/newFileMessageTintCopy"
android:textColor="@color/colorWhite"
android:textSize="16sp"
android:layout_marginTop="10dp" />
<EditText
android:id="@+id/newFileCommitMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="10dp"
android:textSize="14sp"
tools:ignore="Autofill"
android:labelFor="@+id/newFileCommitMessage"
android:background="@drawable/shape_inputs"
android:textColor="@color/colorWhite"
android:textColorHint="@color/colorWhite"
android:inputType="textCapSentences|text"
android:textColorHighlight="@color/colorWhite"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/characters255Limit"
android:textColor="@color/hintColor"
android:textSize="12sp"
android:paddingStart="10dp"
android:paddingEnd="5dp"
android:gravity="end" />
<Button
android:id="@+id/newFileCreate"
android:gravity="center"
android:layout_gravity="end"
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:width="140dp"
android:text="@string/newFileButtonCopy"
android:background="@drawable/shape_buttons"
android:textColor="@color/btnTextColor" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -12,7 +12,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -48,7 +47,6 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/backgroundColor"> android:background="@color/backgroundColor">
<LinearLayout <LinearLayout

View File

@ -10,8 +10,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
tools:ignore="UnusedAttribute">
<ImageView
android:id="@+id/close"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="15dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:contentDescription="@string/close"
android:src="@drawable/ic_close" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="@color/white"
android:maxLines="1"
android:textSize="20sp" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:horizontalSpacing="10dp"
android:numColumns="4"
android:columnWidth="80dp"
android:stretchMode="columnWidth"
android:gravity="center"/>
<TextView
android:id="@+id/noDataStargazers"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:gravity="center"
android:text="@string/noDataFound"
android:textColor="@color/white"
android:textSize="20sp"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible" />
</LinearLayout>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
tools:ignore="UnusedAttribute">
<ImageView
android:id="@+id/close"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="15dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:contentDescription="@string/close"
android:src="@drawable/ic_close" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="@color/white"
android:maxLines="1"
android:textSize="20sp" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:horizontalSpacing="10dp"
android:numColumns="4"
android:columnWidth="80dp"
android:stretchMode="columnWidth"
android:gravity="center"/>
<TextView
android:id="@+id/noDataWatchers"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:gravity="center"
android:text="@string/noDataFound"
android:textColor="@color/white"
android:textSize="20sp"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible" />
</LinearLayout>

View File

@ -10,8 +10,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -44,7 +42,6 @@
<ScrollView android:layout_width="match_parent" <ScrollView android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/backgroundColor"> android:background="@color/backgroundColor">
<LinearLayout <LinearLayout
@ -76,6 +73,18 @@
android:text="@string/liberaPaySponsorsFabian" android:text="@string/liberaPaySponsorsFabian"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="16sp" android:textSize="16sp"
android:layout_marginBottom="10dp"
android:textColorLink="@color/lightBlue"
/>
<TextView
android:id="@+id/liberaPaySponsorsThomas"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/liberaPaySponsorsThomas"
android:textColor="@color/white"
android:textSize="16sp"
android:layout_marginBottom="10dp"
android:textColorLink="@color/lightBlue" android:textColorLink="@color/lightBlue"
/> />

View File

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

View File

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

View File

@ -6,14 +6,12 @@
android:id="@+id/relativeLayoutMainFrame" android:id="@+id/relativeLayoutMainFrame"
android:background="@color/backgroundColor"> android:background="@color/backgroundColor">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingStart="15dp" android:paddingBottom="5dp"
android:paddingEnd="15dp"
android:paddingTop="10dp"
android:paddingBottom="15dp"
android:id="@+id/branchesFrame" android:id="@+id/branchesFrame"
android:layout_margin="15dp"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
@ -38,10 +36,8 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textIsSelectable="true"
android:textColor="@color/colorWhite" android:textColor="@color/colorWhite"
android:textSize="16sp" android:textSize="16sp"
android:autoLink="web"
android:textColorLink="@color/lightBlue"/> android:textColorLink="@color/lightBlue"/>
</LinearLayout> </LinearLayout>

View File

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

View File

@ -27,7 +27,7 @@
android:theme="@style/ThemeOverlay.AppCompat.Dark" android:theme="@style/ThemeOverlay.AppCompat.Dark"
android:queryHint="Search" /> android:queryHint="Search" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
android:id="@+id/select_all_container" android:id="@+id/select_all_container"
android:visibility="gone" android:visibility="gone"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -20,7 +20,7 @@
android:scrollbars="vertical" android:scrollbars="vertical"
/> />
<GridView xmlns:android="http://schemas.android.com/apk/res/android" <GridView
android:id="@+id/gridView" android:id="@+id/gridView"
android:numColumns="auto_fit" android:numColumns="auto_fit"
android:gravity="center" android:gravity="center"
@ -42,7 +42,7 @@
android:textSize="20sp" android:textSize="20sp"
android:visibility="gone" /> android:visibility="gone" />
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" <ProgressBar
android:id="@+id/progress_bar" android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar" style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -25,6 +25,15 @@
android:text="@string/noDataCollaboratorTab" android:text="@string/noDataCollaboratorTab"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="20sp" android:textSize="20sp"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
android:visibility="visible" /> android:visibility="visible" />
</RelativeLayout> </RelativeLayout>

View File

@ -22,7 +22,7 @@
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" <ProgressBar
android:id="@+id/progress_barClosed" android:id="@+id/progress_barClosed"
style="@style/Base.Widget.AppCompat.ProgressBar" style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="match_parent" android:layout_width="match_parent"

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