Compare commits

..

10 Commits

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

View File

@ -24,32 +24,6 @@ steps:
commands: commands:
- ./gradlew build - ./gradlew build
- name: sign
image: nextcloudci/android:android-49
environment:
TOKEN:
from_secret: BOT_TOKEN
KS_PASS:
from_secret: KS_PASS
KEY_PASS:
from_secret: KEY_PASS
OUTPUT: signed.apk
GITEA: https://gitea.com
KS_FILE: ci_keystore.jks
KS_REPO:
from_secret: KS_REPO
commands:
- ./scripts/sign-build.sh
- name: publish
image: vividboarder/drone-webdav
environment:
WEBDAV_USERNAME: GitNexBot
WEBDAV_PASSWORD:
from_secret: NC_TOKEN
PLUGIN_FILE: signed.apk
PLUGIN_DESTINATION: https://cloud.swatian.com/remote.php/dav/files/GitNexBot/GitNex-Builds/latest.apk
trigger: trigger:
event: event:
- push - push

View File

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

View File

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

4
.gitignore vendored
View File

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

View File

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

View File

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

View File

@ -7,11 +7,6 @@ Patches, enhancements, features are always welcome. The PR should focus on the s
Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work. Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work.
**Code Standards**
Please follow the code standards, this will help other developers to understand your code too.
It also helps maintaining the code afterwards.
It is documented in the Wiki: [Code-Standards](https://gitea.com/gitnex/GitNex/wiki/Code-Standards)
**How to submit a PR** **How to submit a PR**
Fork this repository. Pull the forked repository from your namespace to your local machine. Create new branch and work on the bug/feature/enhancement you would like to submit. Push it to your forked version. From there create Pull Request(PR) against **master** branch. Fork this repository. Pull the forked repository from your namespace to your local machine. Create new branch and work on the bug/feature/enhancement you would like to submit. Push it to your forked version. From there create Pull Request(PR) against **master** branch.

View File

@ -2,7 +2,6 @@
[![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://gitea.com/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://gitea.com/gitnex/GitNex/releases) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://gitea.com/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://gitea.com/gitnex/GitNex/releases)
[![Build Status](https://drone.gitea.com/api/badges/gitnex/GitNex/status.svg)](https://drone.gitea.com/gitnex/GitNex) [![Build Status](https://drone.gitea.com/api/badges/gitnex/GitNex/status.svg)](https://drone.gitea.com/gitnex/GitNex)
[![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex)
[![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf)
[<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif) [<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif)
[<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate) [<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate)
@ -91,7 +90,5 @@ Open source libraries
- Caverock/androidsvg - Caverock/androidsvg
- Droidsonroids.gif/android-gif-drawable - Droidsonroids.gif/android-gif-drawable
- Barteksc/AndroidPdfViewer - Barteksc/AndroidPdfViewer
- Mikepenz/fastadapter
- Ge0rg/MemorizingTrustManager
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif) [Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)

View File

@ -6,14 +6,13 @@ android {
applicationId "org.mian.gitnex" applicationId "org.mian.gitnex"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 29
versionCode 251 versionCode 91
versionName "2.5.1" versionName "2.4.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
} }
@ -21,42 +20,31 @@ android {
//checkReleaseBuilds false //checkReleaseBuilds false
abortOnError false abortOnError false
} }
compileOptions {
targetCompatibility = "8"
sourceCompatibility = "8"
}
}
configurations {
cleanedAnnotations
compile.exclude group: 'org.jetbrains', module: 'annotations'
} }
dependencies { dependencies {
def lifecycle_version = "2.2.0" def lifecycle_version = "2.2.0"
def markwon_version = '4.3.1' final def markwon_version = "4.1.1"
def fastadapter = "3.3.1"
def acra = "5.5.0"
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:1.1.0" implementation "androidx.appcompat:appcompat:1.1.0"
implementation "com.google.android.material:material:1.2.0-alpha06" implementation "com.google.android.material:material:1.2.0-alpha05"
implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.legacy:legacy-support-v4:1.0.0"
testImplementation "junit:junit:4.13" testImplementation "junit:junit:4.12"
androidTestImplementation "androidx.test:runner:1.2.0" androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0" androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
implementation "com.github.vihtarb:tooltip:0.2.0" implementation "com.github.vihtarb:tooltip:0.2.0"
implementation 'com.squareup.okhttp3:okhttp:4.5.0' implementation "com.squareup.okhttp3:okhttp:3.12.1"
implementation "com.google.code.gson:gson:2.8.6" implementation "com.google.code.gson:gson:2.8.5"
implementation "com.squareup.picasso:picasso:2.71828" implementation "com.squareup.picasso:picasso:2.71828"
implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1" implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1"
implementation 'com.squareup.retrofit2:retrofit:2.8.1' implementation "com.squareup.retrofit2:retrofit:2.5.0"
implementation 'com.squareup.retrofit2:converter-gson:2.8.1' implementation "com.squareup.retrofit2:converter-gson:2.5.0"
implementation 'com.squareup.retrofit2:converter-scalars:2.8.1' implementation "com.squareup.retrofit2:converter-scalars:2.5.0"
implementation 'com.squareup.okhttp3:logging-interceptor:4.5.0' implementation "com.squareup.okhttp3:logging-interceptor:3.12.1"
implementation 'org.ocpsoft.prettytime:prettytime:4.0.4.Final' implementation "org.ocpsoft.prettytime:prettytime:4.0.1.Final"
implementation "com.vdurmont:emoji-java:5.1.1" implementation "com.vdurmont:emoji-java:4.0.0"
implementation "com.pes.materialcolorpicker:library:1.2.5" implementation "com.pes.materialcolorpicker:library:1.2.5"
implementation "io.noties.markwon:core:$markwon_version" implementation "io.noties.markwon:core:$markwon_version"
implementation "io.noties.markwon:ext-latex:$markwon_version" implementation "io.noties.markwon:ext-latex:$markwon_version"
@ -78,16 +66,8 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9" implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
implementation "commons-io:commons-io:20030203.000550" implementation "commons-io:commons-io:2.6"
implementation "com.github.chrisbanes:PhotoView:2.3.0" implementation "com.github.chrisbanes:PhotoView:2.3.0"
implementation "com.pddstudio:highlightjs-android:1.5.0" implementation "com.pddstudio:highlightjs-android:1.5.0"
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1" implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
//noinspection GradleDependency
implementation "com.mikepenz:fastadapter:$fastadapter"
implementation "com.mikepenz:fastadapter-commons:$fastadapter"
implementation "com.mikepenz:fastadapter-extensions:$fastadapter"
implementation "ch.acra:acra-mail:$acra"
implementation "ch.acra:acra-limiter:$acra"
implementation "ch.acra:acra-notification:$acra"
} }

View File

@ -20,7 +20,7 @@
android:name=".activities.FileViewActivity" android:name=".activities.FileViewActivity"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.CreateFileActivity" android:name=".activities.NewFileActivity"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.RepoWatchersActivity" android:name=".activities.RepoWatchersActivity"
@ -41,16 +41,16 @@
<activity android:name=".activities.ProfileEmailActivity" /> <activity android:name=".activities.ProfileEmailActivity" />
<activity android:name=".activities.AddCollaboratorToRepositoryActivity" /> <activity android:name=".activities.AddCollaboratorToRepositoryActivity" />
<activity android:name=".activities.CreateTeamByOrgActivity" /> <activity android:name=".activities.CreateTeamByOrgActivity" />
<activity android:name=".activities.OrganizationTeamMembersActivity" /> <activity android:name=".activities.OrgTeamMembersActivity" />
<activity <activity
android:name=".activities.OrganizationDetailActivity" android:name=".activities.OrgDetailActivity"
android:label="@string/title_activity_org_detail" android:label="@string/title_activity_org_detail"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".activities.SponsorsActivity" /> <activity android:name=".activities.SponsorsActivity" />
<activity android:name=".activities.CreditsActivity" /> <activity android:name=".activities.CreditsActivity" />
<activity android:name=".activities.CreateLabelActivity" /> <activity android:name=".activities.CreateLabelActivity" />
<activity android:name=".activities.CreateIssueActivity" /> <activity android:name=".activities.CreateIssueActivity" />
<activity android:name=".activities.CreateMilestoneActivity" /> <activity android:name=".activities.NewMilestoneActivity" />
<activity android:name=".activities.ReplyToIssueActivity" /> <activity android:name=".activities.ReplyToIssueActivity" />
<activity <activity
android:name=".activities.IssueDetailActivity" android:name=".activities.IssueDetailActivity"
@ -59,7 +59,7 @@
android:name=".activities.RepoDetailActivity" android:name=".activities.RepoDetailActivity"
android:label="@string/title_activity_repo_detail" android:label="@string/title_activity_repo_detail"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".activities.MainActivity" android:theme="@android:style/Theme.NoTitleBar"> <activity android:name=".activities.MainActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -68,13 +68,11 @@
</activity> </activity>
<activity <activity
android:name=".activities.LoginActivity" android:name=".activities.LoginActivity"
android:launchMode="singleTask" android:theme="@android:style/Theme.NoTitleBar"/> android:launchMode="singleTask" />
<activity android:name=".activities.CreateRepoActivity" /> <activity android:name=".activities.NewRepoActivity" />
<activity android:name=".activities.CreateOrganizationActivity" /> <activity android:name=".activities.NewOrganizationActivity" />
<activity android:name=".activities.OpenRepoInBrowserActivity" /> <activity android:name=".activities.OpenRepoInBrowserActivity" />
<activity android:name=".activities.FileDiffActivity" /> <activity android:name=".activities.FileDiffActivity" />
<activity android:name=".activities.CommitsActivity" />
<activity android:name=".helpers.ssl.MemorizingActivity" android:theme="@android:style/Theme.Material.Dialog" />
</application> </application>
</manifest> </manifest>

View File

@ -2,8 +2,6 @@ package org.mian.gitnex.actions;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity; import org.mian.gitnex.activities.ReplyToIssueActivity;
@ -24,9 +22,9 @@ import retrofit2.Callback;
public class IssueActions { public class IssueActions {
public static void editIssueComment(final Context ctx, final int commentId, final String commentBody) { public static void editIssueComment(final Context context, final int commentId, final String commentBody) {
final TinyDB tinyDb = new TinyDB(ctx); final TinyDB tinyDb = new TinyDB(context);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -39,9 +37,9 @@ public class IssueActions {
Call<IssueComments> call; Call<IssueComments> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, context)
.getApiInterface() .getApiInterface()
.patchIssueComment(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, commentId, commentBodyJson); .patchIssueComment(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, commentId, commentBodyJson);
call.enqueue(new Callback<IssueComments>() { call.enqueue(new Callback<IssueComments>() {
@ -52,32 +50,32 @@ public class IssueActions {
if(response.code() == 200) { if(response.code() == 200) {
tinyDb.putBoolean("commentEdited", true); tinyDb.putBoolean("commentEdited", true);
Toasty.info(ctx, ctx.getString(R.string.editCommentUpdatedText)); Toasty.info(context, context.getString(R.string.editCommentUpdatedText));
((ReplyToIssueActivity)ctx).finish(); ((ReplyToIssueActivity)context).finish();
} }
} }
else if(response.code() == 401) { else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.info(ctx, ctx.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }
@ -91,9 +89,9 @@ public class IssueActions {
} }
public static void closeReopenIssue(final Context ctx, final int issueIndex, final String issueState) { public static void closeReopenIssue(final Context context, final int issueIndex, final String issueState) {
final TinyDB tinyDb = new TinyDB(ctx); final TinyDB tinyDb = new TinyDB(context);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
@ -106,9 +104,9 @@ public class IssueActions {
Call<JsonElement> call; Call<JsonElement> call;
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, context)
.getApiInterface() .getApiInterface()
.closeReopenIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson); .closeReopenIssue(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson);
call.enqueue(new Callback<JsonElement>() { call.enqueue(new Callback<JsonElement>() {
@ -120,43 +118,36 @@ public class IssueActions {
tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("resumeClosedIssues", true); tinyDb.putBoolean("resumeClosedIssues", true);
if(issueState.equals("closed")) { if(issueState.equals("closed")) {
Toasty.info(context, context.getString(R.string.issueStateClosed));
Toasty.info(ctx, ctx.getString(R.string.issueStateClosed));
tinyDb.putString("issueState", "closed");
} }
else if(issueState.equals("open")) { else if(issueState.equals("open")) {
Toasty.info(context, context.getString(R.string.issueStateReopened));
Toasty.info(ctx, ctx.getString(R.string.issueStateReopened));
tinyDb.putString("issueState", "open");
} }
} }
} }
else if(response.code() == 401) { else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.info(ctx, ctx.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }
@ -170,127 +161,4 @@ public class IssueActions {
} }
public static void subscribe(final Context ctx, final TextView subscribeIssue, final TextView unsubscribeIssue) {
final TinyDB tinyDB = new TinyDB(ctx);
final String instanceUrl = tinyDB.getString("instanceUrl");
String repoFullName = tinyDB.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String loginUid = tinyDB.getString("loginUid");
final String userLogin = tinyDB.getString("userLogin");
final String token = "token " + tinyDB.getString(loginUid + "-token");
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
Call<Void> call;
call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.addIssueSubscriber(token, repoOwner, repoName, issueNr, userLogin);
call.enqueue(new Callback<Void>() {
@Override
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
if(response.isSuccessful()) {
if(response.code() == 201) {
unsubscribeIssue.setVisibility(View.VISIBLE);
subscribeIssue.setVisibility(View.GONE);
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtion));
tinyDB.putString("issueSubscriptionState", "unsubscribeToIssue");
}
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtionError));
}
}
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.info(ctx, ctx.getString(R.string.issueSubscribtionError));
}
});
}
public static void unsubscribe(final Context ctx, final TextView subscribeIssue, final TextView unsubscribeIssue) {
final TinyDB tinyDB = new TinyDB(ctx);
final String instanceUrl = tinyDB.getString("instanceUrl");
String repoFullName = tinyDB.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String loginUid = tinyDB.getString("loginUid");
final String userLogin = tinyDB.getString("userLogin");
final String token = "token " + tinyDB.getString(loginUid + "-token");
final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber"));
Call<Void> call;
call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.delIssueSubscriber(token, repoOwner, repoName, issueNr, userLogin);
call.enqueue(new Callback<Void>() {
@Override
public void onResponse(@NonNull Call<Void> call, @NonNull retrofit2.Response<Void> response) {
if(response.isSuccessful()) {
if(response.code() == 201) {
unsubscribeIssue.setVisibility(View.GONE);
subscribeIssue.setVisibility(View.VISIBLE);
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtion));
tinyDB.putString("issueSubscriptionState", "subscribeToIssue");
}
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtionError));
}
}
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.info(ctx, ctx.getString(R.string.issueUnsubscribtionError));
}
});
}
} }

View File

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

View File

@ -13,7 +13,6 @@ import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
@ -49,8 +48,6 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -64,10 +61,6 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
mProgressBar = findViewById(R.id.progress_bar); mProgressBar = findViewById(R.id.progress_bar);
noData = findViewById(R.id.noData); noData = findViewById(R.id.noData);
addCollaboratorSearch.requestFocus();
assert imm != null;
imm.showSoftInput(addCollaboratorSearch, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);

View File

@ -21,7 +21,7 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.adapters.AdminGetUsersAdapter; import org.mian.gitnex.adapters.AdminGetUsersAdapter;
import org.mian.gitnex.fragments.BottomSheetAdminUsersFragment; import org.mian.gitnex.fragments.AdminUsersBottomSheetFragment;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
@ -34,7 +34,7 @@ import java.util.Objects;
* Author M M Arif * Author M M Arif
*/ */
public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAdminUsersFragment.BottomSheetListener { public class AdminGetUsersActivity extends BaseActivity implements AdminUsersBottomSheetFragment.BottomSheetListener {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
@ -171,7 +171,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
finish(); finish();
return true; return true;
case R.id.genericMenu: case R.id.genericMenu:
BottomSheetAdminUsersFragment bottomSheet = new BottomSheetAdminUsersFragment(); AdminUsersBottomSheetFragment bottomSheet = new AdminUsersBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet");
return true; return true;
default: default:

View File

@ -2,28 +2,14 @@ package org.mian.gitnex.activities;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import org.acra.ACRA;
import org.acra.BuildConfig;
import org.acra.annotation.AcraNotification;
import org.acra.config.CoreConfigurationBuilder;
import org.acra.config.LimiterConfigurationBuilder;
import org.acra.config.MailSenderConfigurationBuilder;
import org.acra.data.StringFormat;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.FontsOverride; import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
/** /**
* Author M M Arif * Author M M Arif
*/ */
@AcraNotification(resIcon = R.drawable.gitnex_transparent,
resTitle = R.string.crashTitle,
resChannelName = R.string.setCrashReports,
resText = R.string.crashMessage)
public abstract class BaseActivity extends AppCompatActivity { public abstract class BaseActivity extends AppCompatActivity {
@Override @Override
@ -34,18 +20,6 @@ public abstract class BaseActivity extends AppCompatActivity {
if(tinyDb.getInt("themeId") == 1) { if(tinyDb.getInt("themeId") == 1) {
setTheme(R.style.AppThemeLight); setTheme(R.style.AppThemeLight);
} }
else if(tinyDb.getInt("themeId") == 2) {
boolean timeSetterFlag = TimeHelper.timeBetweenHours(18, 6); // 6pm to 6am
if(timeSetterFlag) {
setTheme(R.style.AppTheme);
}
else {
setTheme(R.style.AppThemeLight);
}
}
else { else {
setTheme(R.style.AppTheme); setTheme(R.style.AppTheme);
} }
@ -53,50 +27,36 @@ public abstract class BaseActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId()); setContentView(getLayoutResourceId());
switch(tinyDb.getInt("customFontId", -1)) { if(tinyDb.getInt("customFontId") == 0) {
case 0:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/roboto.ttf"); FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/roboto.ttf"); FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/roboto.ttf"); FontsOverride.setDefaultFont(this, "SERIF", "fonts/roboto.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/roboto.ttf"); FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/roboto.ttf");
break;
case 2: }
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/sourcecodeproregular.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/sourcecodeproregular.ttf");
break;
default:
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/manroperegular.ttf"); FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/manroperegular.ttf"); FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/manroperegular.ttf"); FontsOverride.setDefaultFont(this, "SERIF", "fonts/manroperegular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/manroperegular.ttf"); FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/manroperegular.ttf");
break;
} }
else if (tinyDb.getInt("customFontId") == 2) {
FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "fonts/sourcecodeproregular.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/sourcecodeproregular.ttf");
// enabling counter badges by default
if(tinyDb.getString("enableCounterBadgesInit").isEmpty()) {
tinyDb.putBoolean("enableCounterBadges", true);
tinyDb.putString("enableCounterBadgesInit", "yes");
} }
else {
// enable crash reports by default FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/roboto.ttf");
if(tinyDb.getString("crashReportingEnabledInit").isEmpty()) { FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/roboto.ttf");
tinyDb.putBoolean("crashReportingEnabled", true); FontsOverride.setDefaultFont(this, "SERIF", "fonts/roboto.ttf");
tinyDb.putString("crashReportingEnabledInit", "yes"); FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/roboto.ttf");
}
if (tinyDb.getBoolean("crashReportingEnabled")) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);
ACRABuilder.setBuildConfigClass(BuildConfig.class).setReportFormat(StringFormat.KEY_VALUE_LIST);
ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class).setReportAsFile(true).setMailTo(getResources().getString(R.string.appEmail)).setSubject(getResources().getString(R.string.crashReportEmailSubject, AppUtil.getAppBuildNo(getApplicationContext()))).setEnabled(true);
ACRABuilder.getPluginConfigurationBuilder(LimiterConfigurationBuilder.class).setEnabled(true);
ACRA.init(getApplication(), ACRABuilder);
} }

View File

@ -1,325 +0,0 @@
package org.mian.gitnex.activities;
import android.os.Bundle;
import android.os.Handler;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.mikepenz.fastadapter.IItemAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.adapters.CommitsAdapter;
import org.mian.gitnex.models.Commits;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
/**
* Author M M Arif
*/
public class CommitsActivity extends BaseActivity implements ItemFilterListener<CommitsAdapter> {
private View.OnClickListener onClickListener;
private TextView noData;
private ProgressBar progressBar;
private SwipeRefreshLayout swipeRefreshLayout;
private String TAG = "CommitsActivity - ";
private int resultLimit = 50;
private boolean loadNextFlag = false;
private List<CommitsAdapter> items = new ArrayList<>();
private FastItemAdapter<CommitsAdapter> fastItemAdapter;
private ItemAdapter footerAdapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
@Override
protected int getLayoutResourceId(){
return R.layout.activity_commits;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
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 branchName = getIntent().getStringExtra("branchName");
TextView toolbar_title = findViewById(R.id.toolbar_title);
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
toolbar_title.setText(branchName);
ImageView closeActivity = findViewById(R.id.close);
noData = findViewById(R.id.noDataCommits);
progressBar = findViewById(R.id.progress_bar);
swipeRefreshLayout = findViewById(R.id.pullToRefresh);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setHasFixedSize(true);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
fastItemAdapter = new FastItemAdapter<>();
fastItemAdapter.withSelectable(true);
footerAdapter = items();
//noinspection unchecked
fastItemAdapter.addAdapter(1, footerAdapter);
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<CommitsAdapter>) (item, constraint) -> item.getCommitTitle().toLowerCase().contains(Objects.requireNonNull(constraint).toString().toLowerCase()));
fastItemAdapter.getItemFilter().withItemFilterListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(fastItemAdapter);
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
@Override
public void onLoadMore(final int currentPage) {
loadNext(instanceUrl, instanceToken, repoOwner, repoName, currentPage, branchName);
}
};
swipeRefreshLayout.setOnRefreshListener(() -> {
progressBar.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
swipeRefreshLayout.setRefreshing(false);
});
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, branchName);
assert savedInstanceState != null;
fastItemAdapter.withSavedInstanceState(savedInstanceState);
}
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String branchName) {
Call<List<Commits>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getRepositoryCommits(token, repoOwner, repoName, 1, branchName);
call.enqueue(new Callback<List<Commits>>() {
@Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
if (response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
if(response.body().size() == resultLimit) {
loadNextFlag = true;
}
for (int i = 0; i < response.body().size(); i++) {
items.add(new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(), response.body().get(i).getHtml_url(),
response.body().get(i).getCommit().getCommitter().getName(), response.body().get(i).getCommit().getCommitter().getDate()));
}
fastItemAdapter.add(items);
}
else {
noData.setVisibility(View.VISIBLE);
}
progressBar.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, final int currentPage, String branchName) {
footerAdapter.clear();
//noinspection unchecked
footerAdapter.add(new ProgressItem().withEnabled(false));
Handler handler = new Handler();
handler.postDelayed(() -> {
Call<List<Commits>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getRepositoryCommits(token, repoOwner, repoName, currentPage + 1, branchName);
call.enqueue(new Callback<List<Commits>>() {
@Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
if (response.isSuccessful()) {
assert response.body() != null;
if (response.body().size() > 0) {
loadNextFlag = response.body().size() == resultLimit;
for (int i = 0; i < response.body().size(); i++) {
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new CommitsAdapter(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(),
response.body().get(i).getHtml_url(), response.body().get(i).getCommit().getCommitter().getName(),
response.body().get(i).getCommit().getCommitter().getDate()));
}
footerAdapter.clear();
}
else {
footerAdapter.clear();
}
progressBar.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}, 1000);
if(!loadNextFlag) {
footerAdapter.clear();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
fastItemAdapter.filter(newText);
return true;
}
});
endlessRecyclerOnScrollListener.enable();
return super.onCreateOptionsMenu(menu);
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<CommitsAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}
@Override
public void onReset() {
endlessRecyclerOnScrollListener.enable();
}
private void initCloseListener() {
onClickListener = view -> {
getIntent().removeExtra("branchName");
finish();
};
}
}

View File

@ -11,7 +11,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.DatePicker; import android.widget.DatePicker;
@ -78,8 +77,6 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -99,10 +96,6 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
newIssueDescription = findViewById(R.id.newIssueDescription); newIssueDescription = findViewById(R.id.newIssueDescription);
labelsIdHolder = findViewById(R.id.labelsIdHolder); labelsIdHolder = findViewById(R.id.labelsIdHolder);
newIssueTitle.requestFocus();
assert imm != null;
imm.showSoftInput(newIssueTitle, InputMethodManager.SHOW_IMPLICIT);
defaultMentionAdapter = new MentionArrayAdapter<>(this); defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList(); loadCollaboratorsList();
@ -367,7 +360,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
} }
} }
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreateIssueActivity.this, ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, milestonesList); R.layout.spinner_item, milestonesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);

View File

@ -11,7 +11,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
@ -51,8 +50,6 @@ public class CreateLabelActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(getApplicationContext());
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
@ -64,7 +61,7 @@ public class CreateLabelActivity extends BaseActivity {
if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("delete")) { if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("delete")) {
deleteLabel(instanceUrl, instanceToken, repoOwner, repoName, Integer.parseInt(Objects.requireNonNull(getIntent().getStringExtra("labelId"))), loginUid); deleteLabel(instanceUrl, instanceToken, repoOwner, repoName, Integer.valueOf(Objects.requireNonNull(getIntent().getStringExtra("labelId"))), loginUid);
finish(); finish();
return; return;
@ -77,10 +74,6 @@ public class CreateLabelActivity extends BaseActivity {
labelName = findViewById(R.id.labelName); labelName = findViewById(R.id.labelName);
createLabelButton = findViewById(R.id.createLabelButton); createLabelButton = findViewById(R.id.createLabelButton);
labelName.requestFocus();
assert imm != null;
imm.showSoftInput(labelName, InputMethodManager.SHOW_IMPLICIT);
final ColorPicker cp = new ColorPicker(CreateLabelActivity.this, 235, 113, 33); final ColorPicker cp = new ColorPicker(CreateLabelActivity.this, 235, 113, 33);
initCloseListener(); initCloseListener();

View File

@ -9,7 +9,6 @@ import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.util.Patterns; import android.util.Patterns;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
@ -48,8 +47,6 @@ public class CreateNewUserActivity extends BaseActivity {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
createUserButton = findViewById(R.id.createUserButton); createUserButton = findViewById(R.id.createUserButton);
fullName = findViewById(R.id.fullName); fullName = findViewById(R.id.fullName);
@ -57,10 +54,6 @@ public class CreateNewUserActivity extends BaseActivity {
userEmail = findViewById(R.id.userEmail); userEmail = findViewById(R.id.userEmail);
userPassword = findViewById(R.id.userPassword); userPassword = findViewById(R.id.userPassword);
fullName.requestFocus();
assert imm != null;
imm.showSoftInput(fullName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);

View File

@ -9,7 +9,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
@ -60,8 +59,6 @@ public class CreateReleaseActivity extends BaseActivity {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -78,10 +75,6 @@ public class CreateReleaseActivity extends BaseActivity {
releaseType = findViewById(R.id.releaseType); releaseType = findViewById(R.id.releaseType);
releaseDraft = findViewById(R.id.releaseDraft); releaseDraft = findViewById(R.id.releaseDraft);
releaseTagName.requestFocus();
assert imm != null;
imm.showSoftInput(releaseTagName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -260,7 +253,7 @@ public class CreateReleaseActivity extends BaseActivity {
} }
} }
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateReleaseActivity.this, ArrayAdapter<Branches> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, branchesList); R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);

View File

@ -9,7 +9,6 @@ import android.content.DialogInterface;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@ -77,8 +76,6 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
teamName = findViewById(R.id.teamName); teamName = findViewById(R.id.teamName);
teamDesc = findViewById(R.id.teamDesc); teamDesc = findViewById(R.id.teamDesc);
@ -88,10 +85,6 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
teamAccessControlsArray = findViewById(R.id.teamAccessControlsArray); teamAccessControlsArray = findViewById(R.id.teamAccessControlsArray);
createTeamButton = findViewById(R.id.createTeamButton); createTeamButton = findViewById(R.id.createTeamButton);
teamName.requestFocus();
assert imm != null;
imm.showSoftInput(teamName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);

View File

@ -12,7 +12,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.DatePicker; import android.widget.DatePicker;
@ -71,8 +70,6 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
@ -91,10 +88,6 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
editIssueDescription = findViewById(R.id.editIssueDescription); editIssueDescription = findViewById(R.id.editIssueDescription);
editIssueDueDate = findViewById(R.id.editIssueDueDate); editIssueDueDate = findViewById(R.id.editIssueDueDate);
editIssueTitle.requestFocus();
assert imm != null;
imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT);
defaultMentionAdapter = new MentionArrayAdapter<>(this); defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList(); loadCollaboratorsList();
@ -388,7 +381,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
} }
ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(EditIssueActivity.this, ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, milestonesList); R.layout.spinner_item, milestonesList);
adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item);

View File

@ -10,7 +10,7 @@ import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.adapters.FilesDiffAdapter; import org.mian.gitnex.adapters.FilesDiffAdapter;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
@ -72,18 +72,18 @@ public class FileDiffActivity extends BaseActivity {
mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.VISIBLE);
String pullIndex = tinyDb.getString("issueNumber"); String fileDiffName = tinyDb.getString("issueNumber")+".diff";
getPullDiffContent(tinyDb.getString("instanceUrlWithProtocol"), repoOwner, repoName, pullIndex); getFileContents(tinyDb.getString("instanceUrlWithProtocol"), repoOwner, repoName, fileDiffName);
} }
private void getPullDiffContent(String instanceUrl, String owner, String repo, String filename) { private void getFileContents(String instanceUrl, String owner, String repo, String filename) {
Call<ResponseBody> call = RetrofitClient Call<ResponseBody> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
.getWebInterface() .getApiInterface()
.getPullDiffContent(owner, repo, filename); .getFileDiffContents(owner, repo, filename);
call.enqueue(new Callback<ResponseBody>() { call.enqueue(new Callback<ResponseBody>() {
@ -121,7 +121,7 @@ public class FileDiffActivity extends BaseActivity {
} }
} }
String fileExtension = FileUtils.getExtension(fileNameFinal); String fileExtension = FilenameUtils.getExtension(fileNameFinal);
String fileContentsFinalWithBlankLines = fileContentsFinal.replaceAll( ".*@@.*", "" ); String fileContentsFinalWithBlankLines = fileContentsFinal.replaceAll( ".*@@.*", "" );
String fileContentsFinalWithoutBlankLines = fileContentsFinal.replaceAll( ".*@@.*(\r?\n|\r)?", "" ); String fileContentsFinalWithoutBlankLines = fileContentsFinal.replaceAll( ".*@@.*(\r?\n|\r)?", "" );
@ -140,9 +140,9 @@ public class FileDiffActivity extends BaseActivity {
String binaryFileRaw = binaryFile[1].substring(binaryFile[1].indexOf('\n')+1); String binaryFileRaw = binaryFile[1].substring(binaryFile[1].indexOf('\n')+1);
String binaryFileFinal = binaryFile[1].substring(binaryFileRaw.indexOf('\n')+1); String binaryFileFinal = binaryFile[1].substring(binaryFileRaw.indexOf('\n')+1);
String fileExtension = FileUtils.getExtension(getFileNameFinal); String fileExtension = FilenameUtils.getExtension(getFileNameFinal);
if(appUtil.imageExtension(FileUtils.getExtension(getFileNameFinal))) { if(appUtil.imageExtension(FilenameUtils.getExtension(getFileNameFinal))) {
fileContentsArray.add(new FileDiffView(getFileNameFinal, appUtil.imageExtension(fileExtension), "", binaryFileFinal)); fileContentsArray.add(new FileDiffView(getFileNameFinal, appUtil.imageExtension(fileExtension), "", binaryFileFinal));
} }

View File

@ -1,6 +1,5 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
@ -14,7 +13,6 @@ import android.text.method.ScrollingMovementMethod;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
@ -32,7 +30,7 @@ import com.github.barteksc.pdfviewer.util.FitPolicy;
import com.github.chrisbanes.photoview.PhotoView; import com.github.chrisbanes.photoview.PhotoView;
import com.pddstudio.highlightjs.HighlightJsView; import com.pddstudio.highlightjs.HighlightJsView;
import com.pddstudio.highlightjs.models.Theme; import com.pddstudio.highlightjs.models.Theme;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetFileViewerFragment; import org.mian.gitnex.fragments.BottomSheetFileViewerFragment;
@ -59,8 +57,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TextView singleFileContents; private TextView singleFileContents;
private LinearLayout singleFileContentsFrame; private LinearLayout singleFileContentsFrame;
private LinearLayout highlightJs; private HighlightJsView singleCodeContents;
//private HighlightJsView singleCodeContents;
private PhotoView imageView; private PhotoView imageView;
final Context ctx = this; final Context ctx = this;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
@ -73,7 +70,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_file_view; return R.layout.activity_file_view;
} }
@ -95,8 +91,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
singleFileContents = findViewById(R.id.singleFileContents); singleFileContents = findViewById(R.id.singleFileContents);
highlightJs = findViewById(R.id.highlightJs); singleCodeContents = findViewById(R.id.singleCodeContents);
//singleCodeContents = findViewById(R.id.singleCodeContents);
imageView = findViewById(R.id.imageView); imageView = findViewById(R.id.imageView);
mProgressBar = findViewById(R.id.progress_bar); mProgressBar = findViewById(R.id.progress_bar);
pdfView = findViewById(R.id.pdfView); pdfView = findViewById(R.id.pdfView);
@ -137,7 +132,10 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<Files> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getSingleFileContents(token, owner, repo, filename); Call<Files> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getSingleFileContents(token, owner, repo, filename);
call.enqueue(new Callback<Files>() { call.enqueue(new Callback<Files>() {
@ -151,7 +149,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if(!response.body().getContent().equals("")) { if(!response.body().getContent().equals("")) {
String fileExtension = FileUtils.getExtension(filename); String fileExtension = FilenameUtils.getExtension(filename);
mProgressBar.setVisibility(View.GONE); mProgressBar.setVisibility(View.GONE);
// download file meta // download file meta
@ -161,8 +159,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if(appUtil.imageExtension(fileExtension)) { // file is image if(appUtil.imageExtension(fileExtension)) { // file is image
singleFileContentsFrame.setVisibility(View.GONE); singleFileContentsFrame.setVisibility(View.GONE);
highlightJs.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
//singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE); imageView.setVisibility(View.VISIBLE);
@ -173,72 +170,49 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
else if (appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode else if (appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode
pdfViewFrame.setVisibility(View.GONE);
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
if(Build.VERSION.SDK_INT > 23) {
highlightJs.setVisibility(View.VISIBLE);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
assert inflater != null;
@SuppressLint("InflateParams") View mView = inflater.inflate(R.layout.custom_highlightjs, null);
HighlightJsView singleCodeContents = mView.findViewById(R.id.singleCodeContents);
highlightJs.addView(mView);
singleFileContentsFrame.setVisibility(View.GONE); singleFileContentsFrame.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE);
singleCodeContents.setVisibility(View.VISIBLE); singleCodeContents.setVisibility(View.VISIBLE);
switch(tinyDb.getInt("fileviewerSourceCodeThemeId")) { singleCodeContents.setTheme(Theme.GRUVBOX_DARK);
case 1:
singleCodeContents.setTheme(Theme.ARDUINO_LIGHT);
break;
case 2:
singleCodeContents.setTheme(Theme.GITHUB);
break;
case 3:
singleCodeContents.setTheme(Theme.FAR);
break;
case 4:
singleCodeContents.setTheme(Theme.IR_BLACK);
break;
case 5:
singleCodeContents.setTheme(Theme.ANDROID_STUDIO);
break;
default:
singleCodeContents.setTheme(Theme.MONOKAI_SUBLIME);
}
singleCodeContents.setShowLineNumbers(true); singleCodeContents.setShowLineNumbers(true);
singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent())); singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent()));
}
else {
singleFileContents.setVisibility(View.VISIBLE);
singleFileContents.setText(appUtil.decodeBase64(response.body().getContent()));
}
} }
else if (appUtil.pdfExtension(fileExtension)) { // file is pdf else if (appUtil.pdfExtension(fileExtension)) { // file is pdf
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.GONE); singleFileContentsFrame.setVisibility(View.GONE);
highlightJs.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
//singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.VISIBLE); pdfViewFrame.setVisibility(View.VISIBLE);
pdfNightMode = tinyDb.getBoolean("enablePdfMode"); pdfNightMode = tinyDb.getBoolean("enablePdfMode");
decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT); decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT);
pdfView.fromBytes(decodedPdf).enableSwipe(true).swipeHorizontal(false).enableDoubletap(true).defaultPage(0).enableAnnotationRendering(false).password(null).scrollHandle(null).enableAntialiasing(true).spacing(0).autoSpacing(true).pageFitPolicy(FitPolicy.WIDTH).fitEachPage(true).pageSnap(false).pageFling(true).nightMode(pdfNightMode).load(); pdfView.fromBytes(decodedPdf)
.enableSwipe(true)
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
.enableAnnotationRendering(false)
.password(null)
.scrollHandle(null)
.enableAntialiasing(true)
.spacing(0)
.autoSpacing(true)
.pageFitPolicy(FitPolicy.WIDTH)
.fitEachPage(true)
.pageSnap(false)
.pageFling(true)
.nightMode(pdfNightMode)
.load();
} }
else if (appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded else if (appUtil.excludeFilesInFileViewerExtension(fileExtension)) { // files need to be excluded
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
highlightJs.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
//singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE); singleFileContentsFrame.setVisibility(View.VISIBLE);
@ -250,8 +224,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
else { // file type not known - plain text view else { // file type not known - plain text view
imageView.setVisibility(View.GONE); imageView.setVisibility(View.GONE);
highlightJs.setVisibility(View.GONE); singleCodeContents.setVisibility(View.GONE);
//singleCodeContents.setVisibility(View.GONE);
pdfViewFrame.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE); singleFileContentsFrame.setVisibility(View.VISIBLE);
@ -268,7 +241,10 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
else if(response.code() == 401) { 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)); 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) { else if(response.code() == 403) {
@ -291,7 +267,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
@Override @Override
public void onFailure(@NonNull Call<Files> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Files> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
@ -300,7 +275,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu); inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
return true; return true;
@ -331,15 +305,18 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
switch (text) { switch (text) {
case "downloadFile": case "downloadFile":
if(Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23)
if(checkPermission()) { {
if (checkPermission())
{
requestFileDownload(); requestFileDownload();
} }
else { else {
requestPermission(); requestPermission();
} }
} }
else { else
{
requestFileDownload(); requestFileDownload();
} }
break; break;
@ -381,19 +358,16 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
private boolean checkPermission() { private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE); int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED; return result == PackageManager.PERMISSION_GRANTED;
} }
private void requestPermission() { private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE); ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) { switch (requestCode) {
case PERMISSION_REQUEST_CODE: case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
@ -407,12 +381,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() { onClickListener = new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
getIntent().removeExtra("singleFileName"); getIntent().removeExtra("singleFileName");
finish(); finish();
} }

View File

@ -4,7 +4,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProviders;
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;
@ -17,6 +17,7 @@ import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.AsyncDrawable;
import io.noties.markwon.image.DefaultMediaDecoder; import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem; import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.ImagesPlugin;
@ -28,12 +29,10 @@ import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.text.Html; import android.text.Html;
@ -51,15 +50,14 @@ import android.widget.RelativeLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
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.adapters.IssueCommentsAdapter; import org.mian.gitnex.adapters.IssueCommentsAdapter;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment; import org.mian.gitnex.fragments.SingleIssueBottomSheetFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.models.IssueComments;
@ -69,6 +67,7 @@ import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.viewmodels.IssueCommentsViewModel; import org.mian.gitnex.viewmodels.IssueCommentsViewModel;
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.Collection;
@ -96,7 +95,6 @@ public class IssueDetailActivity extends BaseActivity {
private HorizontalScrollView assigneesScrollView; private HorizontalScrollView assigneesScrollView;
private ScrollView scrollViewComments; private ScrollView scrollViewComments;
private TextView issueModified; private TextView issueModified;
private ImageView createNewComment;
final Context ctx = this; final Context ctx = this;
private LinearLayout labelsLayout; private LinearLayout labelsLayout;
private LinearLayout assigneesLayout; private LinearLayout assigneesLayout;
@ -134,7 +132,6 @@ public class IssueDetailActivity extends BaseActivity {
assigneesScrollView = findViewById(R.id.assigneesScrollView); assigneesScrollView = findViewById(R.id.assigneesScrollView);
scrollViewComments = findViewById(R.id.scrollViewComments); scrollViewComments = findViewById(R.id.scrollViewComments);
issueModified = findViewById(R.id.issueModified); issueModified = findViewById(R.id.issueModified);
createNewComment = findViewById(R.id.addNewComment);
labelsLayout = findViewById(R.id.frameLabels); labelsLayout = findViewById(R.id.frameLabels);
assigneesLayout = findViewById(R.id.frameAssignees); assigneesLayout = findViewById(R.id.frameAssignees);
@ -150,56 +147,42 @@ public class IssueDetailActivity extends BaseActivity {
mRecyclerView.setNestedScrollingEnabled(false); mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
createNewComment.setOnClickListener(v -> startActivity(new Intent(ctx, ReplyToIssueActivity.class))); swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { public void onRefresh() {
new Handler().postDelayed(new Runnable() {
scrollViewComments.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { @Override
public void run() {
if ((scrollY - oldScrollY) > 0 && createNewComment.isShown()) {
createNewComment.setVisibility(View.GONE);
}
else if ((scrollY - oldScrollY) < 0) {
createNewComment.setVisibility(View.VISIBLE);
}
if (!scrollViewComments.canScrollVertically(1)) { // bottom
createNewComment.setVisibility(View.GONE);
}
if (!scrollViewComments.canScrollVertically(-1)) { // top
createNewComment.setVisibility(View.VISIBLE);
}
});
}
swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setRefreshing(false); swipeRefresh.setRefreshing(false);
IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, getApplicationContext()); IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, getApplicationContext());
}
}, 500)); }, 500);
}
});
Typeface myTypeface; Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
}
else if (tinyDb.getInt("customFontId") == 1) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/manroperegular.ttf");
}
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
switch(tinyDb.getInt("customFontId", -1)) {
case 1:
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/manroperegular.ttf");
break;
case 2:
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default:
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf"); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
break;
} }
@ -228,7 +211,7 @@ public class IssueDetailActivity extends BaseActivity {
finish(); finish();
return true; return true;
case R.id.genericMenu: case R.id.genericMenu:
BottomSheetSingleIssueFragment bottomSheet = new BottomSheetSingleIssueFragment(); SingleIssueBottomSheetFragment bottomSheet = new SingleIssueBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(), "singleIssueBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "singleIssueBottomSheet");
return true; return true;
default: default:
@ -310,7 +293,7 @@ public class IssueDetailActivity extends BaseActivity {
private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo, int index, String loginUid) { private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo, int index, String loginUid) {
IssueCommentsViewModel issueCommentsModel = new ViewModelProvider(this).get(IssueCommentsViewModel.class); IssueCommentsViewModel issueCommentsModel = ViewModelProviders.of(this).get(IssueCommentsViewModel.class);
issueCommentsModel.getIssueCommentList(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), owner, repo, index, getApplicationContext()).observe(this, new Observer<List<IssueComments>>() { issueCommentsModel.getIssueCommentList(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), owner, repo, index, getApplicationContext()).observe(this, new Observer<List<IssueComments>>() {
@Override @Override
@ -343,7 +326,9 @@ public class IssueDetailActivity extends BaseActivity {
final Markwon markwon = Markwon.builder(Objects.requireNonNull(getApplicationContext())) final Markwon markwon = Markwon.builder(Objects.requireNonNull(getApplicationContext()))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> { .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override
public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() { plugin.addSchemeHandler(new SchemeHandler() {
@NonNull @NonNull
@Override @Override
@ -366,12 +351,19 @@ public class IssueDetailActivity extends BaseActivity {
return Collections.singleton("drawable"); return Collections.singleton("drawable");
} }
}); });
plugin.placeholderProvider(drawable -> null); plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false)); plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(getApplicationContext().getResources())); plugin.addMediaDecoder(SvgMediaDecoder.create(getApplicationContext().getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create()); plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getApplicationContext().getResources())); plugin.defaultMediaDecoder(DefaultMediaDecoder.create(getApplicationContext().getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
})) }))
.usePlugin(new AbstractMarkwonPlugin() { .usePlugin(new AbstractMarkwonPlugin() {
@ -396,7 +388,7 @@ public class IssueDetailActivity extends BaseActivity {
tinyDb.putString("issueState", singleIssue.getState()); tinyDb.putString("issueState", singleIssue.getState());
tinyDb.putString("issueTitle", singleIssue.getTitle()); tinyDb.putString("issueTitle", singleIssue.getTitle());
PicassoService.getInstance(ctx).get().load(singleIssue.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); Picasso.get().load(singleIssue.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
String issueNumber_ = "<font color='" + getApplicationContext().getResources().getColor(R.color.lightGray) + "'>" + getApplicationContext().getResources().getString(R.string.hash) + singleIssue.getNumber() + "</font>"; String issueNumber_ = "<font color='" + getApplicationContext().getResources().getColor(R.color.lightGray) + "'>" + getApplicationContext().getResources().getString(R.string.hash) + singleIssue.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle())); issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle()));
String cleanIssueDescription = singleIssue.getBody().trim(); String cleanIssueDescription = singleIssue.getBody().trim();
@ -414,7 +406,7 @@ public class IssueDetailActivity extends BaseActivity {
ImageView assigneesView = new ImageView(getApplicationContext()); ImageView assigneesView = new ImageView(getApplicationContext());
PicassoService.getInstance(ctx).get().load(singleIssue.getAssignees().get(i).getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(100, 100).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);
@ -435,7 +427,7 @@ public class IssueDetailActivity extends BaseActivity {
if(singleIssue.getLabels() != null) { if(singleIssue.getLabels() != null) {
labelsScrollView.setVisibility(View.VISIBLE); labelsScrollView.setVisibility(View.VISIBLE);
int width = 25; int width = 33;
for (int i = 0; i < singleIssue.getLabels().size(); i++) { for (int i = 0; i < singleIssue.getLabels().size(); i++) {
String labelColor = singleIssue.getLabels().get(i).getColor(); String labelColor = singleIssue.getLabels().get(i).getColor();
@ -451,11 +443,11 @@ public class IssueDetailActivity extends BaseActivity {
.beginConfig() .beginConfig()
.useFont(Typeface.DEFAULT) .useFont(Typeface.DEFAULT)
.textColor(new ColorInverter().getContrastColor(color)) .textColor(new ColorInverter().getContrastColor(color))
.fontSize(30) .fontSize(36)
.width(LabelWidthCalculator.calculateLabelWidth(labelName, Typeface.DEFAULT, 30, 15)) .width((width * labelName.length()) - ((width / 4) * labelName.length()))
.height(50) .height(60)
.endConfig() .endConfig()
.buildRoundRect(labelName, color, 10); .buildRoundRect(labelName, color, 8);
labelsView.setImageDrawable(drawable); labelsView.setImageDrawable(drawable);
labelsLayout.addView(labelsView); labelsLayout.addView(labelsView);
@ -514,11 +506,29 @@ public class IssueDetailActivity extends BaseActivity {
issueDescription.setLayoutParams(paramsDesc); issueDescription.setLayoutParams(paramsDesc);
} }
issueCreatedTime.setText(TimeHelper.formatTime(singleIssue.getCreated_at(), new Locale(locale), timeFormat, ctx)); switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(singleIssue.getCreated_at());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setVisibility(View.VISIBLE); issueCreatedTime.setVisibility(View.VISIBLE);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getCreated_at()), getApplicationContext()));
if(timeFormat.equals("pretty")) { break;
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getCreated_at()), ctx)); }
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(singleIssue.getCreated_at());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setVisibility(View.VISIBLE);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(singleIssue.getCreated_at());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setVisibility(View.VISIBLE);
break;
}
} }
if(singleIssue.getMilestone() != null) { if(singleIssue.getMilestone() != null) {
@ -557,7 +567,12 @@ public class IssueDetailActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
View.OnClickListener onClickListener = view -> finish(); View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
};
} }
} }

View File

@ -2,6 +2,7 @@ package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
@ -15,7 +16,6 @@ import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.RadioGroup; import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -23,8 +23,7 @@ import androidx.appcompat.app.AlertDialog;
import com.tooltip.Tooltip; import com.tooltip.Tooltip;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.NetworkObserver; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.VersionCheck; import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
@ -54,7 +53,6 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private RadioGroup loginMethod; private RadioGroup loginMethod;
final Context ctx = this; final Context ctx = this;
private String device_id = "token"; private String device_id = "token";
private ScrollView layoutView;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -67,7 +65,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
NetworkObserver networkMonitor = new NetworkObserver(this); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
loginButton = findViewById(R.id.login_button); loginButton = findViewById(R.id.login_button);
instanceUrlET = findViewById(R.id.instance_url); instanceUrlET = findViewById(R.id.instance_url);
@ -80,94 +78,57 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
protocolSpinner = findViewById(R.id.httpsSpinner); protocolSpinner = findViewById(R.id.httpsSpinner);
loginMethod = findViewById(R.id.loginMethod); loginMethod = findViewById(R.id.loginMethod);
loginTokenCode = findViewById(R.id.loginTokenCode); loginTokenCode = findViewById(R.id.loginTokenCode);
layoutView = findViewById(R.id.loginForm);
viewTextAppVersion.setText(AppUtil.getAppVersion(getApplicationContext())); viewTextAppVersion.setText(AppUtil.getAppVersion(getApplicationContext()));
Resources res = getResources(); Resources res = getResources();
String[] allProtocols = res.getStringArray(R.array.protocolValues); String[] allProtocols = res.getStringArray(R.array.protocolValues);
final ArrayAdapter<String> adapterProtocols = new ArrayAdapter<String>(LoginActivity.this, final ArrayAdapter<String> adapterProtocols = new ArrayAdapter<String>(Objects.requireNonNull(getApplicationContext()),
R.layout.spinner_item, allProtocols); R.layout.spinner_item, allProtocols);
adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item); adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item);
protocolSpinner.setAdapter(adapterProtocols); protocolSpinner.setAdapter(adapterProtocols);
protocolSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { protocolSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
String value = getResources().getStringArray(R.array.protocolValues)[pos]; String value = getResources().getStringArray(R.array.protocolValues)[pos];
if(value.toLowerCase().equals("http")) { if(value.toLowerCase().equals("http")) {
SnackBar.warning(getApplicationContext(), layoutView,getResources().getString(R.string.protocolError)); Toasty.info(getApplicationContext(), getResources().getString(R.string.protocolError));
} }
} }
public void onNothingSelected(AdapterView<?> parent) { public void onNothingSelected(AdapterView<?> parent) {
} }
}); });
info_button.setOnClickListener(infoListener); info_button.setOnClickListener(infoListener);
if(tinyDb.getString("loginType").equals("basic")) { // username/password if(!connToInternet) {
loginMethod.check(R.id.loginUsernamePassword); Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
return;
}
loginMethod.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if(checkedId == R.id.loginUsernamePassword){
loginUidET.setVisibility(View.VISIBLE); loginUidET.setVisibility(View.VISIBLE);
loginPassword.setVisibility(View.VISIBLE); loginPassword.setVisibility(View.VISIBLE);
otpCode.setVisibility(View.VISIBLE); otpCode.setVisibility(View.VISIBLE);
otpInfo.setVisibility(View.VISIBLE); otpInfo.setVisibility(View.VISIBLE);
loginTokenCode.setVisibility(View.GONE); loginTokenCode.setVisibility(View.GONE);
} else {
}
else {
loginMethod.check(R.id.loginToken);
loginUidET.setVisibility(View.GONE); loginUidET.setVisibility(View.GONE);
loginPassword.setVisibility(View.GONE); loginPassword.setVisibility(View.GONE);
otpCode.setVisibility(View.GONE); otpCode.setVisibility(View.GONE);
otpInfo.setVisibility(View.GONE); otpInfo.setVisibility(View.GONE);
loginTokenCode.setVisibility(View.VISIBLE); loginTokenCode.setVisibility(View.VISIBLE);
} }
loginMethod.setOnCheckedChangeListener((group, checkedId) -> {
if(checkedId == R.id.loginToken) {
loginUidET.setVisibility(View.GONE);
loginPassword.setVisibility(View.GONE);
otpCode.setVisibility(View.GONE);
otpInfo.setVisibility(View.GONE);
loginTokenCode.setVisibility(View.VISIBLE);
} }
else {
loginUidET.setVisibility(View.VISIBLE);
loginPassword.setVisibility(View.VISIBLE);
otpCode.setVisibility(View.VISIBLE);
otpInfo.setVisibility(View.VISIBLE);
loginTokenCode.setVisibility(View.GONE);
}
});
networkMonitor.onInternetStateListener(isAvailable -> {
if(isAvailable) {
enableProcessButton();
SnackBar.success(getApplicationContext(), layoutView, getResources().getString(R.string.netConnectionIsBack));
}
else {
disableProcessButton();
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.checkNetConnection));
}
}); });
//login_button.setOnClickListener(this); //login_button.setOnClickListener(this);
@ -216,7 +177,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
}; };
private View.OnClickListener infoListener = v -> new Tooltip.Builder(v) private View.OnClickListener infoListener = new View.OnClickListener() {
public void onClick(View v) {
new Tooltip.Builder(v)
.setText(R.string.urlInfoTooltip) .setText(R.string.urlInfoTooltip)
.setTextColor(getResources().getColor(R.color.white)) .setTextColor(getResources().getColor(R.color.white))
.setBackgroundColor(getResources().getColor(R.color.tooltipBackground)) .setBackgroundColor(getResources().getColor(R.color.tooltipBackground))
@ -226,6 +189,8 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
.setCornerRadius(R.dimen.tooltipCornor) .setCornerRadius(R.dimen.tooltipCornor)
.setGravity(Gravity.BOTTOM) .setGravity(Gravity.BOTTOM)
.show(); .show();
}
};
@SuppressLint("ResourceAsColor") @SuppressLint("ResourceAsColor")
private void login() { private void login() {
@ -244,8 +209,6 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
if(loginMethodType == R.id.loginUsernamePassword) { if(loginMethodType == R.id.loginUsernamePassword) {
tinyDb.putString("loginType", "basic");
if(instanceUrl.contains("@")) { if(instanceUrl.contains("@")) {
String[] urlForHttpAuth = instanceUrl.split("@"); String[] urlForHttpAuth = instanceUrl.split("@");
@ -282,7 +245,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
instanceUrl = "http://" + instanceHost + "/api/v1/"; instanceUrl = "http://" + instanceHost + "/api/v1/";
instanceUrlWithProtocol = "http://" + instanceHost; instanceUrlWithProtocol = "https://" + instanceHost;
} }
tinyDb.putString("instanceUrlRaw", instanceHost); tinyDb.putString("instanceUrlRaw", instanceHost);
@ -294,7 +257,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
if(instanceUrlET.getText().toString().equals("")) { if(instanceUrlET.getText().toString().equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.emptyFieldURL)); Toasty.info(getApplicationContext(), getString(R.string.emptyFieldURL));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -302,7 +265,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
if(loginUid.equals("")) { if(loginUid.equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.emptyFieldUsername)); Toasty.info(getApplicationContext(), getString(R.string.emptyFieldUsername));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -310,7 +273,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
if(loginPassword.getText().toString().equals("")) { if(loginPassword.getText().toString().equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.emptyFieldPassword)); Toasty.info(getApplicationContext(), getString(R.string.emptyFieldPassword));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -326,7 +289,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.loginOTPTypeError)); Toasty.info(getApplicationContext(), getString(R.string.loginOTPTypeError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -340,15 +303,13 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getString(R.string.checkNetConnection));
} }
} }
else { else {
tinyDb.putString("loginType", "token");
String instanceHost; String instanceHost;
if(AppUtil.httpCheck(instanceUrl)) { if(AppUtil.httpCheck(instanceUrl)) {
@ -373,10 +334,11 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
instanceUrl = "http://" + instanceHost + "/api/v1/"; instanceUrl = "http://" + instanceHost + "/api/v1/";
instanceUrlWithProtocol = "http://" + instanceHost; instanceUrlWithProtocol = "https://" + instanceHost;
} }
tinyDb.putString("instanceUrlRaw", instanceHost); tinyDb.putString("instanceUrlRaw", instanceHost);
//tinyDb.putString("loginUid", loginUid);
tinyDb.putString("instanceUrl", instanceUrl); tinyDb.putString("instanceUrl", instanceUrl);
tinyDb.putString("instanceUrlWithProtocol", instanceUrlWithProtocol); tinyDb.putString("instanceUrlWithProtocol", instanceUrlWithProtocol);
@ -384,7 +346,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
if (instanceUrlET.getText().toString().equals("")) { if (instanceUrlET.getText().toString().equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.emptyFieldURL)); Toasty.info(getApplicationContext(), getString(R.string.emptyFieldURL));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -392,7 +354,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
if (loginToken_.equals("")) { if (loginToken_.equals("")) {
SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.loginTokenError)); Toasty.info(getApplicationContext(), getString(R.string.loginTokenError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
return; return;
@ -403,7 +365,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.checkNetConnection)); Toasty.info(getApplicationContext(), getString(R.string.checkNetConnection));
} }
@ -413,28 +375,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private void versionCheck(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP, final String loginToken_, final int loginType) { private void versionCheck(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP, final String loginToken_, final int loginType) {
Call<GiteaVersion> callVersion; final TinyDB tinyDb = new TinyDB(getApplicationContext());
if (!loginToken_.isEmpty()) {
callVersion = RetrofitClient Call<GiteaVersion> callVersion = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getGiteaVersionWithToken(loginToken_); .getGiteaVersion();
}
else {
final String credential = Credentials.basic(loginUid, loginPass, StandardCharsets.UTF_8);
if (loginOTP != 0) {
callVersion = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getGiteaVersionWithOTP(credential,loginOTP);
}
else {
callVersion = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getGiteaVersionWithBasic(credential);
}
}
callVersion.enqueue(new Callback<GiteaVersion>() { callVersion.enqueue(new Callback<GiteaVersion>() {
@ -450,7 +396,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
switch (vt) { switch (vt) {
case UNSUPPORTED_NEW: case UNSUPPORTED_NEW:
//SnackBar.warning(getApplicationContext(), layoutView, getResources().getString(R.string.versionUnsupportedNew)); //Toasty.info(getApplicationContext(), getString(R.string.versionUnsupportedNew));
case SUPPORTED_LATEST: case SUPPORTED_LATEST:
case SUPPORTED_OLD: case SUPPORTED_OLD:
case DEVELOPMENT: case DEVELOPMENT:
@ -465,17 +411,21 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())) .setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion()))
.setCancelable(true) .setCancelable(true)
.setIcon(R.drawable.ic_warning) .setIcon(R.drawable.ic_warning)
.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> { .setNegativeButton(getString(R.string.cancelButton), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
enableProcessButton(); enableProcessButton();
}
}) })
.setPositiveButton(getString(R.string.textContinue), (dialog, which) -> { .setPositiveButton(getString(R.string.textContinue), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_); login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
}
}); });
AlertDialog alertDialog = alertDialogBuilder.create(); AlertDialog alertDialog = alertDialogBuilder.create();
@ -483,37 +433,30 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
alertDialog.show(); alertDialog.show();
return; return;
default: // UNKNOWN default: // UNKNOWN
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.versionUnknow)); Toasty.info(getApplicationContext(), getString(R.string.versionUnknow));
enableProcessButton(); enableProcessButton();
} }
} }
else if (responseVersion.code() == 403) { else if (responseVersion.code() == 403) {
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_); login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
} }
} }
private void login(int loginType, String instanceUrl, String loginUid, String loginPass, int loginOTP, String loginToken_) { private void login(int loginType, String instanceUrl, String loginUid, String loginPass, int loginOTP, String loginToken_) {
if (loginType == 1) { if (loginType == 1) {
letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP); letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP);
} }
else if (loginType == 2) { // token else if (loginType == 2) { // token
letTheUserInViaToken(instanceUrl, loginToken_); letTheUserInViaToken(instanceUrl, loginToken_);
} }
} }
@Override @Override
public void onFailure(@NonNull Call<GiteaVersion> callVersion, Throwable t) { public void onFailure(@NonNull Call<GiteaVersion> callVersion, Throwable t) {
Log.e("onFailure-version", t.toString()); Log.e("onFailure-version", t.toString());
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.errorOnLogin));
enableProcessButton();
loginButton.setText(R.string.btnLogin);
} }
@ -545,7 +488,6 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
assert userDetails != null; assert userDetails != null;
tinyDb.putString(userDetails.getLogin() + "-token", loginToken_); tinyDb.putString(userDetails.getLogin() + "-token", loginToken_);
tinyDb.putString("loginUid", userDetails.getLogin()); tinyDb.putString("loginUid", userDetails.getLogin());
tinyDb.putString("userLogin", userDetails.getUsername());
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -557,14 +499,18 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else if(response.code() == 401) { else if(response.code() == 401) {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.unauthorizedApiError)); String toastError = getResources().getString(R.string.unauthorizedApiError);
Toasty.info(getApplicationContext(), toastError);
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericApiStatusError) + response.code()); String toastError = getResources().getString(R.string.genericApiStatusError) + response.code();
Toasty.info(getApplicationContext(), toastError);
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -574,12 +520,10 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
@Override @Override
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericError)); Toasty.info(getApplicationContext(), getResources().getString(R.string.genericError));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
} }
}); });
@ -591,20 +535,16 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
Call<List<UserTokens>> call; Call<List<UserTokens>> call;
if(loginOTP != 0) { if(loginOTP != 0) {
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getUserTokensWithOTP(credential, loginOTP, loginUid); .getUserTokensWithOTP(credential, loginOTP, loginUid);
} }
else { else {
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getUserTokens(credential, loginUid); .getUserTokens(credential, loginUid);
} }
call.enqueue(new Callback<List<UserTokens>>() { call.enqueue(new Callback<List<UserTokens>>() {
@ -657,20 +597,16 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
Call<UserTokens> callCreateToken; Call<UserTokens> callCreateToken;
if(loginOTP != 0) { if(loginOTP != 0) {
callCreateToken = RetrofitClient callCreateToken = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewTokenWithOTP(credential, loginOTP, loginUid, createUserToken); .createNewTokenWithOTP(credential, loginOTP, loginUid, createUserToken);
} }
else { else {
callCreateToken = RetrofitClient callCreateToken = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.createNewToken(credential, loginUid, createUserToken); .createNewToken(credential, loginUid, createUserToken);
} }
callCreateToken.enqueue(new Callback<UserTokens>() { callCreateToken.enqueue(new Callback<UserTokens>() {
@ -688,28 +624,11 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
if (!newToken.getSha1().equals("")) { if (!newToken.getSha1().equals("")) {
Call<UserInfo> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserInfo("token " + newToken.getSha1());
call.enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(@NonNull Call<UserInfo> call, @NonNull retrofit2.Response<UserInfo> response) {
UserInfo userDetails = response.body();
if (response.isSuccessful()) {
if (response.code() == 200) {
tinyDb.remove("loginPass"); tinyDb.remove("loginPass");
tinyDb.putBoolean("loggedInMode", true); tinyDb.putBoolean("loggedInMode", true);
assert userDetails != null;
tinyDb.putString("userLogin", userDetails.getUsername());
tinyDb.putString(loginUid + "-token", newToken.getSha1()); tinyDb.putString(loginUid + "-token", newToken.getSha1());
tinyDb.putString(loginUid + "-token-last-eight", appUtil.getLastCharactersOfWord(newToken.getSha1(), 8)); tinyDb.putString(loginUid + "-token-last-eight", appUtil.getLastCharactersOfWord(newToken.getSha1(), 8));
//Log.i("Tokens", "new:" + newToken.getSha1() + " old:" + tinyDb.getString(loginUid + "-token"));
startActivity(new Intent(LoginActivity.this, MainActivity.class)); startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish(); finish();
@ -717,42 +636,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
} }
else if(response.code() == 401) {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.unauthorizedApiError));
enableProcessButton();
loginButton.setText(R.string.btnLogin);
}
else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton();
loginButton.setText(R.string.btnLogin);
}
}
@Override
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericError));
enableProcessButton();
loginButton.setText(R.string.btnLogin);
}
});
}
}
} }
else if(responseCreate.code() == 500) { else if(responseCreate.code() == 500) {
SnackBar.error(getApplicationContext(), layoutView,getResources().getString(R.string.genericApiStatusError) + responseCreate.code()); String toastError = getResources().getString(R.string.genericApiStatusError) + responseCreate.code();
Toasty.info(getApplicationContext(), toastError);
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -761,9 +650,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
@Override @Override
public void onFailure(@NonNull Call<UserTokens> createUserToken, @NonNull Throwable t) { public void onFailure(@NonNull Call<UserTokens> createUserToken, Throwable t) {
Log.e("onFailure-token", t.toString());
} }
@ -771,27 +658,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
else { else {
String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); //Log.i("Current Token", tinyDb.getString(loginUid + "-token"));
Call<UserInfo> callGetUsername = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getUserInfo(instanceToken);
callGetUsername.enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(@NonNull Call<UserInfo> call, @NonNull retrofit2.Response<UserInfo> response) {
UserInfo userDetails = response.body();
if (response.isSuccessful()) {
if (response.code() == 200) {
assert userDetails != null;
tinyDb.putString("userLogin", userDetails.getUsername());
tinyDb.putBoolean("loggedInMode", true); tinyDb.putBoolean("loggedInMode", true);
startActivity(new Intent(LoginActivity.this, MainActivity.class)); startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish(); finish();
@ -799,49 +666,22 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
} }
} }
else if(response.code() == 401) {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.unauthorizedApiError));
enableProcessButton();
loginButton.setText(R.string.btnLogin);
}
else {
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton();
loginButton.setText(R.string.btnLogin);
}
}
@Override
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
SnackBar.error(getApplicationContext(), layoutView, getResources().getString(R.string.genericError));
enableProcessButton();
loginButton.setText(R.string.btnLogin);
}
});
}
}
} }
else if(response.code() == 500) { else if(response.code() == 500) {
SnackBar.error(getApplicationContext(), layoutView,getResources().getString(R.string.genericApiStatusError) + response.code()); String toastError = getResources().getString(R.string.genericApiStatusError) + response.code();
Toasty.info(getApplicationContext(), toastError);
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
} }
else { else {
SnackBar.error(getApplicationContext(), layoutView,getResources().getString(R.string.genericApiStatusError) + response.code()); String toastError = getResources().getString(R.string.genericApiStatusError) + response.code();
//Log.i("error message else4", String.valueOf(response.code()));
Toasty.info(getApplicationContext(), toastError);
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
@ -851,12 +691,10 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
@Override @Override
public void onFailure(@NonNull Call<List<UserTokens>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<UserTokens>> call, @NonNull Throwable t) {
Log.e("onFailure-login", t.toString()); Log.e("onFailure-login", t.toString());
SnackBar.error(getApplicationContext(), layoutView,getResources().getString(R.string.malformedJson)); Toasty.info(getApplicationContext(), getResources().getString(R.string.malformedJson));
enableProcessButton(); enableProcessButton();
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
} }
}); });

View File

@ -1,6 +1,5 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.app.Activity;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -12,8 +11,6 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -23,19 +20,18 @@ import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.NetworkPolicy; import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.AboutFragment; import org.mian.gitnex.fragments.AboutFragment;
import org.mian.gitnex.fragments.ExploreRepositoriesFragment; import org.mian.gitnex.fragments.ExploreRepositoriesFragment;
import org.mian.gitnex.fragments.MyRepositoriesFragment; import org.mian.gitnex.fragments.MyRepositoriesFragment;
import org.mian.gitnex.fragments.BottomSheetNavSubMenuFragment; import org.mian.gitnex.fragments.NavSubMenuBottomSheetFragment;
import org.mian.gitnex.fragments.OrganizationsFragment; import org.mian.gitnex.fragments.OrganizationsFragment;
import org.mian.gitnex.fragments.SettingsFragment; import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.fragments.StarredRepositoriesFragment; import org.mian.gitnex.fragments.StarredRepositoriesFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.ChangeLog;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
@ -102,26 +98,31 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
if(!tinyDb.getBoolean("loggedInMode")) { if(!tinyDb.getBoolean("loggedInMode")) {
logout(this, ctx); logout();
return; return;
} }
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
toolbarTitle = toolbar.findViewById(R.id.toolbar_title); toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
switch(tinyDb.getInt("customFontId", -1)) { if(tinyDb.getInt("customFontId") == 0) {
case 0:
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/roboto.ttf"); myTypeface = Typeface.createFromAsset(getAssets(), "fonts/roboto.ttf");
break;
case 2: }
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodeproregular.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
break;
default:
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/manroperegular.ttf"); myTypeface = Typeface.createFromAsset(getAssets(), "fonts/manroperegular.ttf");
break;
}
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/roboto.ttf");
} }
@ -160,7 +161,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
ImageView navSubMenu = hView.findViewById(R.id.navSubMenu); ImageView navSubMenu = hView.findViewById(R.id.navSubMenu);
navSubMenu.setOnClickListener(new View.OnClickListener() { navSubMenu.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
BottomSheetNavSubMenuFragment bottomSheet = new BottomSheetNavSubMenuFragment(); NavSubMenuBottomSheetFragment bottomSheet = new NavSubMenuBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(), "adminMenuBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "adminMenuBottomSheet");
} }
}); });
@ -203,7 +204,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
userAvatar = hView.findViewById(R.id.userAvatar); userAvatar = hView.findViewById(R.id.userAvatar);
if (!userAvatarNav.equals("")) { if (!userAvatarNav.equals("")) {
PicassoService.getInstance(ctx).get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar); Picasso.get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
} }
userAvatar.setOnClickListener(new View.OnClickListener() { userAvatar.setOnClickListener(new View.OnClickListener() {
@ -284,23 +285,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
// Changelog popup
int versionCode = 0;
try {
PackageInfo packageInfo = getApplicationContext().getPackageManager()
.getPackageInfo(getApplicationContext().getPackageName(), 0);
versionCode = packageInfo.versionCode;
}
catch (PackageManager.NameNotFoundException e) {
Log.e("changelogDialog", Objects.requireNonNull(e.getMessage()));
}
if (versionCode > tinyDb.getInt("versionCode")) {
tinyDb.putInt("versionCode", versionCode);
tinyDb.putBoolean("versionFlag", true);
ChangeLog changelogDialog = new ChangeLog(this);
changelogDialog.showDialog();
}
} }
public void setActionBarTitle (@NonNull String title) { public void setActionBarTitle (@NonNull String title) {
@ -350,7 +334,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
new SettingsFragment()).commit(); new SettingsFragment()).commit();
break; break;
case R.id.nav_logout: case R.id.nav_logout:
logout(this, ctx); logout();
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
break; break;
case R.id.nav_about: case R.id.nav_about:
@ -388,15 +372,15 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
} }
public static void logout(Activity activity, Context ctx) { public void logout() {
TinyDB tinyDb = new TinyDB(ctx.getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
tinyDb.putBoolean("loggedInMode", false); tinyDb.putBoolean("loggedInMode", false);
tinyDb.remove("basicAuthPassword"); tinyDb.remove("basicAuthPassword");
tinyDb.putBoolean("basicAuthFlag", false); tinyDb.putBoolean("basicAuthFlag", false);
//tinyDb.clear(); //tinyDb.clear();
activity.finish(); finish();
ctx.startActivity(new Intent(ctx, LoginActivity.class)); startActivity(new Intent(MainActivity.this, LoginActivity.class));
} }
@ -404,12 +388,10 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(getApplicationContext());
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
Call<GiteaVersion> callVersion = RetrofitClient Call<GiteaVersion> callVersion = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
.getGiteaVersionWithToken(token); .getGiteaVersion();
callVersion.enqueue(new Callback<GiteaVersion>() { callVersion.enqueue(new Callback<GiteaVersion>() {
@ -486,7 +468,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
userAvatar = hView.findViewById(R.id.userAvatar); userAvatar = hView.findViewById(R.id.userAvatar);
if (!Objects.requireNonNull(userDetails).getAvatar().equals("")) { if (!Objects.requireNonNull(userDetails).getAvatar().equals("")) {
PicassoService.getInstance(ctx).get().load(userDetails.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar); Picasso.get().load(userDetails.getAvatar()).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar);
} else { } else {
userAvatar.setImageResource(R.mipmap.app_logo_round); userAvatar.setImageResource(R.mipmap.app_logo_round);
} }

View File

@ -1,20 +1,15 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import androidx.annotation.NonNull;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import com.hendraanggrian.appcompat.socialview.Mention; import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter; import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView; import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
@ -23,13 +18,10 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.MergePullRequest; import org.mian.gitnex.models.MergePullRequest;
import org.mian.gitnex.models.MergePullRequestSpinner;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
@ -47,68 +39,35 @@ public class MergePullRequestActivity extends BaseActivity {
final Context ctx = this; final Context ctx = this;
private SocialAutoCompleteTextView mergeDescription; private SocialAutoCompleteTextView mergePR;
private EditText mergeTitle;
private Spinner mergeModeSpinner;
private ArrayAdapter<Mention> defaultMentionAdapter; private ArrayAdapter<Mention> defaultMentionAdapter;
private Button mergeButton; private Button mergeButton;
private String Do;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_merge_pull_request; return R.layout.activity_merge_pull_request;
} }
@SuppressLint("SetTextI18n")
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); mergePR = findViewById(R.id.mergePR);
mergePR.setShowSoftInputOnFocus(true);
mergeModeSpinner = findViewById(R.id.mergeSpinner);
mergeDescription = findViewById(R.id.mergeDescription);
mergeTitle = findViewById(R.id.mergeTitle);
mergeTitle.requestFocus();
assert imm != null;
imm.showSoftInput(mergeTitle, InputMethodManager.SHOW_IMPLICIT);
setMergeAdapter();
mergeModeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
MergePullRequestSpinner mergeId = (MergePullRequestSpinner) parent.getSelectedItem();
Do = mergeId.getId();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
defaultMentionAdapter = new MentionArrayAdapter<>(this); defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList(); loadCollaboratorsList();
mergeDescription.setMentionAdapter(defaultMentionAdapter); mergePR.setMentionAdapter(defaultMentionAdapter);
closeActivity = findViewById(R.id.close); closeActivity = findViewById(R.id.close);
TextView toolbar_title = findViewById(R.id.toolbar_title); TextView toolbar_title = findViewById(R.id.toolbar_title);
if(!tinyDb.getString("issueTitle").isEmpty()) { if(!tinyDb.getString("issueTitle").isEmpty()) {
toolbar_title.setText(tinyDb.getString("issueTitle")); toolbar_title.setText(tinyDb.getString("issueTitle"));
mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber")+ ")");
} }
initCloseListener(); initCloseListener();
@ -120,8 +79,7 @@ public class MergePullRequestActivity extends BaseActivity {
disableProcessButton(); disableProcessButton();
} } else {
else {
mergeButton.setOnClickListener(mergePullRequest); mergeButton.setOnClickListener(mergePullRequest);
@ -129,26 +87,6 @@ public class MergePullRequestActivity extends BaseActivity {
} }
private void setMergeAdapter() {
TinyDB tinyDb = new TinyDB(getApplicationContext());
ArrayList<MergePullRequestSpinner> mergeList = new ArrayList<>();
mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge)));
mergeList.add(new MergePullRequestSpinner("rebase", getResources().getString(R.string.mergeOptionRebase)));
mergeList.add(new MergePullRequestSpinner("rebase-merge", getResources().getString(R.string.mergeOptionRebaseCommit)));
//squash merge works only on gitea v1.11.5 and higher due to a bug
if(VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) {
mergeList.add(new MergePullRequestSpinner("squash", getResources().getString(R.string.mergeOptionSquash)));
}
ArrayAdapter<MergePullRequestSpinner> adapter = new ArrayAdapter<>(MergePullRequestActivity.this, R.layout.spinner_item, mergeList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
mergeModeSpinner.setAdapter(adapter);
}
public void loadCollaboratorsList() { public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(getApplicationContext());
@ -161,7 +99,10 @@ public class MergePullRequestActivity extends BaseActivity {
final String repoOwner = parts[0]; final String repoOwner = parts[0];
final String repoName = parts[1]; final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() { call.enqueue(new Callback<List<Collaborators>>() {
@ -176,7 +117,8 @@ public class MergePullRequestActivity extends BaseActivity {
if(!response.body().get(i).getFull_name().equals("")) { if(!response.body().get(i).getFull_name().equals("")) {
fullName = response.body().get(i).getFull_name(); fullName = response.body().get(i).getFull_name();
} }
defaultMentionAdapter.add(new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url())); defaultMentionAdapter.add(
new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
} }
} }
@ -190,7 +132,6 @@ public class MergePullRequestActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.toString()); Log.i("onFailure", t.toString());
} }
@ -198,17 +139,23 @@ public class MergePullRequestActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
private View.OnClickListener mergePullRequest = v -> processMergePullRequest(); private View.OnClickListener mergePullRequest = new View.OnClickListener() {
public void onClick(View v) {
processMergePullRequest();
}
};
private void processMergePullRequest() { private void processMergePullRequest() {
String mergePRDesc = mergeDescription.getText().toString(); String mergePRDT = mergePR.getText().toString();
String mergePRTitle = mergeTitle.getText().toString();
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
if(!connToInternet) { if(!connToInternet) {
@ -219,11 +166,12 @@ public class MergePullRequestActivity extends BaseActivity {
} }
disableProcessButton(); disableProcessButton();
mergeFunction(Do, mergePRDesc, mergePRTitle); String doWhat = "merge";
mergeFunction(doWhat, mergePRDT);
} }
private void mergeFunction(String Do, String mergePRDT, String mergeTitle) { private void mergeFunction(String doWhat, String mergePRDT) {
final TinyDB tinyDb = new TinyDB(getApplicationContext()); final TinyDB tinyDb = new TinyDB(getApplicationContext());
@ -236,9 +184,12 @@ public class MergePullRequestActivity extends BaseActivity {
final String repoName = parts[1]; final String repoName = parts[1];
final int prIndex = Integer.parseInt(tinyDb.getString("issueNumber")); final int prIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle); MergePullRequest mergePR = new MergePullRequest(doWhat, mergePRDT, null);
Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().mergePullRequest(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR); Call<ResponseBody> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext())
.getApiInterface()
.mergePullRequest(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR);
call.enqueue(new Callback<ResponseBody>() { call.enqueue(new Callback<ResponseBody>() {
@ -256,7 +207,10 @@ public class MergePullRequestActivity extends BaseActivity {
else if(response.code() == 401) { else if(response.code() == 401) {
enableProcessButton(); enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); 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) { else if(response.code() == 404) {
@ -276,7 +230,6 @@ public class MergePullRequestActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
enableProcessButton(); enableProcessButton();
} }

View File

@ -6,7 +6,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
@ -33,7 +32,7 @@ import retrofit2.Callback;
* Author M M Arif * Author M M Arif
*/ */
public class CreateFileActivity extends BaseActivity { public class NewFileActivity extends BaseActivity {
public ImageView closeActivity; public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -60,8 +59,6 @@ public class CreateFileActivity extends BaseActivity {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
@ -77,10 +74,6 @@ public class CreateFileActivity extends BaseActivity {
newFileBranchName = findViewById(R.id.newFileBranchName); newFileBranchName = findViewById(R.id.newFileBranchName);
newFileCommitMessage = findViewById(R.id.newFileCommitMessage); newFileCommitMessage = findViewById(R.id.newFileCommitMessage);
newFileName.requestFocus();
assert imm != null;
imm.showSoftInput(newFileName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -293,7 +286,7 @@ public class CreateFileActivity extends BaseActivity {
} }
} }
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateFileActivity.this, ArrayAdapter<Branches> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, branchesList); R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);

View File

@ -9,7 +9,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.DatePicker; import android.widget.DatePicker;
import android.widget.EditText; import android.widget.EditText;
@ -29,7 +28,7 @@ import java.util.Calendar;
* Author M M Arif * Author M M Arif
*/ */
public class CreateMilestoneActivity extends BaseActivity implements View.OnClickListener { public class NewMilestoneActivity extends BaseActivity implements View.OnClickListener {
private EditText milestoneDueDate; private EditText milestoneDueDate;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -49,18 +48,12 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
milestoneDueDate = findViewById(R.id.milestoneDueDate); milestoneDueDate = findViewById(R.id.milestoneDueDate);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
createNewMilestoneButton = findViewById(R.id.createNewMilestoneButton); createNewMilestoneButton = findViewById(R.id.createNewMilestoneButton);
milestoneTitle = findViewById(R.id.milestoneTitle); milestoneTitle = findViewById(R.id.milestoneTitle);
milestoneDescription = findViewById(R.id.milestoneDescription); milestoneDescription = findViewById(R.id.milestoneDescription);
milestoneTitle.requestFocus();
assert imm != null;
imm.showSoftInput(milestoneTitle, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
milestoneDueDate.setOnClickListener(this); milestoneDueDate.setOnClickListener(this);

View File

@ -6,7 +6,6 @@ import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
@ -25,7 +24,7 @@ import retrofit2.Callback;
* Author M M Arif * Author M M Arif
*/ */
public class CreateOrganizationActivity extends BaseActivity { public class NewOrganizationActivity extends BaseActivity {
public ImageView closeActivity; public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -46,16 +45,10 @@ public class CreateOrganizationActivity extends BaseActivity {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
closeActivity = findViewById(R.id.close); closeActivity = findViewById(R.id.close);
orgName = findViewById(R.id.newOrganizationName); orgName = findViewById(R.id.newOrganizationName);
orgDesc = findViewById(R.id.newOrganizationDescription); orgDesc = findViewById(R.id.newOrganizationDescription);
orgName.requestFocus();
assert imm != null;
imm.showSoftInput(orgName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);

View File

@ -7,7 +7,6 @@ import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
@ -25,9 +24,7 @@ import org.mian.gitnex.models.OrganizationRepository;
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.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -35,7 +32,7 @@ import retrofit2.Callback;
* Author M M Arif * Author M M Arif
*/ */
public class CreateRepoActivity extends BaseActivity { public class NewRepoActivity extends BaseActivity {
public ImageView closeActivity; public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -46,11 +43,7 @@ public class CreateRepoActivity extends BaseActivity {
private CheckBox repoAccess; private CheckBox repoAccess;
final Context ctx = this; final Context ctx = this;
List<OrgOwner> organizationsList = new ArrayList<>(); List<OrgOwner> orgsList = new ArrayList<>();
//https://github.com/go-gitea/gitea/blob/52cfd2743c0e85b36081cf80a850e6a5901f1865/models/repo.go#L964-L967
final List<String> reservedRepoNames = Arrays.asList(".", "..");
final Pattern reservedRepoPatterns = Pattern.compile("\\.(git|wiki)$");
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -69,23 +62,17 @@ public class CreateRepoActivity extends BaseActivity {
final String userLogin = tinyDb.getString("userLogin"); final String userLogin = tinyDb.getString("userLogin");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
closeActivity = findViewById(R.id.close); closeActivity = findViewById(R.id.close);
repoName = findViewById(R.id.newRepoName); repoName = findViewById(R.id.newRepoName);
repoDesc = findViewById(R.id.newRepoDescription); repoDesc = findViewById(R.id.newRepoDescription);
repoAccess = findViewById(R.id.newRepoPrivate); repoAccess = findViewById(R.id.newRepoPrivate);
repoName.requestFocus();
assert imm != null;
imm.showSoftInput(repoName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
spinner = findViewById(R.id.ownerSpinner); spinner = findViewById(R.id.ownerSpinner);
spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP); spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getOrganizations(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), userLogin); getOrgs(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), userLogin);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
@ -111,6 +98,7 @@ public class CreateRepoActivity extends BaseActivity {
createRepo.setOnClickListener(createRepoListener); createRepo.setOnClickListener(createRepoListener);
} }
} }
private View.OnClickListener createRepoListener = new View.OnClickListener() { private View.OnClickListener createRepoListener = new View.OnClickListener() {
@ -158,23 +146,15 @@ public class CreateRepoActivity extends BaseActivity {
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorInvalid)); Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorInvalid));
}
else if (reservedRepoNames.contains(newRepoName)) {
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorReservedName));
}
else if (reservedRepoPatterns.matcher(newRepoName).find()) {
Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorReservedPatterns));
} }
else { else {
//Log.i("repoOwner", String.valueOf(repoOwner));
disableProcessButton(); disableProcessButton();
createNewRepository(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess); createNewRepository(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess);
} }
} }
private void createNewRepository(final String instanceUrl, final String token, String loginUid, String repoName, String repoDesc, String repoOwner, boolean isPrivate) { private void createNewRepository(final String instanceUrl, final String token, String loginUid, String repoName, String repoDesc, String repoOwner, boolean isPrivate) {
@ -242,11 +222,10 @@ public class CreateRepoActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
} }
}); });
} }
private void getOrganizations(String instanceUrl, String instanceToken, final String userLogin) { private void getOrgs(String instanceUrl, String instanceToken, final String userLogin) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<List<OrgOwner>> call = RetrofitClient Call<List<OrgOwner>> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
@ -261,39 +240,26 @@ public class CreateRepoActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 200) { if(response.code() == 200) {
int organizationId = 0; List<OrgOwner> orgsList_ = response.body();
List<OrgOwner> organizationsList_ = response.body(); orgsList.add(new OrgOwner(userLogin));
assert orgsList_ != null;
if(orgsList_.size() > 0) {
for (int i = 0; i < orgsList_.size(); i++) {
organizationsList.add(new OrgOwner(userLogin));
assert organizationsList_ != null;
if(organizationsList_.size() > 0) {
for (int i = 0; i < organizationsList_.size(); i++) {
if(!tinyDb.getString("organizationId").isEmpty()) {
if (Integer.parseInt(tinyDb.getString("organizationId")) == organizationsList_.get(i).getId()) {
organizationId = i + 1;
}
}
OrgOwner data = new OrgOwner( OrgOwner data = new OrgOwner(
organizationsList_.get(i).getUsername() orgsList_.get(i).getUsername()
); );
organizationsList.add(data); orgsList.add(data);
} }
} }
ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(CreateRepoActivity.this, ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(getApplicationContext(),
R.layout.spinner_item, organizationsList); R.layout.spinner_item, orgsList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
spinner.setAdapter(adapter); spinner.setAdapter(adapter);
if (tinyDb.getBoolean("organizationAction") & organizationId != 0) {
spinner.setSelection(organizationId);
tinyDb.putBoolean("organizationAction", false);
}
enableProcessButton(); enableProcessButton();
} }
@ -316,6 +282,7 @@ public class CreateRepoActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
} }
}); });
} }
private void initCloseListener() { private void initCloseListener() {

View File

@ -18,7 +18,7 @@ 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.fragments.MembersByOrgFragment; import org.mian.gitnex.fragments.MembersByOrgFragment;
import org.mian.gitnex.fragments.BottomSheetOrganizationFragment; import org.mian.gitnex.fragments.OrgBottomSheetFragment;
import org.mian.gitnex.fragments.OrganizationInfoFragment; import org.mian.gitnex.fragments.OrganizationInfoFragment;
import org.mian.gitnex.fragments.RepositoriesByOrgFragment; import org.mian.gitnex.fragments.RepositoriesByOrgFragment;
import org.mian.gitnex.fragments.TeamsByOrgFragment; import org.mian.gitnex.fragments.TeamsByOrgFragment;
@ -29,7 +29,7 @@ import java.util.Objects;
* Author M M Arif * Author M M Arif
*/ */
public class OrganizationDetailActivity extends BaseActivity implements BottomSheetOrganizationFragment.BottomSheetListener { public class OrgDetailActivity extends BaseActivity implements OrgBottomSheetFragment.BottomSheetListener {
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -50,7 +50,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
Objects.requireNonNull(getSupportActionBar()).setTitle(orgName); Objects.requireNonNull(getSupportActionBar()).setTitle(orgName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
OrganizationDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrganizationDetailActivity.SectionsPagerAdapter(getSupportFragmentManager()); OrgDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrgDetailActivity.SectionsPagerAdapter(getSupportFragmentManager());
ViewPager mViewPager = findViewById(R.id.container); ViewPager mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setAdapter(mSectionsPagerAdapter);
@ -58,20 +58,24 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
TabLayout tabLayout = findViewById(R.id.tabs); TabLayout tabLayout = findViewById(R.id.tabs);
Typeface myTypeface; Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
switch(tinyDb.getInt("customFontId", -1)) { myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
case 0: }
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/roboto.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
break;
case 2: myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default: }
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/manroperegular.ttf"); else if (tinyDb.getInt("customFontId") == 2) {
break;
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
} }
@ -114,7 +118,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
finish(); finish();
return true; return true;
case R.id.repoMenu: case R.id.repoMenu:
BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment(); OrgBottomSheetFragment bottomSheet = new OrgBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet");
return true; return true;
default: default:
@ -126,15 +130,9 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@Override @Override
public void onButtonClicked(String text) { public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
switch (text) { switch (text) {
case "repository":
tinyDb.putBoolean("organizationAction", true);
startActivity(new Intent(OrganizationDetailActivity.this, CreateRepoActivity.class));
break;
case "team": case "team":
startActivity(new Intent(OrganizationDetailActivity.this, CreateTeamByOrgActivity.class)); startActivity(new Intent(OrgDetailActivity.this, CreateTeamByOrgActivity.class));
break; break;
} }
//Log.i("clicked", text); //Log.i("clicked", text);
@ -144,7 +142,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
public class SectionsPagerAdapter extends FragmentPagerAdapter { public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) { SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); super(fm);
} }
@NonNull @NonNull
@ -153,7 +151,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
String orgName; String orgName;
if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) { if(getIntent().getStringExtra("orgName") != null || !getIntent().getStringExtra("orgName").equals("")) {
orgName = getIntent().getStringExtra("orgName"); orgName = getIntent().getStringExtra("orgName");
} }
else { else {

View File

@ -21,7 +21,7 @@ import java.util.Objects;
* Author M M Arif * Author M M Arif
*/ */
public class OrganizationTeamMembersActivity extends BaseActivity { public class OrgTeamMembersActivity extends BaseActivity {
private TextView noDataMembers; private TextView noDataMembers;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;

View File

@ -9,7 +9,6 @@ import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.util.Patterns; import android.util.Patterns;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
@ -48,16 +47,10 @@ public class ProfileEmailActivity extends BaseActivity {
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
userEmail = findViewById(R.id.userEmail); userEmail = findViewById(R.id.userEmail);
addEmailButton = findViewById(R.id.addEmailButton); addEmailButton = findViewById(R.id.addEmailButton);
userEmail.requestFocus();
assert imm != null;
imm.showSoftInput(userEmail, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);

View File

@ -9,7 +9,6 @@ import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
@ -54,8 +53,6 @@ public class ReplyToIssueActivity extends BaseActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
@ -70,10 +67,6 @@ public class ReplyToIssueActivity extends BaseActivity {
closeActivity = findViewById(R.id.close); closeActivity = findViewById(R.id.close);
TextView toolbar_title = findViewById(R.id.toolbar_title); TextView toolbar_title = findViewById(R.id.toolbar_title);
addComment.requestFocus();
assert imm != null;
imm.showSoftInput(addComment, InputMethodManager.SHOW_IMPLICIT);
if(!tinyDb.getString("issueTitle").isEmpty()) { if(!tinyDb.getString("issueTitle").isEmpty()) {
toolbar_title.setText(tinyDb.getString("issueTitle")); toolbar_title.setText(tinyDb.getString("issueTitle"));
} }

View File

@ -25,18 +25,18 @@ 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.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetRepoFragment;
import org.mian.gitnex.fragments.BranchesFragment; import org.mian.gitnex.fragments.BranchesFragment;
import org.mian.gitnex.fragments.ClosedIssuesFragment;
import org.mian.gitnex.fragments.CollaboratorsFragment; import org.mian.gitnex.fragments.CollaboratorsFragment;
import org.mian.gitnex.fragments.FilesFragment; import org.mian.gitnex.fragments.FilesFragment;
import org.mian.gitnex.fragments.IssuesMainFragment; import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.fragments.LabelsFragment; import org.mian.gitnex.fragments.LabelsFragment;
import org.mian.gitnex.fragments.MilestonesFragment; import org.mian.gitnex.fragments.MilestonesFragment;
import org.mian.gitnex.fragments.PullRequestsFragment; import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.fragments.ReleasesFragment; import org.mian.gitnex.fragments.ReleasesFragment;
import org.mian.gitnex.fragments.RepoBottomSheetFragment;
import org.mian.gitnex.fragments.RepoInfoFragment; import org.mian.gitnex.fragments.RepoInfoFragment;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository; import org.mian.gitnex.models.WatchRepository;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
@ -48,11 +48,9 @@ import android.net.Uri;
* Author M M Arif * Author M M Arif
*/ */
public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoFragment.BottomSheetListener { public class RepoDetailActivity extends BaseActivity implements RepoBottomSheetFragment.BottomSheetListener {
private TextView textViewBadgeIssue; private TextView textViewBadge;
private TextView textViewBadgePull;
private TextView textViewBadgeRelease;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -91,20 +89,24 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
TabLayout tabLayout = findViewById(R.id.tabs); TabLayout tabLayout = findViewById(R.id.tabs);
Typeface myTypeface; Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
switch(tinyDb.getInt("customFontId", -1)) { myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
case 0: }
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/roboto.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
break;
case 2: myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/manroperegular.ttf");
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/sourcecodeproregular.ttf");
break;
default: }
myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/manroperegular.ttf"); else if (tinyDb.getInt("customFontId") == 2) {
break;
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getApplicationContext()).getAssets(), "fonts/roboto.ttf");
} }
@ -124,69 +126,28 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
} }
} }
// only show Collaborators if you have permission to
final View collaboratorTab = vg.getChildAt(8);
if (tinyDb.getBoolean("isRepoAdmin")) {
collaboratorTab.setVisibility(View.VISIBLE);
}
else {
collaboratorTab.setVisibility(View.GONE);
}
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)); tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
if(tinyDb.getBoolean("enableCounterBadges")) { if(tinyDb.getBoolean("enableCounterIssueBadge")) {
@SuppressLint("InflateParams") View tabHeader2 = LayoutInflater.from(this).inflate(R.layout.badge_issue, null);
textViewBadgeIssue = tabHeader2.findViewById(R.id.counterBadgeIssue);
@SuppressLint("InflateParams") View tabHeader4 = LayoutInflater.from(this).inflate(R.layout.badge_pull, null);
textViewBadgePull = tabHeader4.findViewById(R.id.counterBadgePull);
@SuppressLint("InflateParams") View tabHeader6 = LayoutInflater.from(this).inflate(R.layout.badge_release, null);
textViewBadgeRelease = tabHeader6.findViewById(R.id.counterBadgeRelease);
textViewBadgeIssue.setVisibility(View.GONE);
textViewBadgePull.setVisibility(View.GONE);
textViewBadgeRelease.setVisibility(View.GONE);
@SuppressLint("InflateParams") View tabHeader = LayoutInflater.from(this).inflate(R.layout.badge, null);
textViewBadge = tabHeader.findViewById(R.id.counterBadge);
if(!tinyDb.getString("issuesCounter").isEmpty()) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
ColorStateList textColor = tabLayout.getTabTextColors(); }
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader);
// issue count
if (textViewBadgeIssue.getText() != "") {
TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2); TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2);
Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2); ColorStateList textColor = tabLayout.getTabTextColors();
assert tabOpenIssues != null; assert tabOpenIssues != null;
TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeIssueText); TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeText);
openIssueTabView.setTextColor(textColor); openIssueTabView.setTextColor(textColor);
}
// pull count
if (textViewBadgePull.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(4)).setCustomView(tabHeader4);
TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(4);
assert tabOpenPulls != null;
TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText);
openPullTabView.setTextColor(textColor);
}
// release count
if (VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) {
if(textViewBadgeRelease.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5);
assert tabOpenRelease != null;
TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText);
openReleaseTabView.setTextColor(textColor);
}
}
} }
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
} }
@Override @Override
@ -205,16 +166,13 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
if(tinyDb.getBoolean("enableCounterIssueBadge")) { if(tinyDb.getBoolean("enableCounterIssueBadge")) {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
} }
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.repo_dotted_menu, menu); inflater.inflate(R.menu.repo_dotted_menu, menu);
return true; return true;
} }
@Override @Override
@ -227,7 +185,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
finish(); finish();
return true; return true;
case R.id.repoMenu: case R.id.repoMenu:
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment(); RepoBottomSheetFragment bottomSheet = new RepoBottomSheetFragment();
bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet");
return true; return true;
default: default:
@ -239,8 +197,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
@Override @Override
public void onButtonClicked(String text) { public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
switch (text) { switch (text) {
case "label": case "label":
startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class)); startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class));
@ -249,7 +205,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class)); startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class));
break; break;
case "newMilestone": case "newMilestone":
startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class)); startActivity(new Intent(RepoDetailActivity.this, NewMilestoneActivity.class));
break; break;
case "addCollaborator": case "addCollaborator":
startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class)); startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class));
@ -258,18 +214,18 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class)); startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
break; break;
case "openWebRepo": case "openWebRepo":
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(tinyDb.getString("repoHtmlUrl"))); 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); startActivity(i);
break; break;
case "shareRepo":
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, tinyDb.getString("repoHtmlUrl"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, tinyDb.getString("repoHtmlUrl"));
startActivity(Intent.createChooser(sharingIntent, tinyDb.getString("repoHtmlUrl")));
break;
case "newFile": case "newFile":
startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class)); startActivity(new Intent(RepoDetailActivity.this, NewFileActivity.class));
break; break;
} }
@ -293,42 +249,42 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
Fragment fragment = null; Fragment fragment = null;
switch (position) { switch (position) {
case 0: // files case 0: // information
return FilesFragment.newInstance(repoOwner, repoName);
case 1: // information
return RepoInfoFragment.newInstance(repoOwner, repoName); return RepoInfoFragment.newInstance(repoOwner, repoName);
case 1: // files
return FilesFragment.newInstance(repoOwner, repoName);
case 2: // issues case 2: // issues
fragment = new IssuesMainFragment(); fragment = new IssuesFragment();
break;
case 3: // closed issues
fragment = new ClosedIssuesFragment();
break; break;
case 3: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 4: // pull requests case 4: // pull requests
fragment = new PullRequestsFragment(); fragment = new PullRequestsFragment();
break; break;
case 5: // releases case 5: // milestones
return ReleasesFragment.newInstance(repoOwner, repoName);
case 6: // milestones
return MilestonesFragment.newInstance(repoOwner, repoName); return MilestonesFragment.newInstance(repoOwner, repoName);
case 7: // labels case 6: // labels
return LabelsFragment.newInstance(repoOwner, repoName); return LabelsFragment.newInstance(repoOwner, repoName);
case 8: // collaborators case 7: // branches
return BranchesFragment.newInstance(repoOwner, repoName);
case 8: // releases
return ReleasesFragment.newInstance(repoOwner, repoName);
case 9: // collaborators
return CollaboratorsFragment.newInstance(repoOwner, repoName); return CollaboratorsFragment.newInstance(repoOwner, repoName);
} }
assert fragment != null;
return fragment; return fragment;
} }
@Override @Override
public int getCount() { public int getCount() {
return 9; return 10;
} }
} }
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) { private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) {
TinyDB tinyDb = new TinyDB(getApplicationContext());
Call<UserRepositories> call = RetrofitClient Call<UserRepositories> call = RetrofitClient
.getInstance(instanceUrl, getApplicationContext()) .getInstance(instanceUrl, getApplicationContext())
.getApiInterface() .getApiInterface()
@ -345,24 +301,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
if (response.code() == 200) { if (response.code() == 200) {
if(tinyDb.getBoolean("enableCounterBadges")) {
assert repoInfo != null; assert repoInfo != null;
textViewBadge.setText(repoInfo.getOpen_issues_count());
if(repoInfo.getOpen_issues_count() != null) {
textViewBadgeIssue.setVisibility(View.VISIBLE);
textViewBadgeIssue.setText(repoInfo.getOpen_issues_count());
}
if(repoInfo.getOpen_pull_count() != null) {
textViewBadgePull.setVisibility(View.VISIBLE);
textViewBadgePull.setText(repoInfo.getOpen_pull_count());
}
if(repoInfo.getRelease_count() != null) {
textViewBadgeRelease.setVisibility(View.VISIBLE);
textViewBadgeRelease.setText(repoInfo.getRelease_count());
}
}
} }
@ -377,7 +317,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -1,161 +0,0 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.items.AbstractItem;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.util.TinyDB;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* Author M M Arif
*/
public class CommitsAdapter extends AbstractItem<CommitsAdapter, CommitsAdapter.ViewHolder> {
final private Context ctx;
private String commitTitle;
private String commitHtmlUrl;
private String commitCommitter;
private Date commitDate;
private boolean isSelectable = true;
public CommitsAdapter(Context ctx) {
this.ctx = ctx;
}
public CommitsAdapter withNewItems(String commitTitle, String commitHtmlUrl, String commitCommitter, Date commitDate) {
this.setNewItems(commitTitle, commitHtmlUrl, commitCommitter, commitDate);
return this;
}
private void setNewItems(String commitTitle, String commitHtmlUrl, String commitCommitter, Date commitDate) {
this.commitTitle = commitTitle;
this.commitHtmlUrl = commitHtmlUrl;
this.commitCommitter = commitCommitter;
this.commitDate = commitDate;
}
public String getCommitTitle() {
return commitTitle;
}
private String getCommitHtmlUrl() {
return commitHtmlUrl;
}
private String getcommitCommitter() {
return commitCommitter;
}
private Date getcommitDate() {
return commitDate;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public CommitsAdapter withEnabled(boolean enabled) {
return null;
}
@Override
public boolean isSelectable() {
return isSelectable;
}
@Override
public CommitsAdapter withSelectable(boolean selectable) {
this.isSelectable = selectable;
return this;
}
@Override
public int getType() {
return R.id.commitList;
}
@Override
public int getLayoutRes() {
return R.layout.list_commits;
}
@NonNull
@Override
public CommitsAdapter.ViewHolder getViewHolder(@NonNull View v) {
return new CommitsAdapter.ViewHolder(v);
}
public class ViewHolder extends FastAdapter.ViewHolder<CommitsAdapter> {
final TinyDB tinyDb = new TinyDB(ctx);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
TextView commitTitleVw;
TextView commitCommitterVw;
TextView commitDateVw;
TextView commitHtmlUrlVw;
public ViewHolder(View itemView) {
super(itemView);
commitTitleVw = itemView.findViewById(R.id.commitTitleVw);
commitCommitterVw = itemView.findViewById(R.id.commitCommitterVw);
commitDateVw = itemView.findViewById(R.id.commitDateVw);
commitHtmlUrlVw = itemView.findViewById(R.id.commitHtmlUrlVw);
}
@Override
public void bindView(CommitsAdapter item, @NonNull List<Object> payloads) {
commitTitleVw.setText(item.getCommitTitle());
commitCommitterVw.setText(ctx.getString(R.string.commitCommittedBy, item.getcommitCommitter()));
commitDateVw.setText(TimeHelper.formatTime(item.getcommitDate(), new Locale(locale), timeFormat, ctx));
if(timeFormat.equals("pretty")) {
commitDateVw.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getcommitDate()), ctx));
}
commitHtmlUrlVw.setText(Html.fromHtml("<a href='" + item.getCommitHtmlUrl() + "'>" + ctx.getResources().getString(R.string.viewInBrowser) + "</a> "));
commitHtmlUrlVw.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
public void unbindView(@NonNull CommitsAdapter item) {
commitTitleVw.setText(null);
commitCommitterVw.setText(null);
commitDateVw.setText(null);
commitHtmlUrlVw.setText(null);
}
}
}

View File

@ -1,35 +1,32 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.lang.reflect.Field;
import java.util.List; import java.util.List;
import retrofit2.Call; import java.util.Objects;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -42,7 +39,6 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
private Context mCtx; private Context mCtx;
public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context mCtx) { public ExploreRepositoriesAdapter(List<UserRepositories> dataList, Context mCtx) {
this.mCtx = mCtx; this.mCtx = mCtx;
this.searchedReposList = dataList; this.searchedReposList = dataList;
} }
@ -50,31 +46,30 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
static class ReposSearchViewHolder extends RecyclerView.ViewHolder { static class ReposSearchViewHolder extends RecyclerView.ViewHolder {
private ImageView image; private ImageView image;
private TextView repoName; private TextView mTextView1;
private TextView repoDescription; private TextView mTextView2;
private TextView fullName; private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoForks; private TextView repoForks;
private TextView repoOpenIssuesCount; private TextView repoOpenIssuesCount;
private ReposSearchViewHolder(View itemView) { private ReposSearchViewHolder(View itemView) {
super(itemView); super(itemView);
repoName = itemView.findViewById(R.id.repoName); mTextView1 = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription); mTextView2 = itemView.findViewById(R.id.repoDescription);
image = itemView.findViewById(R.id.imageAvatar); image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
repoStars = itemView.findViewById(R.id.repoStars); repoStars = itemView.findViewById(R.id.repoStars);
repoForks = itemView.findViewById(R.id.repoForks); 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); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName); TextView repoFullName = v.findViewById(R.id.repoFullName);
@ -85,103 +80,72 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString()); tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
//store if user is watching this repo
{
final String instanceUrl = tinyDb.getString("instanceUrl");
String[] parts = repoFullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository();
Call<WatchRepository> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() {
@Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
}
}
@Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
});
}
context.startActivity(intent); context.startActivity(intent);
}
}); });
reposDropdownMenu.setOnClickListener(v -> { reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext(); final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null); PopupMenu popupMenu = new PopupMenu(context, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); Object menuHelper;
TextView repoStargazers = view.findViewById(R.id.repoStargazers); Class[] argTypes;
TextView repoWatchers = view.findViewById(R.id.repoWatchers); try {
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullName.getText()); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
BottomSheetDialog dialog = new BottomSheetDialog(context); fMenuHelper.setAccessible(true);
dialog.setContentView(view); menuHelper = fMenuHelper.get(popupMenu);
dialog.show(); argTypes = new Class[] { boolean.class };
Objects.requireNonNull(menuHelper).getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
repoOpenInBrowser.setOnClickListener(openInBrowser -> { } catch (Exception e) {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); popupMenu.show();
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText()); return;
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
}); }
repoStargazers.setOnClickListener(stargazers -> { 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 intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText()); intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); break;
}); case R.id.repoWatchers:
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class); Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText()); intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW); context.startActivity(intentW);
dialog.dismiss(); 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();
}
}); });
} }
@ -191,8 +155,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
@NonNull @NonNull
@Override @Override
public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ExploreRepositoriesAdapter.ReposSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repos_list, parent, false);
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repos, parent, false);
return new ExploreRepositoriesAdapter.ReposSearchViewHolder(v); return new ExploreRepositoriesAdapter.ReposSearchViewHolder(v);
} }
@ -202,19 +165,26 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
final UserRepositories currentItem = searchedReposList.get(position); final UserRepositories currentItem = searchedReposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.mTextView2.setVisibility(View.GONE);
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0)); String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3); TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) { if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) { if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} } else {
else {
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
} }
@ -222,10 +192,10 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
holder.repoName.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.mTextView2.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullname()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
@ -237,17 +207,11 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return searchedReposList.size(); return searchedReposList.size();
} }
} }

View File

@ -13,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Files; import org.mian.gitnex.models.Files;
import org.mian.gitnex.util.AppUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -39,7 +38,6 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
private ImageView fileTypeImage; private ImageView fileTypeImage;
private TextView fileName; private TextView fileName;
private TextView fileType; private TextView fileType;
private TextView fileInfo;
private FilesViewHolder(View itemView) { private FilesViewHolder(View itemView) {
@ -47,7 +45,6 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
fileName = itemView.findViewById(R.id.fileName); fileName = itemView.findViewById(R.id.fileName);
fileTypeImage = itemView.findViewById(R.id.fileImage); fileTypeImage = itemView.findViewById(R.id.fileImage);
fileType = itemView.findViewById(R.id.fileType); fileType = itemView.findViewById(R.id.fileType);
fileInfo = itemView.findViewById(R.id.fileInfo);
//ImageView filesDropdownMenu = itemView.findViewById(R.id.filesDropdownMenu); //ImageView filesDropdownMenu = itemView.findViewById(R.id.filesDropdownMenu);
@ -147,7 +144,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
@NonNull @NonNull
@Override @Override
public FilesAdapter.FilesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public FilesAdapter.FilesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_files, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.files_list, parent, false);
return new FilesAdapter.FilesViewHolder(v); return new FilesAdapter.FilesViewHolder(v);
} }
@ -161,8 +158,6 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
if(currentItem.getType().equals("file")) { if(currentItem.getType().equals("file")) {
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_file_new)); holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_file_new));
holder.fileInfo.setVisibility(View.VISIBLE);
holder.fileInfo.setText(AppUtil.formatFileSizeInDetail(currentItem.getSize()));
} }
else if(currentItem.getType().equals("dir")) { else if(currentItem.getType().equals("dir")) {
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_folder_24)); holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_folder_24));

View File

@ -53,14 +53,13 @@ public class FilesDiffAdapter extends RecyclerView.Adapter<FilesDiffAdapter.File
@NonNull @NonNull
@Override @Override
public FilesDiffAdapter.FilesDiffViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public FilesDiffAdapter.FilesDiffViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_files_diffs, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.files_diffs_list, parent, false);
return new FilesDiffAdapter.FilesDiffViewHolder(v); return new FilesDiffAdapter.FilesDiffViewHolder(v);
} }
@Override @Override
public void onBindViewHolder(@NonNull FilesDiffViewHolder holder, int position) { public void onBindViewHolder(@NonNull FilesDiffViewHolder holder, int position) {
holder.setIsRecyclable(false);
FileDiffView data = dataList.get(position); FileDiffView data = dataList.get(position);
if(data.isFileType()) { if(data.isFileType()) {

View File

@ -7,15 +7,15 @@ import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.text.Spanned; import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetDialog; 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.clients.PicassoService;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.models.IssueComments;
@ -23,7 +23,7 @@ import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.ocpsoft.prettytime.PrettyTime; import org.ocpsoft.prettytime.PrettyTime;
import java.sql.Time; 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.Collection;
@ -33,6 +33,8 @@ 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.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
@ -70,11 +72,8 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
private ImageView commentsOptionsMenu; private ImageView commentsOptionsMenu;
private TextView commendBodyRaw; private TextView commendBodyRaw;
private TextView commentModified; private TextView commentModified;
private TextView commenterUsername;
private TextView htmlUrl;
private IssueCommentViewHolder(View itemView) { private IssueCommentViewHolder(View itemView) {
super(itemView); super(itemView);
issueNumber = itemView.findViewById(R.id.issueNumber); issueNumber = itemView.findViewById(R.id.issueNumber);
@ -85,84 +84,75 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu); commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu);
commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw); commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw);
commentModified = itemView.findViewById(R.id.commentModified); commentModified = itemView.findViewById(R.id.commentModified);
commenterUsername = itemView.findViewById(R.id.commenterUsername);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
commentsOptionsMenu.setOnClickListener(v -> { commentsOptionsMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext(); final Context context = v.getContext();
final TinyDB tinyDb = new TinyDB(context); //Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
final String loginUid = tinyDb.getString("loginUid");
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_issue_comments, null); PopupMenu popupMenu = new PopupMenu(context, v);
popupMenu.inflate(R.menu.issue_comment_menu);
TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit); Object menuHelper;
TextView commentShare = view.findViewById(R.id.issueCommentShare); Class[] argTypes;
//TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete); 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;
if(!loginUid.contentEquals(commenterUsername.getText())) {
commentMenuEdit.setVisibility(View.GONE);
//commentMenuDelete.setVisibility(View.GONE);
} }
BottomSheetDialog dialog = new BottomSheetDialog(context); popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
dialog.setContentView(view); @Override
dialog.show(); public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
commentMenuEdit.setOnClickListener(ediComment -> { case R.id.commentMenuEdit:
Intent intent = new Intent(context, ReplyToIssueActivity.class); Intent intent = new Intent(context, ReplyToIssueActivity.class);
intent.putExtra("commentId", commendId.getText()); intent.putExtra("commentId", commendId.getText());
intent.putExtra("commentAction", "edit"); intent.putExtra("commentAction", "edit");
intent.putExtra("commentBody", commendBodyRaw.getText()); intent.putExtra("commentBody", commendBodyRaw.getText());
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); break;
case R.id.commentMenuDelete:
break;
}
return false;
}
}); });
commentShare.setOnClickListener(ediComment -> { popupMenu.show();
// get comment Url
CharSequence commentUrl = htmlUrl.getText();
// share issue comment
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
String intentHeader = tinyDb.getString("issueNumber") + context.getResources().getString(R.string.hash) + "issuecomment-" + commendId.getText() + " " + tinyDb.getString("issueTitle");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, intentHeader);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, commentUrl);
context.startActivity(Intent.createChooser(sharingIntent, intentHeader));
dialog.dismiss();
});
/*commentMenuDelete.setOnClickListener(deleteComment -> {
dialog.dismiss();
});*/
}
}); });
} }
} }
public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) { public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {
this.mCtx = mCtx; this.mCtx = mCtx;
this.issuesComments = issuesCommentsMain; this.issuesComments = issuesCommentsMain;
} }
@NonNull @NonNull
@Override @Override
public IssueCommentsAdapter.IssueCommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public IssueCommentsAdapter.IssueCommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.issue_comments, parent, false);
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_issue_comments, parent, false);
return new IssueCommentsAdapter.IssueCommentViewHolder(v); return new IssueCommentsAdapter.IssueCommentViewHolder(v);
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@ -172,58 +162,61 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
final TinyDB tinyDb = new TinyDB(mCtx); final TinyDB tinyDb = new TinyDB(mCtx);
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 String loginUid = tinyDb.getString("loginUid");
IssueComments currentItem = issuesComments.get(position); IssueComments currentItem = issuesComments.get(position);
holder.htmlUrl.setText(currentItem.getHtml_url()); if(!loginUid.equals(currentItem.getUser().getUsername())) {
holder.commenterUsername.setText(currentItem.getUser().getUsername()); holder.commentsOptionsMenu.setVisibility(View.INVISIBLE);
}
holder.commendId.setText(String.valueOf(currentItem.getId())); holder.commendId.setText(String.valueOf(currentItem.getId()));
holder.commendBodyRaw.setText(currentItem.getBody()); holder.commendBodyRaw.setText(currentItem.getBody());
if (!currentItem.getUser().getFull_name().equals("")) { if (!currentItem.getUser().getFull_name().equals("")) {
holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getFull_name(), mCtx)); holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getFull_name(), mCtx));
} } else {
else {
holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getLogin(), mCtx)); holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getLogin(), mCtx));
} }
PicassoService.getInstance(mCtx).get().load(currentItem.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar); if (currentItem.getUser().getAvatar_url() != null) {
Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);
} else {
Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.issueCommenterAvatar);
}
String cleanIssueComments = currentItem.getBody().trim(); String cleanIssueComments = currentItem.getBody().trim();
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)).usePlugin(CorePlugin.create()).usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() { final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override @Override
public void configureImages(@NonNull ImagesPlugin plugin) { public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() { plugin.addSchemeHandler(new SchemeHandler() {
@NonNull @NonNull
@Override @Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = mCtx.getResources().getIdentifier(raw.substring("drawable://".length()), "drawable", mCtx.getPackageName()); final int resourceId = mCtx.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
mCtx.getPackageName());
final Drawable drawable = mCtx.getDrawable(resourceId); final Drawable drawable = mCtx.getDrawable(resourceId);
assert drawable != null; assert drawable != null;
return ImageItem.withResult(drawable); return ImageItem.withResult(drawable);
} }
@NonNull @NonNull
@Override @Override
public Collection<String> supportedSchemes() { public Collection<String> supportedSchemes() {
return Collections.singleton("drawable"); return Collections.singleton("drawable");
} }
}); });
plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() { plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable @Nullable
@Override @Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) { public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null; return null;
} }
}); });
@ -233,15 +226,22 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources())); plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); 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")).codeBackgroundColor(tinyDb.getInt("codeBlockBackground")).linkColor(mCtx.getResources().getColor(R.color.lightBlue)); .codeTextColor(tinyDb.getInt("codeBlockColor"))
.codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(mCtx.getResources().getColor(R.color.lightBlue));
} }
})
}).usePlugin(TablePlugin.create(mCtx)).usePlugin(TaskListPlugin.create(mCtx)).usePlugin(HtmlPlugin.create()).usePlugin(StrikethroughPlugin.create()).usePlugin(LinkifyPlugin.create()).build(); .usePlugin(TablePlugin.create(mCtx))
.usePlugin(TaskListPlugin.create(mCtx))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments)); Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
markwon.setParsedMarkdown(holder.issueComment, UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments)); markwon.setParsedMarkdown(holder.issueComment, UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments));
@ -249,31 +249,42 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
String edited; String edited;
if(!currentItem.getUpdated_at().equals(currentItem.getCreated_at())) { if(!currentItem.getUpdated_at().equals(currentItem.getCreated_at())) {
edited = mCtx.getResources().getString(R.string.colorfulBulletSpan) + mCtx.getResources().getString(R.string.modifiedText); edited = mCtx.getResources().getString(R.string.colorfulBulletSpan) + mCtx.getResources().getString(R.string.modifiedText);
holder.commentModified.setVisibility(View.VISIBLE); holder.commentModified.setVisibility(View.VISIBLE);
holder.commentModified.setText(edited); holder.commentModified.setText(edited);
holder.commentModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), mCtx)); holder.commentModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), mCtx));
} }
else { else {
holder.commentModified.setVisibility(View.INVISIBLE); holder.commentModified.setVisibility(View.INVISIBLE);
} }
holder.issueCommentDate.setText(TimeHelper.formatTime(currentItem.getCreated_at(), new Locale(locale), timeFormat, mCtx)); switch (timeFormat) {
case "pretty": {
if(timeFormat.equals("pretty")) { PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx)); holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx));
break;
} }
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(currentItem.getCreated_at());
holder.issueCommentDate.setText(createdTime);
break;
}
}
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return issuesComments.size(); return issuesComments.size();
} }
} }

View File

@ -1,150 +1,118 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.Html; import android.text.Html;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import com.squareup.picasso.Picasso;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.items.AbstractItem;
import com.mikepenz.fastadapter.listeners.ClickEventHook;
import com.mikepenz.fastadapter.utils.EventHookUtil;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB; 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.Date; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class IssuesAdapter extends AbstractItem<IssuesAdapter, IssuesAdapter.ViewHolder> { public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
final private Context ctx; private Context context;
private String issueTitle; private final int TYPE_LOAD = 0;
private int issueNumber; private List<Issues> issuesList;
private String issueAssigneeAvatar; private List<Issues> issuesListFull;
private Date issueCreatedTime; private OnLoadMoreListener loadMoreListener;
private int issueCommentsCount; private boolean isLoading = false, isMoreDataAvailable = true;
private String userFullname;
private String userLogin;
private boolean isSelectable = true; public IssuesAdapter(Context context, List<Issues> issuesListMain) {
public IssuesAdapter(Context ctx) { this.context = context;
this.ctx = ctx; this.issuesList = issuesListMain;
} issuesListFull = new ArrayList<>(issuesList);
public IssuesAdapter withNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) {
this.setNewItems(issueTitle, issueNumber, issueAssigneeAvatar, issueCreatedTime, issueCommentsCount, userFullname, userLogin);
return this;
}
private void setNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) {
this.issueTitle = issueTitle;
this.issueNumber = issueNumber;
this.issueAssigneeAvatar = issueAssigneeAvatar;
this.issueCreatedTime = issueCreatedTime;
this.issueCommentsCount = issueCommentsCount;
this.userFullname = userFullname;
this.userLogin = userLogin;
}
private int getIssueNumber() {
return issueNumber;
}
public String getIssueTitle() {
return issueTitle;
}
private String getIssueAssigneeAvatar() {
return issueAssigneeAvatar;
}
private Date getIssueCreatedTime() {
return issueCreatedTime;
}
private int getIssueCommentsCount() {
return issueCommentsCount;
}
private String getUserFullname() {
return userFullname;
}
private String getUserLogin() {
return userLogin;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public IssuesAdapter withEnabled(boolean enabled) {
return null;
}
@Override
public boolean isSelectable() {
return isSelectable;
}
@Override
public IssuesAdapter withSelectable(boolean selectable) {
this.isSelectable = selectable;
return this;
}
@Override
public int getType() {
return R.id.relativeLayoutFrameIssuesList;
}
@Override
public int getLayoutRes() {
return R.layout.list_issues;
} }
@NonNull @NonNull
@Override @Override
public IssuesAdapter.ViewHolder getViewHolder(@NonNull View v) { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new IssuesAdapter.ViewHolder(v);
LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD){
return new IssuesHolder(inflater.inflate(R.layout.repo_detail_issues_list, parent,false));
}
else {
return new LoadHolder(inflater.inflate(R.layout.row_load,parent,false));
} }
public class ViewHolder extends FastAdapter.ViewHolder<IssuesAdapter> { }
final TinyDB tinyDb = new TinyDB(ctx); @Override
final String locale = tinyDb.getString("locale"); public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
final String timeFormat = tinyDb.getString("dateFormat");
if(position >= getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if(getItemViewType(position) == TYPE_LOAD) {
((IssuesHolder)holder).bindData(issuesList.get(position));
}
}
@Override
public int getItemViewType(int position) {
if(issuesList.get(position).getTitle() != null) {
return TYPE_LOAD;
}
else {
return 1;
}
}
@Override
public int getItemCount() {
return issuesList.size();
}
class IssuesHolder extends RecyclerView.ViewHolder {
private TextView issueNumber; private TextView issueNumber;
private ImageView issueAssigneeAvatar; private ImageView issueAssigneeAvatar;
private TextView issueTitle; private TextView issueTitle;
private TextView issueCreatedTime; private TextView issueCreatedTime;
private TextView issueCommentsCount; private TextView issueCommentsCount;
private RelativeLayout relativeLayoutFrame;
public ViewHolder(View itemView) { IssuesHolder(View itemView) {
super(itemView); super(itemView);
@ -152,94 +120,172 @@ public class IssuesAdapter extends AbstractItem<IssuesAdapter, IssuesAdapter.Vie
issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
issueTitle = itemView.findViewById(R.id.issueTitle); issueTitle = itemView.findViewById(R.id.issueTitle);
issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount); issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime); issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
relativeLayoutFrame = itemView.findViewById(R.id.relativeLayoutFrame);
} issueTitle.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void bindView(@NonNull IssuesAdapter item, @NonNull List<Object> payloads) { public void onClick(View v) {
if (!item.getUserFullname().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserFullname(), ctx));
}
else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserLogin(), ctx));
}
PicassoService.getInstance(ctx).get().load(item.getIssueAssigneeAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
String issueNumber_ = "<font color='" + ctx.getResources().getColor(R.color.lightGray) + "'>" + ctx.getResources().getString(R.string.hash) + item.getIssueNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + item.getIssueTitle()));
issueNumber.setText(String.valueOf(item.getIssueNumber()));
issueCommentsCount.setText(String.valueOf(item.getIssueCommentsCount()));
switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getIssueCreatedTime()), ctx));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(item.getIssueCreatedTime());
issueCreatedTime.setText(createdTime);
break;
}
}
}
@Override
public void unbindView(@NonNull IssuesAdapter item) {
issueTitle.setText(null);
issueCommentsCount.setText(null);
issueCreatedTime.setText(null);
}
}
public static class IssueTitleClickEvent extends ClickEventHook<IssuesAdapter> {
@Nullable
@Override
public List<View> onBindMany(@NonNull RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof IssuesAdapter.ViewHolder) {
return EventHookUtil.toList(((ViewHolder) viewHolder).issueTitle);
}
return super.onBindMany(viewHolder);
}
@Override
public void onClick(View v, int position, @NonNull FastAdapter<IssuesAdapter> fastAdapter, IssuesAdapter item) {
Context context = v.getContext(); Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
Intent intent = new Intent(context, IssueDetailActivity.class); Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", item.getIssueNumber()); intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", String.valueOf(item.getIssueNumber())); tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue"); tinyDb.putString("issueType", "issue");
context.startActivity(intent); context.startActivity(intent);
} }
});
frameCommentsCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
//Log.i("issueNumber", issueNumber.getText().toString());
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "issue");
context.startActivity(intent);
}
});
} }
@SuppressLint("SetTextI18n")
void bindData(Issues issuesModel){
final TinyDB tinyDb = new TinyDB(context);
final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat");
/*if(issuesModel.getPull_request() != null) {
if (!issuesModel.getPull_request().isMerged()) {
relativeLayoutFrame.setVisibility(View.GONE);
relativeLayoutFrame.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
}
}*/
if (!issuesModel.getUser().getFull_name().equals("")) {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context));
} else {
issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
}
if (issuesModel.getUser().getAvatar_url() != null) {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
} else {
Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar);
}
String issueNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + "</font>";
issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle()));
issueNumber.setText(String.valueOf(issuesModel.getNumber()));
issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(issuesModel.getCreated_at());
issueCreatedTime.setText(createdTime);
break;
}
}
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
@Override
public Filter getFilter() {
return issuesFilter;
}
private Filter issuesFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Issues> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(issuesList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Issues item : issuesList) {
if (item.getTitle().toLowerCase().contains(filterPattern) || item.getBody().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
issuesList.clear();
issuesList.addAll((List) results.values);
notifyDataSetChanged();
}
};
} }

View File

@ -1,27 +1,28 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
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.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.CreateLabelActivity; import org.mian.gitnex.activities.CreateLabelActivity;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.ColorInverter; import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.LabelWidthCalculator; import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.models.Labels; import org.mian.gitnex.models.Labels;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
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;
/** /**
@ -50,23 +51,39 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
labelId = itemView.findViewById(R.id.labelId); labelId = itemView.findViewById(R.id.labelId);
labelColor = itemView.findViewById(R.id.labelColor); labelColor = itemView.findViewById(R.id.labelColor);
labelsOptionsMenu.setOnClickListener(v -> { labelsOptionsMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext(); final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
@SuppressLint("InflateParams") PopupMenu popupMenu = new PopupMenu(context, v);
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_labels_in_list, null); popupMenu.inflate(R.menu.labels_menu);
TextView labelMenuEdit = view.findViewById(R.id.labelMenuEdit); Object menuHelper;
TextView labelMenuDelete = view.findViewById(R.id.labelMenuDelete); Class[] argTypes;
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); try {
bottomSheetHeader.setText(labelTitle.getText()); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
BottomSheetDialog dialog = new BottomSheetDialog(context); fMenuHelper.setAccessible(true);
dialog.setContentView(view); menuHelper = fMenuHelper.get(popupMenu);
dialog.show(); argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
labelMenuEdit.setOnClickListener(editLabel -> { } catch (Exception e) {
popupMenu.show();
return;
}
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.labelMenuEdit:
Intent intent = new Intent(context, CreateLabelActivity.class); Intent intent = new Intent(context, CreateLabelActivity.class);
intent.putExtra("labelId", labelId.getText()); intent.putExtra("labelId", labelId.getText());
@ -74,21 +91,25 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
intent.putExtra("labelColor", labelColor.getText()); intent.putExtra("labelColor", labelColor.getText());
intent.putExtra("labelAction", "edit"); intent.putExtra("labelAction", "edit");
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); break;
}); case R.id.labelMenuDelete:
labelMenuDelete.setOnClickListener(deleteLabel -> {
AlertDialogs.labelDeleteDialog(context, labelTitle.getText().toString(), labelId.getText().toString(), AlertDialogs.labelDeleteDialog(context, labelTitle.getText().toString(), labelId.getText().toString(),
context.getResources().getString(R.string.labelDeleteTitle), context.getResources().getString(R.string.labelDeleteTitle),
context.getResources().getString(R.string.labelDeleteMessage), context.getResources().getString(R.string.labelDeleteMessage),
context.getResources().getString(R.string.labelDeletePositiveButton), context.getResources().getString(R.string.labelDeletePositiveButton),
context.getResources().getString(R.string.labelDeleteNegativeButton)); context.getResources().getString(R.string.labelDeleteNegativeButton));
dialog.dismiss(); break;
}
return false;
}
}); });
popupMenu.show();
}
}); });
} }
@ -102,7 +123,7 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
@NonNull @NonNull
@Override @Override
public LabelsAdapter.LabelsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public LabelsAdapter.LabelsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_labels, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.labels_list, parent, false);
return new LabelsAdapter.LabelsViewHolder(v); return new LabelsAdapter.LabelsViewHolder(v);
} }
@ -110,6 +131,7 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
public void onBindViewHolder(@NonNull LabelsAdapter.LabelsViewHolder holder, int position) { public void onBindViewHolder(@NonNull LabelsAdapter.LabelsViewHolder holder, int position) {
Labels currentItem = labelsList.get(position); Labels currentItem = labelsList.get(position);
int width = 33;
holder.labelTitle.setText(currentItem.getName()); holder.labelTitle.setText(currentItem.getName());
holder.labelId.setText(String.valueOf(currentItem.getId())); holder.labelId.setText(String.valueOf(currentItem.getId()));
@ -117,24 +139,35 @@ public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsView
String labelColor = currentItem.getColor(); String labelColor = currentItem.getColor();
String labelName = currentItem.getName(); String labelName = currentItem.getName();
int color = Color.parseColor("#" + labelColor); int color = Color.parseColor("#" + labelColor);
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
.useFont(Typeface.DEFAULT) //.useFont(Typeface.DEFAULT)
.bold() .bold()
.textColor(new ColorInverter().getContrastColor(color)) .textColor(new ColorInverter().getContrastColor(color))
.fontSize(35) .fontSize(36)
.width(LabelWidthCalculator.calculateLabelWidth(labelName, Typeface.DEFAULT, 40, 20)) .width(LabelWidthCalculator.customWidth(getMaxLabelLength()))
.height(55) .height(60)
.endConfig() .endConfig()
.buildRoundRect(labelName, color, 10); .buildRoundRect(labelName, color, 8);
holder.labelsView.setImageDrawable(drawable); holder.labelsView.setImageDrawable(drawable);
} }
private int getMaxLabelLength() {
for(int i = 0; i < labelsList.size(); i++) {
Labels labelItem = labelsList.get(i);
labelsArray.add(labelItem.getName().length());
}
return Collections.max(labelsArray);
}
@Override @Override
public int getItemCount() { public int getItemCount() {
return labelsList.size(); return labelsList.size();

View File

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

View File

@ -15,10 +15,8 @@ import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.MilestoneActions;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
@ -34,6 +32,7 @@ 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 io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
@ -43,6 +42,7 @@ import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.AsyncDrawable;
import io.noties.markwon.image.DefaultMediaDecoder; import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem; import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin; import io.noties.markwon.image.ImagesPlugin;
@ -63,7 +63,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
static class MilestonesViewHolder extends RecyclerView.ViewHolder { static class MilestonesViewHolder extends RecyclerView.ViewHolder {
private TextView milestoneId;
private TextView msTitle; private TextView msTitle;
private TextView msDescription; private TextView msDescription;
private TextView msOpenIssues; private TextView msOpenIssues;
@ -71,12 +70,10 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
private TextView msDueDate; private TextView msDueDate;
private ImageView msStatus; private ImageView msStatus;
private ProgressBar msProgress; private ProgressBar msProgress;
private TextView milestoneStatus;
private MilestonesViewHolder(View itemView) { private MilestonesViewHolder(View itemView) {
super(itemView); super(itemView);
milestoneId = itemView.findViewById(R.id.milestoneId);
msTitle = itemView.findViewById(R.id.milestoneTitle); msTitle = itemView.findViewById(R.id.milestoneTitle);
msStatus = itemView.findViewById(R.id.milestoneState); msStatus = itemView.findViewById(R.id.milestoneState);
msDescription = itemView.findViewById(R.id.milestoneDescription); msDescription = itemView.findViewById(R.id.milestoneDescription);
@ -84,52 +81,23 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
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); msProgress = itemView.findViewById(R.id.milestoneProgress);
ImageView milestonesMenu = itemView.findViewById(R.id.milestonesMenu);
milestoneStatus = itemView.findViewById(R.id.milestoneStatus);
milestonesMenu.setOnClickListener(v -> { /*msTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context ctx = v.getContext(); Context context = v.getContext();
int milestoneId_ = Integer.parseInt(milestoneId.getText().toString()); Log.i("issueNumber", issueNumber.getText().toString());
@SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_milestones_in_list, null); Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
TextView closeMilestone = view.findViewById(R.id.closeMilestone); TinyDB tinyDb = new TinyDB(context);
TextView openMilestone = view.findViewById(R.id.openMilestone); tinyDb.putString("issueNumber", issueNumber.getText().toString());
context.startActivity(intent);
BottomSheetDialog dialog = new BottomSheetDialog(ctx);
dialog.setContentView(view);
dialog.show();
if(milestoneStatus.getText().toString().equals("open")) {
closeMilestone.setVisibility(View.VISIBLE);
openMilestone.setVisibility(View.GONE);
} }
else { });*/
closeMilestone.setVisibility(View.GONE);
openMilestone.setVisibility(View.VISIBLE);
}
closeMilestone.setOnClickListener(v12 -> {
MilestoneActions.closeMilestone(ctx, milestoneId_);
dialog.dismiss();
});
openMilestone.setOnClickListener(v12 -> {
MilestoneActions.openMilestone(ctx, milestoneId_);
dialog.dismiss();
});
});
} }
} }
@ -142,7 +110,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
@NonNull @NonNull
@Override @Override
public MilestonesAdapter.MilestonesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public MilestonesAdapter.MilestonesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_milestones, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.milestones_list, parent, false);
return new MilestonesAdapter.MilestonesViewHolder(v); return new MilestonesAdapter.MilestonesViewHolder(v);
} }
@ -155,12 +123,11 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
Milestones currentItem = milestonesList.get(position); Milestones currentItem = milestonesList.get(position);
holder.milestoneId.setText(String.valueOf(currentItem.getId()));
holder.milestoneStatus.setText(currentItem.getState());
final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)) final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
.usePlugin(CorePlugin.create()) .usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> { .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
@Override
public void configureImages(@NonNull ImagesPlugin plugin) {
plugin.addSchemeHandler(new SchemeHandler() { plugin.addSchemeHandler(new SchemeHandler() {
@NonNull @NonNull
@Override @Override
@ -183,12 +150,19 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
return Collections.singleton("drawable"); return Collections.singleton("drawable");
} }
}); });
plugin.placeholderProvider(drawable -> null); plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
@Nullable
@Override
public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
return null;
}
});
plugin.addMediaDecoder(GifMediaDecoder.create(false)); plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources())); plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create()); plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources())); plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}
})) }))
.usePlugin(new AbstractMarkwonPlugin() { .usePlugin(new AbstractMarkwonPlugin() {
@Override @Override
@ -208,6 +182,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
Spanned msTitle = markwon.toMarkdown(currentItem.getTitle()); Spanned msTitle = markwon.toMarkdown(currentItem.getTitle());
markwon.setParsedMarkdown(holder.msTitle, msTitle); markwon.setParsedMarkdown(holder.msTitle, msTitle);
//holder.msStatus.setText(currentItem.getState());
if(currentItem.getState().equals("open")) { if(currentItem.getState().equals("open")) {
@ -249,7 +224,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
holder.msDescription.setText(bodyWithMD); holder.msDescription.setText(bodyWithMD);
} }
else { else {
holder.msDescription.setText(""); holder.msDescription.setVisibility(View.GONE);
} }
holder.msOpenIssues.setText(String.valueOf(currentItem.getOpen_issues())); holder.msOpenIssues.setText(String.valueOf(currentItem.getOpen_issues()));
@ -286,14 +261,13 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
} catch (ParseException e) { } catch (ParseException e) {
e.printStackTrace(); e.printStackTrace();
} }
assert date != null;
String dueDate = formatter.format(date); String dueDate = formatter.format(date);
assert date != null;
if(date.before(new Date())) { if(date.before(new Date())) {
holder.msDueDate.setTextColor(mCtx.getResources().getColor(R.color.darkRed)); holder.msDueDate.setTextColor(mCtx.getResources().getColor(R.color.darkRed));
} }
holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate)); holder.msDueDate.setText(dueDate);
holder.msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(currentItem.getDue_on()), mCtx)); holder.msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(currentItem.getDue_on()), mCtx));
} else if (timeFormat.equals("normal1")) { } else if (timeFormat.equals("normal1")) {
@ -304,14 +278,13 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
} catch (ParseException e) { } catch (ParseException e) {
e.printStackTrace(); e.printStackTrace();
} }
assert date1 != null;
String dueDate = formatter.format(date1); String dueDate = formatter.format(date1);
holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate)); holder.msDueDate.setText(dueDate);
} }
} }
else { else {
holder.msDueDate.setText(""); holder.msDueDate.setVisibility(View.GONE);
} }
} }
@ -327,7 +300,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
} }
private Filter milestoneFilter = new Filter() { private Filter milestoneFilter = new Filter() {
@Override @Override
protected FilterResults performFiltering(CharSequence constraint) { protected FilterResults performFiltering(CharSequence constraint) {
List<Milestones> filteredList = new ArrayList<>(); List<Milestones> filteredList = new ArrayList<>();
@ -356,7 +328,6 @@ public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.Mi
milestonesList.addAll((List) results.values); milestonesList.addAll((List) results.values);
notifyDataSetChanged(); notifyDataSetChanged();
} }
}; };
} }

View File

@ -1,10 +1,10 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Filter; import android.widget.Filter;
@ -13,25 +13,22 @@ 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.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository;
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;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -68,7 +65,9 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
@ -78,104 +77,73 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullNameMy.getText().toString()); tinyDb.putString("repoFullName", fullNameMy.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString()); tinyDb.putString("repoType", repoType.getText().toString());
//tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
//store if user is watching this repo
{
final String instanceUrl = tinyDb.getString("instanceUrl");
String[] parts = fullNameMy.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository();
Call<WatchRepository> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() {
@Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
}
}
@Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
});
}
context.startActivity(intent); context.startActivity(intent);
}
}); });
reposDropdownMenu.setOnClickListener(v -> { reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext(); final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
@SuppressLint("InflateParams") PopupMenu popupMenu = new PopupMenu(context, v);
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null); popupMenu.inflate(R.menu.repo_dotted_list_menu);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); Object menuHelper;
TextView repoStargazers = view.findViewById(R.id.repoStargazers); Class[] argTypes;
TextView repoWatchers = view.findViewById(R.id.repoWatchers); try {
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullNameMy.getText()); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
BottomSheetDialog dialog = new BottomSheetDialog(context); fMenuHelper.setAccessible(true);
dialog.setContentView(view); menuHelper = fMenuHelper.get(popupMenu);
dialog.show(); argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
repoOpenInBrowser.setOnClickListener(openInBrowser -> { } catch (Exception e) {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); popupMenu.show();
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullNameMy.getText()); return;
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
}); }
repoStargazers.setOnClickListener(stargazers -> { 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 intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullNameMy.getText()); intent.putExtra("repoFullNameForStars", fullNameMy.getText());
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); break;
}); case R.id.repoWatchers:
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class); Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullNameMy.getText()); intentW.putExtra("repoFullNameForWatchers", fullNameMy.getText());
context.startActivity(intentW); context.startActivity(intentW);
dialog.dismiss(); 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();
}
}); });
} }
@ -190,7 +158,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
@NonNull @NonNull
@Override @Override
public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_my_repos, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_repos_list, parent, false);
return new MyReposListAdapter.MyReposViewHolder(v); return new MyReposListAdapter.MyReposViewHolder(v);
} }
@ -216,7 +184,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
if (currentItem.getAvatar_url() != null) { if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) { if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.imageMy); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.imageMy);
} else { } else {
holder.imageMy.setImageDrawable(drawable); holder.imageMy.setImageDrawable(drawable);
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -14,9 +14,9 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
@ -57,7 +57,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
LayoutInflater inflater = LayoutInflater.from(context); LayoutInflater inflater = LayoutInflater.from(context);
if(viewType == TYPE_LOAD){ if(viewType == TYPE_LOAD){
return new PullRequestsAdapter.PullRequestsHolder(inflater.inflate(R.layout.list_pr, parent,false)); return new PullRequestsAdapter.PullRequestsHolder(inflater.inflate(R.layout.repo_pr_list, parent,false));
} }
else { else {
return new PullRequestsAdapter.LoadHolder(inflater.inflate(R.layout.row_load,parent,false)); return new PullRequestsAdapter.LoadHolder(inflater.inflate(R.layout.row_load,parent,false));
@ -170,9 +170,9 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
} }
if (prModel.getUser().getAvatar_url() != null) { if (prModel.getUser().getAvatar_url() != null) {
PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); Picasso.get().load(prModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
} else { } else {
PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); Picasso.get().load(prModel.getUser().getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
} }
String prNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + prModel.getNumber() + "</font>"; String prNumber_ = "<font color='" + context.getResources().getColor(R.color.lightGray) + "'>" + context.getResources().getString(R.string.hash) + prModel.getNumber() + "</font>";
@ -181,10 +181,26 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
prNumber.setText(String.valueOf(prModel.getNumber())); prNumber.setText(String.valueOf(prModel.getNumber()));
prCommentsCount.setText(String.valueOf(prModel.getComments())); prCommentsCount.setText(String.valueOf(prModel.getComments()));
prCreatedTime.setText(TimeHelper.formatTime(prModel.getCreated_at(), new Locale(locale), timeFormat, context)); switch (timeFormat) {
case "pretty": {
if(timeFormat.equals("pretty")) { PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(prModel.getCreated_at());
prCreatedTime.setText(createdTime);
prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context)); prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context));
break;
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(prModel.getCreated_at());
prCreatedTime.setText(createdTime);
break;
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
String createdTime = formatter.format(prModel.getCreated_at());
prCreatedTime.setText(createdTime);
break;
}
} }
} }

View File

@ -80,7 +80,7 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
@NonNull @NonNull
@Override @Override
public ReleasesAdapter.ReleasesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ReleasesAdapter.ReleasesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_releases, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.releases_list, parent, false);
return new ReleasesAdapter.ReleasesViewHolder(v); return new ReleasesAdapter.ReleasesViewHolder(v);
} }

View File

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

View File

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

View File

@ -1,38 +1,34 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import androidx.annotation.NonNull;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository;
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 retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -47,10 +43,9 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
static class ReposViewHolder extends RecyclerView.ViewHolder { static class ReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image; private ImageView image;
private TextView repoName; private TextView mTextView1;
private TextView repoDescription; private TextView mTextView2;
private TextView fullName; private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoForks; private TextView repoForks;
@ -60,9 +55,8 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
private ReposViewHolder(View itemView) { private ReposViewHolder(View itemView) {
super(itemView); super(itemView);
repoName = itemView.findViewById(R.id.repoName); mTextView1 = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription); mTextView2 = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar); image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
@ -72,7 +66,9 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
TextView repoFullName = v.findViewById(R.id.repoFullName); TextView repoFullName = v.findViewById(R.id.repoFullName);
@ -84,112 +80,80 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", repoFullName.getText().toString()); tinyDb.putString("repoFullName", repoFullName.getText().toString());
tinyDb.putString("repoType", repoType_.getText().toString()); tinyDb.putString("repoType", repoType_.getText().toString());
//tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
//store if user is watching this repo
{
final String instanceUrl = tinyDb.getString("instanceUrl");
String[] parts = repoFullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository();
Call<WatchRepository> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() {
@Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
}
}
@Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
});
}
context.startActivity(intent); context.startActivity(intent);
}
}); });
reposDropdownMenu.setOnClickListener(v -> { reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext(); final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
@SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null); PopupMenu popupMenu = new PopupMenu(context, v);
popupMenu.inflate(R.menu.repo_dotted_list_menu);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); Object menuHelper;
TextView repoStargazers = view.findViewById(R.id.repoStargazers); Class[] argTypes;
TextView repoWatchers = view.findViewById(R.id.repoWatchers); try {
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullName.getText()); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
BottomSheetDialog dialog = new BottomSheetDialog(context); fMenuHelper.setAccessible(true);
dialog.setContentView(view); menuHelper = fMenuHelper.get(popupMenu);
dialog.show(); argTypes = new Class[] { boolean.class };
assert menuHelper != null;
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
repoOpenInBrowser.setOnClickListener(openInBrowser -> { } catch (Exception e) {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); popupMenu.show();
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText()); return;
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
}); }
repoStargazers.setOnClickListener(stargazers -> { 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 intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText()); intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); break;
}); case R.id.repoWatchers:
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class); Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText()); intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW); context.startActivity(intentW);
dialog.dismiss(); 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();
}
}); });
} }
} }
public ReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) { public ReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
this.mCtx = mCtx; this.mCtx = mCtx;
this.reposList = reposListMain; this.reposList = reposListMain;
reposListFull = new ArrayList<>(reposList); reposListFull = new ArrayList<>(reposList);
@ -198,8 +162,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
@NonNull @NonNull
@Override @Override
public ReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repos_list, parent, false);
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repos, parent, false);
return new ReposViewHolder(v); return new ReposViewHolder(v);
} }
@ -207,19 +170,26 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
public void onBindViewHolder(@NonNull ReposViewHolder holder, int position) { public void onBindViewHolder(@NonNull ReposViewHolder holder, int position) {
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.mTextView2.setVisibility(View.GONE);
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
String firstCharacter = String.valueOf(currentItem.getName().charAt(0)); String firstCharacter = String.valueOf(currentItem.getName().charAt(0));
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3); TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.useFont(Typeface.DEFAULT)
.fontSize(18)
.toUpperCase()
.width(28)
.height(28)
.endConfig()
.buildRoundRect(firstCharacter, color, 3);
if (currentItem.getAvatar_url() != null) { if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) { if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} } else {
else {
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
} }
@ -227,10 +197,10 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
holder.repoName.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.mTextView2.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullname()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
@ -244,36 +214,27 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if(holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return reposList.size(); return reposList.size();
} }
@Override @Override
public Filter getFilter() { public Filter getFilter() {
return reposFilter; return reposFilter;
} }
private Filter reposFilter = new Filter() { private Filter reposFilter = new Filter() {
@Override @Override
protected FilterResults performFiltering(CharSequence constraint) { protected FilterResults performFiltering(CharSequence constraint) {
List<UserRepositories> filteredList = new ArrayList<>(); List<UserRepositories> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) { if (constraint == null || constraint.length() == 0) {
filteredList.addAll(reposListFull); filteredList.addAll(reposListFull);
} } else {
else {
String filterPattern = constraint.toString().toLowerCase().trim(); String filterPattern = constraint.toString().toLowerCase().trim();
for (UserRepositories item : reposListFull) { for (UserRepositories item : reposListFull) {
@ -291,7 +252,6 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
@Override @Override
protected void publishResults(CharSequence constraint, FilterResults results) { protected void publishResults(CharSequence constraint, FilterResults results) {
reposList.clear(); reposList.clear();
reposList.addAll((List) results.values); reposList.addAll((List) results.values);
notifyDataSetChanged(); notifyDataSetChanged();

View File

@ -1,38 +1,34 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.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.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository;
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;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -47,10 +43,9 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
static class OrgReposViewHolder extends RecyclerView.ViewHolder { static class OrgReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image; private ImageView image;
private TextView repoName; private TextView mTextView1;
private TextView repoDescription; private TextView mTextView2;
private TextView fullName; private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoForks; private TextView repoForks;
@ -59,9 +54,8 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
private OrgReposViewHolder(View itemView) { private OrgReposViewHolder(View itemView) {
super(itemView); super(itemView);
repoName = itemView.findViewById(R.id.repoName); mTextView1 = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription); mTextView2 = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar); image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
@ -71,7 +65,9 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
@ -81,104 +77,73 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullName.getText().toString()); tinyDb.putString("repoFullName", fullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString()); tinyDb.putString("repoType", repoType.getText().toString());
//tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
//store if user is watching this repo
{
final String instanceUrl = tinyDb.getString("instanceUrl");
String[] parts = fullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository();
Call<WatchRepository> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() {
@Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
}
}
@Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
});
}
context.startActivity(intent); context.startActivity(intent);
}
}); });
reposDropdownMenu.setOnClickListener(v -> { reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext(); final Context context = v.getContext();
//Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
@SuppressLint("InflateParams") PopupMenu popupMenu = new PopupMenu(context, v);
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null); popupMenu.inflate(R.menu.repo_dotted_list_menu);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); Object menuHelper;
TextView repoStargazers = view.findViewById(R.id.repoStargazers); Class[] argTypes;
TextView repoWatchers = view.findViewById(R.id.repoWatchers); try {
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullName.getText()); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
BottomSheetDialog dialog = new BottomSheetDialog(context); fMenuHelper.setAccessible(true);
dialog.setContentView(view); menuHelper = fMenuHelper.get(popupMenu);
dialog.show(); argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
repoOpenInBrowser.setOnClickListener(openInBrowser -> { } catch (Exception e) {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); popupMenu.show();
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText()); return;
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
}); }
repoStargazers.setOnClickListener(openInBrowser -> { 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 intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText()); intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); break;
}); case R.id.repoWatchers:
repoWatchers.setOnClickListener(openInBrowser -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class); Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText()); intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW); context.startActivity(intentW);
dialog.dismiss(); 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();
}
}); });
} }
@ -194,7 +159,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
@NonNull @NonNull
@Override @Override
public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_repositories_by_org, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repositories_by_org_list, parent, false);
return new RepositoriesByOrgAdapter.OrgReposViewHolder(v); return new RepositoriesByOrgAdapter.OrgReposViewHolder(v);
} }
@ -202,7 +167,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
public void onBindViewHolder(@NonNull RepositoriesByOrgAdapter.OrgReposViewHolder holder, int position) { public void onBindViewHolder(@NonNull RepositoriesByOrgAdapter.OrgReposViewHolder holder, int position) {
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.mTextView2.setVisibility(View.GONE);
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -220,7 +185,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
if (currentItem.getAvatar_url() != null) { if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) { if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else { } else {
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
@ -229,10 +194,10 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
holder.repoName.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.mTextView2.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullname()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
@ -247,11 +212,6 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
holder.repoForks.setText(currentItem.getForks_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if (holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
} }
@Override @Override

View File

@ -1,38 +1,34 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.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.google.android.material.bottomsheet.BottomSheetDialog; import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.OpenRepoInBrowserActivity;
import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoStargazersActivity;
import org.mian.gitnex.activities.RepoWatchersActivity; import org.mian.gitnex.activities.RepoWatchersActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository;
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;
import retrofit2.Call;
import retrofit2.Callback;
/** /**
* Author M M Arif * Author M M Arif
@ -47,10 +43,9 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
static class StarredReposViewHolder extends RecyclerView.ViewHolder { static class StarredReposViewHolder extends RecyclerView.ViewHolder {
private ImageView image; private ImageView image;
private TextView repoName; private TextView mTextView1;
private TextView repoDescription; private TextView mTextView2;
private TextView fullName; private TextView fullName;
private CheckBox isRepoAdmin;
private ImageView repoPrivatePublic; private ImageView repoPrivatePublic;
private TextView repoStars; private TextView repoStars;
private TextView repoForks; private TextView repoForks;
@ -59,9 +54,8 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
private StarredReposViewHolder(View itemView) { private StarredReposViewHolder(View itemView) {
super(itemView); super(itemView);
repoName = itemView.findViewById(R.id.repoName); mTextView1 = itemView.findViewById(R.id.repoName);
repoDescription = itemView.findViewById(R.id.repoDescription); mTextView2 = itemView.findViewById(R.id.repoDescription);
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
image = itemView.findViewById(R.id.imageAvatar); image = itemView.findViewById(R.id.imageAvatar);
fullName = itemView.findViewById(R.id.repoFullName); fullName = itemView.findViewById(R.id.repoFullName);
repoPrivatePublic = itemView.findViewById(R.id.imageRepoType); repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
@ -71,7 +65,9 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu); ImageView reposDropdownMenu = itemView.findViewById(R.id.reposDropdownMenu);
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext(); Context context = v.getContext();
@ -81,105 +77,73 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
TinyDB tinyDb = new TinyDB(context); TinyDB tinyDb = new TinyDB(context);
tinyDb.putString("repoFullName", fullName.getText().toString()); tinyDb.putString("repoFullName", fullName.getText().toString());
tinyDb.putString("repoType", repoType.getText().toString()); tinyDb.putString("repoType", repoType.getText().toString());
//tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("isRepoAdmin", isRepoAdmin.isChecked());
//store if user is watching this repo
{
final String instanceUrl = tinyDb.getString("instanceUrl");
String[] parts = fullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
WatchRepository watch = new WatchRepository();
Call<WatchRepository> call;
call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName);
call.enqueue(new Callback<WatchRepository>() {
@Override
public void onResponse(@NonNull Call<WatchRepository> call, @NonNull retrofit2.Response<WatchRepository> response) {
if(response.isSuccessful()) {
assert response.body() != null;
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
} else {
tinyDb.putBoolean("repoWatch", false);
if(response.code() != 404) {
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
}
}
@Override
public void onFailure(@NonNull Call<WatchRepository> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false);
Toasty.info(context, context.getString(R.string.genericApiStatusError));
}
});
}
context.startActivity(intent); context.startActivity(intent);
}
}); });
reposDropdownMenu.setOnClickListener(v -> { reposDropdownMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Context context = v.getContext(); final Context context = v.getContext();
Context context_ = new ContextThemeWrapper(context, R.style.AppThemeConfirmDialog);
@SuppressLint("InflateParams") PopupMenu popupMenu = new PopupMenu(context, v);
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_repository_in_list, null); popupMenu.inflate(R.menu.repo_dotted_list_menu);
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); Object menuHelper;
TextView repoStargazers = view.findViewById(R.id.repoStargazers); Class[] argTypes;
TextView repoWatchers = view.findViewById(R.id.repoWatchers); try {
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(fullName.getText()); Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
BottomSheetDialog dialog = new BottomSheetDialog(context); fMenuHelper.setAccessible(true);
dialog.setContentView(view); menuHelper = fMenuHelper.get(popupMenu);
dialog.show(); argTypes = new Class[] { boolean.class };
menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
argTypes).invoke(menuHelper, true);
repoOpenInBrowser.setOnClickListener(openInBrowser -> { } catch (Exception e) {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); popupMenu.show();
intentOpenInBrowser.putExtra("repoFullNameBrowser", fullName.getText()); return;
context.startActivity(intentOpenInBrowser);
dialog.dismiss();
}); }
repoStargazers.setOnClickListener(stargazers -> { 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 intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText()); intent.putExtra("repoFullNameForStars", fullName.getText());
context.startActivity(intent); context.startActivity(intent);
dialog.dismiss(); break;
}); case R.id.repoWatchers:
repoWatchers.setOnClickListener(watchers -> {
Intent intentW = new Intent(context, RepoWatchersActivity.class); Intent intentW = new Intent(context, RepoWatchersActivity.class);
intentW.putExtra("repoFullNameForWatchers", fullName.getText()); intentW.putExtra("repoFullNameForWatchers", fullName.getText());
context.startActivity(intentW); context.startActivity(intentW);
dialog.dismiss(); 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();
}
}); });
} }
@ -195,7 +159,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
@NonNull @NonNull
@Override @Override
public StarredReposListAdapter.StarredReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public StarredReposListAdapter.StarredReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_starred_repos, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.starred_repos_list, parent, false);
return new StarredReposListAdapter.StarredReposViewHolder(v); return new StarredReposListAdapter.StarredReposViewHolder(v);
} }
@ -203,7 +167,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
public void onBindViewHolder(@NonNull StarredReposListAdapter.StarredReposViewHolder holder, int position) { public void onBindViewHolder(@NonNull StarredReposListAdapter.StarredReposViewHolder holder, int position) {
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.mTextView2.setVisibility(View.GONE);
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -221,7 +185,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
if (currentItem.getAvatar_url() != null) { if (currentItem.getAvatar_url() != null) {
if (!currentItem.getAvatar_url().equals("")) { if (!currentItem.getAvatar_url().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image); Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.image);
} else { } else {
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
@ -230,10 +194,10 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
holder.image.setImageDrawable(drawable); holder.image.setImageDrawable(drawable);
} }
holder.repoName.setText(currentItem.getName()); holder.mTextView1.setText(currentItem.getName());
if (!currentItem.getDescription().equals("")) { if (!currentItem.getDescription().equals("")) {
holder.repoDescription.setVisibility(View.VISIBLE); holder.mTextView2.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.mTextView2.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullname()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
@ -247,10 +211,6 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
holder.repoForks.setText(currentItem.getForks_count()); holder.repoForks.setText(currentItem.getForks_count());
holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count()); holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
if (holder.isRepoAdmin == null) {
holder.isRepoAdmin = new CheckBox(mCtx);
}
holder.isRepoAdmin.setChecked(currentItem.getPermissions().isAdmin());
} }

View File

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

View File

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

View File

@ -9,9 +9,9 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.CollaboratorActions; import org.mian.gitnex.actions.CollaboratorActions;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
@ -120,7 +120,7 @@ public class UserSearchAdapter extends RecyclerView.Adapter<UserSearchAdapter.Us
@NonNull @NonNull
@Override @Override
public UserSearchAdapter.UserSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public UserSearchAdapter.UserSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_collaborators_search, parent, false); View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.collaborators_list_search, parent, false);
return new UserSearchAdapter.UserSearchViewHolder(v); return new UserSearchAdapter.UserSearchViewHolder(v);
} }
@ -141,7 +141,7 @@ public class UserSearchAdapter extends RecyclerView.Adapter<UserSearchAdapter.Us
} }
if (!currentItem.getAvatar().equals("")) { if (!currentItem.getAvatar().equals("")) {
PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAvatar); 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

@ -1,16 +1,10 @@
package org.mian.gitnex.clients; package org.mian.gitnex.clients;
import android.content.Context; import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import okhttp3.Cache; import okhttp3.Cache;
import okhttp3.Interceptor; import okhttp3.Interceptor;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@ -36,34 +30,22 @@ public class IssuesService {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY); logging.setLevel(HttpLoggingInterceptor.Level.BODY);
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(ctx);
sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom());
OkHttpClient okHttpClient = new OkHttpClient.Builder() OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cache(cache) .cache(cache)
//.addInterceptor(logging) //.addInterceptor(logging)
.sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager)
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()))
.addInterceptor(new Interceptor() { .addInterceptor(new Interceptor() {
@NonNull @NonNull
@Override @Override public Response intercept(@NonNull Chain chain) throws IOException {
public Response intercept(@NonNull Chain chain) throws IOException {
Request request = chain.request(); Request request = chain.request();
if (connToInternet) { if (connToInternet) {
request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build(); request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
} } else {
else {
request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build(); request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build();
} }
return chain.proceed(request); return chain.proceed(request);
} }
}).build(); })
.build();
Retrofit.Builder builder = new Retrofit.Builder() Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(instanceURL) .baseUrl(instanceURL)
@ -71,14 +53,9 @@ public class IssuesService {
.addConverterFactory(GsonConverterFactory.create()); .addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build(); Retrofit retrofit = builder.build();
return retrofit.create(serviceClass); return retrofit.create(serviceClass);
} }
catch(Exception e) {
Log.e("onFailure", e.toString());
}
return null;
}
} }

View File

@ -1,76 +0,0 @@
package org.mian.gitnex.clients;
import android.content.Context;
import android.util.Log;
import com.squareup.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.helpers.PicassoCache;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import java.io.File;
import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
/**
* Author anonTree1417
*/
public class PicassoService {
private static PicassoService picassoService;
private Picasso picasso;
private PicassoService(Context context) {
Picasso.Builder builder = new Picasso.Builder(context);
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(context);
sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom());
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager)
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()));
builder.downloader(new OkHttp3Downloader(okHttpClient.build()));
builder.listener((picasso, uri, exception) -> {
//Log.e("PicassoService", Objects.requireNonNull(uri.toString()));
//Log.e("PicassoService", exception.toString());
});
File cachePath = new File(context.getCacheDir() + "/picasso_cache/");
//noinspection ResultOfMethodCallIgnored
cachePath.mkdirs();
picasso = builder.memoryCache(new PicassoCache(cachePath)).build();
}
catch(Exception e) {
Log.e("PicassoService", e.toString());
}
}
public Picasso get() {
return picasso;
}
public static synchronized PicassoService getInstance(Context context) {
if(picassoService == null) {
picassoService = new PicassoService(context);
}
return picassoService;
}
}

View File

@ -1,16 +1,10 @@
package org.mian.gitnex.clients; package org.mian.gitnex.clients;
import android.content.Context; import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import okhttp3.Cache; import okhttp3.Cache;
import okhttp3.Interceptor; import okhttp3.Interceptor;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@ -36,34 +30,22 @@ public class PullRequestsService {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY); logging.setLevel(HttpLoggingInterceptor.Level.BODY);
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(ctx);
sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom());
OkHttpClient okHttpClient = new OkHttpClient.Builder() OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cache(cache) .cache(cache)
//.addInterceptor(logging) //.addInterceptor(logging)
.sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager)
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()))
.addInterceptor(new Interceptor() { .addInterceptor(new Interceptor() {
@NonNull @NonNull
@Override @Override public Response intercept(@NonNull Chain chain) throws IOException {
public Response intercept(@NonNull Chain chain) throws IOException {
Request request = chain.request(); Request request = chain.request();
if (connToInternet) { if (connToInternet) {
request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build(); request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
} } else {
else {
request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build(); request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build();
} }
return chain.proceed(request); return chain.proceed(request);
} }
}).build(); })
.build();
Retrofit.Builder builder = new Retrofit.Builder() Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(instanceURL) .baseUrl(instanceURL)
@ -71,13 +53,9 @@ public class PullRequestsService {
.addConverterFactory(GsonConverterFactory.create()); .addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build(); Retrofit retrofit = builder.build();
return retrofit.create(serviceClass); return retrofit.create(serviceClass);
}
catch(Exception e) {
Log.e("onFailure", e.toString());
}
return null;
} }
} }

View File

@ -1,19 +1,16 @@
package org.mian.gitnex.clients; package org.mian.gitnex.clients;
import android.content.Context; import android.content.Context;
import android.util.Log; import androidx.annotation.NonNull;
import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.interfaces.WebInterface;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
import java.io.File; import java.io.File;
import java.security.SecureRandom; import java.io.IOException;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import okhttp3.Cache; import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor; import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
@ -37,43 +34,31 @@ public class RetrofitClient {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY); logging.setLevel(HttpLoggingInterceptor.Level.BODY);
try { OkHttpClient okHttpClient = new OkHttpClient.Builder()
SSLContext sslContext = SSLContext.getInstance("TLS");
MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(ctx);
sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom());
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder()
.cache(cache) .cache(cache)
//.addInterceptor(logging) //.addInterceptor(logging)
.sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager) .addInterceptor(new Interceptor() {
.hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier())) @NonNull
.addInterceptor(chain -> { @Override public Response intercept(@NonNull Chain chain) throws IOException {
Request request = chain.request(); Request request = chain.request();
if (connToInternet) { if (connToInternet) {
request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build(); request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
} } else {
else {
request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build(); request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build();
} }
return chain.proceed(request); return chain.proceed(request);
}); }
})
.build();
Retrofit.Builder builder = new Retrofit.Builder() Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(instanceUrl) .baseUrl(instanceUrl)
.client(okHttpClient.build()) .client(okHttpClient)
.addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create()); .addConverterFactory(GsonConverterFactory.create());
retrofit = builder.build(); retrofit = builder.build();
}
catch(Exception e) {
Log.e("onFailure", e.toString());
}
} }
public static synchronized RetrofitClient getInstance(String instanceUrl, Context ctx) { public static synchronized RetrofitClient getInstance(String instanceUrl, Context ctx) {
@ -84,8 +69,4 @@ public class RetrofitClient {
return retrofit.create(ApiInterface.class); return retrofit.create(ApiInterface.class);
} }
public WebInterface getWebInterface() {
return retrofit.create(WebInterface.class);
}
} }

View File

@ -15,14 +15,14 @@ import org.mian.gitnex.R;
* Author M M Arif * Author M M Arif
*/ */
public class BottomSheetAdminUsersFragment extends BottomSheetDialogFragment { public class AdminUsersBottomSheetFragment extends BottomSheetDialogFragment {
private BottomSheetAdminUsersFragment.BottomSheetListener bmListener; private AdminUsersBottomSheetFragment.BottomSheetListener bmListener;
@Nullable @Nullable
@Override @Override
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.bottom_sheet_admin_users_layout, container, false); View v = inflater.inflate(R.layout.admin_users_bottom_sheet_layout, container, false);
TextView createNewUser = v.findViewById(R.id.createNewUser); TextView createNewUser = v.findViewById(R.id.createNewUser);
@ -46,7 +46,7 @@ public class BottomSheetAdminUsersFragment extends BottomSheetDialogFragment {
super.onAttach(context); super.onAttach(context);
try { try {
bmListener = (BottomSheetAdminUsersFragment.BottomSheetListener) context; bmListener = (AdminUsersBottomSheetFragment.BottomSheetListener) context;
} catch (ClassCastException e) { } catch (ClassCastException e) {
throw new ClassCastException(context.toString() throw new ClassCastException(context.toString()
+ " must implement BottomSheetListener"); + " must implement BottomSheetListener");

View File

@ -0,0 +1,289 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.ClosedIssuesAdapter;
import org.mian.gitnex.clients.IssuesService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Author M M Arif
*/
public class ClosedIssuesFragment extends Fragment {
private ProgressBar mProgressBarClosed;
private RecyclerView recyclerViewClosed;
private List<Issues> issuesListClosed;
private ClosedIssuesAdapter adapterClosed;
private ApiInterface apiClosed;
private String TAG = "closedIssuesListFragment - ";
private Context context;
private int pageSize = 1;
private TextView noDataIssuesClosed;
private String issueState = "closed";
private int resultLimit = 50;
private String requestType = "issues";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_issues_closed, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
String repoFullName = tinyDb.getString("repoFullName");
//Log.i("repoFullName", tinyDb.getString("repoFullName"));
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefreshClosed);
context = getContext();
recyclerViewClosed = v.findViewById(R.id.recyclerViewClosed);
issuesListClosed = new ArrayList<>();
mProgressBarClosed = v.findViewById(R.id.progress_barClosed);
noDataIssuesClosed = v.findViewById(R.id.noDataIssuesClosed);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, issueState, resultLimit, requestType);
adapterClosed.notifyDataChanged();
}
}, 200);
}
});
adapterClosed = new ClosedIssuesAdapter(getContext(), issuesListClosed);
adapterClosed.setLoadMoreListener(new ClosedIssuesAdapter.OnLoadMoreListener() {
@Override
public void onLoadMore() {
recyclerViewClosed.post(new Runnable() {
@Override
public void run() {
if(issuesListClosed.size() == 10 || pageSize == 10) {
int page = (issuesListClosed.size() + 10) / 10;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, issueState, resultLimit, requestType);
}
/*else {
Toasty.info(context, getString(R.string.noMoreData));
}*/
}
});
}
});
recyclerViewClosed.setHasFixedSize(true);
recyclerViewClosed.setLayoutManager(new LinearLayoutManager(context));
recyclerViewClosed.setAdapter(adapterClosed);
apiClosed = IssuesService.createService(ApiInterface.class, instanceUrl, getContext());
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, issueState, resultLimit, requestType);
return v;
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("resumeClosedIssues")) {
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, issueState, resultLimit, requestType);
tinyDb.putBoolean("resumeClosedIssues", false);
}
}
private void loadInitial(String token, String repoOwner, String repoName, String issueState, int resultLimit, String requestType) {
Call<List<Issues>> call = apiClosed.getClosedIssues(token, repoOwner, repoName, 1, issueState, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
issuesListClosed.clear();
issuesListClosed.addAll(response.body());
adapterClosed.notifyDataChanged();
noDataIssuesClosed.setVisibility(View.GONE);
}
else {
issuesListClosed.clear();
adapterClosed.notifyDataChanged();
noDataIssuesClosed.setVisibility(View.VISIBLE);
}
mProgressBarClosed.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadMore(String token, String repoOwner, String repoName, int page, String issueState, int resultLimit, String requestType){
//add loading progress view
issuesListClosed.add(new Issues("load"));
adapterClosed.notifyItemInserted((issuesListClosed.size() - 1));
Call<List<Issues>> call = apiClosed.getClosedIssues(token, repoOwner, repoName, page, issueState, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()){
//remove loading view
issuesListClosed.remove(issuesListClosed.size()-1);
List<Issues> result = response.body();
assert result != null;
if(result.size() > 0) {
pageSize = result.size();
issuesListClosed.addAll(result);
}
else {
Toasty.info(context, getString(R.string.noMoreData));
adapterClosed.setMoreDataAvailable(false);
}
adapterClosed.notifyDataChanged();
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
//searchView.setQueryHint(getContext().getString(R.string.strFilter));
/*if(!connToInternet) {
return;
}*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapterClosed.getFilter().filter(newText);
return false;
}
});
}
}

View File

@ -30,10 +30,9 @@ import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
/** /**
* + * Template Author M M Arif + * Template Author M M Arif
* + * Author 6543 + * Author 6543
* + + */
*/
public class ExploreRepositoriesFragment extends Fragment { public class ExploreRepositoriesFragment extends Fragment {
@ -51,11 +50,9 @@ public class ExploreRepositoriesFragment extends Fragment {
private OnFragmentInteractionListener mListener; private OnFragmentInteractionListener mListener;
public ExploreRepositoriesFragment() { public ExploreRepositoriesFragment() {
} }
public static ExploreRepositoriesFragment newInstance(String param1, String param2) { public static ExploreRepositoriesFragment newInstance(String param1, String param2) {
ExploreRepositoriesFragment fragment = new ExploreRepositoriesFragment(); ExploreRepositoriesFragment fragment = new ExploreRepositoriesFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(repoOwnerF, param1); args.putString(repoOwnerF, param1);
@ -66,7 +63,6 @@ public class ExploreRepositoriesFragment extends Fragment {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (getArguments() != null) { if (getArguments() != null) {
String repoName = getArguments().getString(repoNameF); String repoName = getArguments().getString(repoNameF);
@ -75,7 +71,8 @@ public class ExploreRepositoriesFragment extends Fragment {
} }
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_explore_repo, container, false); final View v = inflater.inflate(R.layout.fragment_explore_repo, container, false);
//setHasOptionsMenu(true); //setHasOptionsMenu(true);
@ -93,10 +90,8 @@ public class ExploreRepositoriesFragment extends Fragment {
mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.VISIBLE);
searchKeyword.setOnEditorActionListener(new TextView.OnEditorActionListener() { searchKeyword.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override @Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND) { if (actionId == EditorInfo.IME_ACTION_SEND) {
if(!searchKeyword.getText().toString().equals("")) { if(!searchKeyword.getText().toString().equals("")) {
mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.VISIBLE);
@ -117,7 +112,10 @@ public class ExploreRepositoriesFragment extends Fragment {
private void loadDefaultList(String instanceUrl, String instanceToken, String loginUid, Boolean repoTypeInclude, String sort, String order, final Context context, int limit) { private void loadDefaultList(String instanceUrl, String instanceToken, String loginUid, Boolean repoTypeInclude, String sort, String order, final Context context, int limit) {
Call<ExploreRepositories> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), null, repoTypeInclude, sort, order, limit); Call<ExploreRepositories> call = RetrofitClient
.getInstance(instanceUrl, getContext())
.getApiInterface()
.queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), null, repoTypeInclude, sort, order, limit);
call.enqueue(new Callback<ExploreRepositories>() { call.enqueue(new Callback<ExploreRepositories>() {
@ -127,8 +125,7 @@ public class ExploreRepositoriesFragment extends Fragment {
if (response.isSuccessful()) { if (response.isSuccessful()) {
assert response.body() != null; assert response.body() != null;
getReposList(response.body().getSearchedData(), context); getReposList(response.body().getSearchedData(), context);
} } else {
else {
Log.i("onResponse", String.valueOf(response.code())); Log.i("onResponse", String.valueOf(response.code()));
} }
@ -136,7 +133,6 @@ public class ExploreRepositoriesFragment extends Fragment {
@Override @Override
public void onFailure(@NonNull Call<ExploreRepositories> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<ExploreRepositories> call, @NonNull Throwable t) {
Log.i("onFailure", Objects.requireNonNull(t.getMessage())); Log.i("onFailure", Objects.requireNonNull(t.getMessage()));
} }
@ -146,7 +142,10 @@ public class ExploreRepositoriesFragment extends Fragment {
private void loadSearchReposList(String instanceUrl, String instanceToken, String loginUid, String searchKeyword, Boolean repoTypeInclude, String sort, String order, final Context context, int limit) { private void loadSearchReposList(String instanceUrl, String instanceToken, String loginUid, String searchKeyword, Boolean repoTypeInclude, String sort, String order, final Context context, int limit) {
Call<ExploreRepositories> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), searchKeyword, repoTypeInclude, sort, order, limit); Call<ExploreRepositories> call = RetrofitClient
.getInstance(instanceUrl, getContext())
.getApiInterface()
.queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), searchKeyword, repoTypeInclude, sort, order, limit);
call.enqueue(new Callback<ExploreRepositories>() { call.enqueue(new Callback<ExploreRepositories>() {
@ -156,8 +155,7 @@ public class ExploreRepositoriesFragment extends Fragment {
if (response.isSuccessful()) { if (response.isSuccessful()) {
assert response.body() != null; assert response.body() != null;
getReposList(response.body().getSearchedData(), context); getReposList(response.body().getSearchedData(), context);
} } else {
else {
Log.i("onResponse", String.valueOf(response.code())); Log.i("onResponse", String.valueOf(response.code()));
} }
@ -165,7 +163,6 @@ public class ExploreRepositoriesFragment extends Fragment {
@Override @Override
public void onFailure(@NonNull Call<ExploreRepositories> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<ExploreRepositories> call, @NonNull Throwable t) {
Log.i("onFailure", Objects.requireNonNull(t.getMessage())); Log.i("onFailure", Objects.requireNonNull(t.getMessage()));
} }
@ -181,7 +178,8 @@ public class ExploreRepositoriesFragment extends Fragment {
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
if(adapter.getItemCount() > 0) { if(adapter.getItemCount() > 0) {
@ -201,7 +199,6 @@ public class ExploreRepositoriesFragment extends Fragment {
} }
public void onButtonPressed(Uri uri) { public void onButtonPressed(Uri uri) {
if (mListener != null) { if (mListener != null) {
mListener.onFragmentInteraction(uri); mListener.onFragmentInteraction(uri);
} }
@ -209,15 +206,11 @@ public class ExploreRepositoriesFragment extends Fragment {
@Override @Override
public void onDetach() { public void onDetach() {
super.onDetach(); super.onDetach();
mListener = null; mListener = null;
} }
public interface OnFragmentInteractionListener { public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri); void onFragmentInteraction(Uri uri);
} }
} }

View File

@ -1,6 +1,5 @@
package org.mian.gitnex.fragments; package org.mian.gitnex.fragments;
import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -146,9 +145,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
final String finalDirName_ = dirName_; final String finalDirName_ = dirName_;
mBreadcrumbsView.addItem(createItem(dirName)); mBreadcrumbsView.addItem(createItem(dirName));
//noinspection unchecked
mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() { mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() {
@SuppressLint("SetTextI18n")
@Override @Override
public void onNavigateBack(BreadcrumbItem item, int position) { public void onNavigateBack(BreadcrumbItem item, int position) {

View File

@ -1,305 +0,0 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.adapters.IssuesAdapter;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.mikepenz.fastadapter.IItemAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
/**
* Author M M Arif
*/
public class IssuesClosedFragment extends Fragment implements ItemFilterListener<IssuesAdapter> {
private Context ctx;
private ProgressBar mProgressBarClosed;
private boolean loadNextFlag = false;
private String TAG = StaticGlobalVariables.tagIssuesListClosed;
private TextView noDataIssuesClosed;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private String requestType = StaticGlobalVariables.issuesRequestType;
private String issueState = StaticGlobalVariables.issueStateClosed;
private List<IssuesAdapter> items = new ArrayList<>();
private FastItemAdapter<IssuesAdapter> fastItemAdapter;
private ItemAdapter footerAdapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_issues_closed, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
if (VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
noDataIssuesClosed = v.findViewById(R.id.noDataIssuesClosed);
mProgressBarClosed = v.findViewById(R.id.progress_barClosed);
final SwipeRefreshLayout swipeRefreshLayout = v.findViewById(R.id.pullToRefreshClosed);
RecyclerView recyclerView = v.findViewById(R.id.recyclerViewClosed);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
fastItemAdapter = new FastItemAdapter<>();
fastItemAdapter.withSelectable(true);
footerAdapter = items();
//noinspection unchecked
fastItemAdapter.addAdapter(StaticGlobalVariables.issuesPageInit, footerAdapter);
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<IssuesAdapter>) (item, constraint) -> item.getIssueTitle().toLowerCase().contains(constraint.toString().toLowerCase()));
fastItemAdapter.getItemFilter().withItemFilterListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(fastItemAdapter);
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
@Override
public void onLoadMore(final int currentPage) {
loadNext(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, issueState, requestType, currentPage);
}
};
swipeRefreshLayout.setOnRefreshListener(() -> {
mProgressBarClosed.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
swipeRefreshLayout.setRefreshing(false);
});
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, issueState, resultLimit, requestType);
fastItemAdapter.withEventHook(new IssuesAdapter.IssueTitleClickEvent());
assert savedInstanceState != null;
fastItemAdapter.withSavedInstanceState(savedInstanceState);
return v;
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
if(tinyDb.getBoolean("resumeClosedIssues")) {
mProgressBarClosed.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
tinyDb.putBoolean("resumeClosedIssues", false);
}
}
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String issueState, int resultLimit, String requestType) {
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getClosedIssues(token, repoOwner, repoName, 1, issueState, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
if(response.body().size() == resultLimit) {
loadNextFlag = true;
}
for(int i = 0; i < response.body().size(); i++) {
items.add(new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
fastItemAdapter.add(items);
noDataIssuesClosed.setVisibility(View.GONE);
}
else {
noDataIssuesClosed.setVisibility(View.VISIBLE);
}
mProgressBarClosed.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String issueState, String requestType, final int currentPage) {
footerAdapter.clear();
//noinspection unchecked
footerAdapter.add(new ProgressItem().withEnabled(false));
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getClosedIssues(token, repoOwner, repoName, currentPage + 1, issueState, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
loadNextFlag = response.body().size() == resultLimit;
for(int i = 0; i < response.body().size(); i++) {
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
footerAdapter.clear();
mProgressBarClosed.setVisibility(View.GONE);
}
else {
footerAdapter.clear();
}
mProgressBarClosed.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.i(TAG, t.toString());
}
});
if(!loadNextFlag) {
footerAdapter.clear();
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
fastItemAdapter.filter(newText);
return true;
}
});
endlessRecyclerOnScrollListener.enable();
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<IssuesAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}
@Override
public void onReset() {
endlessRecyclerOnScrollListener.enable();
}
}

View File

@ -0,0 +1,288 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.IssuesAdapter;
import org.mian.gitnex.clients.IssuesService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.AppUtil;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Author M M Arif
*/
public class IssuesFragment extends Fragment {
private ProgressBar mProgressBar;
private RecyclerView recyclerView;
private List<Issues> issuesList;
private IssuesAdapter adapter;
private ApiInterface api;
private String TAG = "IssuesListFragment - ";
private Context context;
private int pageSize = 1;
private TextView noDataIssues;
private int resultLimit = 50;
private String requestType = "issues";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_issues, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
String repoFullName = tinyDb.getString("repoFullName");
//Log.i("repoFullName", tinyDb.getString("repoFullName"));
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
context = getContext();
recyclerView = v.findViewById(R.id.recyclerView);
issuesList = new ArrayList<>();
mProgressBar = v.findViewById(R.id.progress_bar);
noDataIssues = v.findViewById(R.id.noDataIssues);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefresh.setRefreshing(false);
loadInitial(instanceToken, repoOwner, repoName, resultLimit, requestType);
adapter.notifyDataChanged();
}
}, 200);
}
});
adapter = new IssuesAdapter(getContext(), issuesList);
adapter.setLoadMoreListener(new IssuesAdapter.OnLoadMoreListener() {
@Override
public void onLoadMore() {
recyclerView.post(new Runnable() {
@Override
public void run() {
if(issuesList.size() == 10 || pageSize == 10) {
int page = (issuesList.size() + 10) / 10;
loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, requestType);
}
/*else {
Toasty.info(context, getString(R.string.noMoreData));
}*/
}
});
}
});
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
api = IssuesService.createService(ApiInterface.class, instanceUrl, getContext());
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType);
return v;
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("resumeIssues")) {
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType);
tinyDb.putBoolean("resumeIssues", false);
}
}
private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String requestType) {
Call<List<Issues>> call = api.getIssues(token, repoOwner, repoName, 1, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
issuesList.clear();
issuesList.addAll(response.body());
adapter.notifyDataChanged();
noDataIssues.setVisibility(View.GONE);
}
else {
issuesList.clear();
adapter.notifyDataChanged();
noDataIssues.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadMore(String token, String repoOwner, String repoName, int page, int resultLimit, String requestType){
//add loading progress view
issuesList.add(new Issues("load"));
adapter.notifyItemInserted((issuesList.size() - 1));
Call<List<Issues>> call = api.getIssues(token, repoOwner, repoName, page, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()){
//remove loading view
issuesList.remove(issuesList.size()-1);
List<Issues> result = response.body();
assert result != null;
if(result.size() > 0) {
pageSize = result.size();
issuesList.addAll(result);
}
else {
Toasty.info(context, getString(R.string.noMoreData));
adapter.setMoreDataAvailable(false);
}
adapter.notifyDataChanged();
}
else {
Log.e(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
//searchView.setQueryHint(getContext().getString(R.string.strFilter));
/*if(!connToInternet) {
return;
}*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
}
}

View File

@ -1,155 +0,0 @@
package org.mian.gitnex.fragments;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.android.material.tabs.TabLayout;
import org.mian.gitnex.R;
import org.mian.gitnex.util.TinyDB;
import java.util.Objects;
/**
* Author M M Arif
*/
public class IssuesMainFragment extends Fragment {
private Context ctx;
public IssuesMainFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_issues_main, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
SectionsPagerAdapter mSectionsPagerAdapter = new IssuesMainFragment.SectionsPagerAdapter(getChildFragmentManager());
ViewPager mViewPager = v.findViewById(R.id.issuesContainer);
mViewPager.setAdapter(mSectionsPagerAdapter);
Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf");
}
else if (tinyDb.getInt("customFontId") == 1) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/manroperegular.ttf");
}
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf");
}
TabLayout tabLayout = v.findViewById(R.id.tabs);
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildCount = vgTab.getChildCount();
for (int i = 0; i < tabChildCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(myTypeface);
}
}
}
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
return v;
}
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0: // open issues
fragment = new IssuesOpenFragment();
break;
case 1: // closed issues
fragment = new IssuesClosedFragment();
break;
}
assert fragment != null;
return fragment;
}
@Override
public int getCount() {
return 2;
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.repo_dotted_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
return true;
case R.id.repoMenu:
BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment();
bottomSheet.show(getChildFragmentManager(), "repoBottomSheet");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

View File

@ -1,302 +0,0 @@
package org.mian.gitnex.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.mikepenz.fastadapter.IItemAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter;
import com.mikepenz.fastadapter.listeners.ItemFilterListener;
import com.mikepenz.fastadapter_extensions.items.ProgressItem;
import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.adapters.IssuesAdapter;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
import java.util.ArrayList;
import java.util.List;
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
/**
* Author M M Arif
*/
public class IssuesOpenFragment extends Fragment implements ItemFilterListener<IssuesAdapter> {
private ProgressBar mProgressBar;
private boolean loadNextFlag = false;
private String TAG = StaticGlobalVariables.tagIssuesListOpen;
private TextView noDataIssues;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private String requestType = StaticGlobalVariables.issuesRequestType;
private List<IssuesAdapter> items = new ArrayList<>();
private FastItemAdapter<IssuesAdapter> fastItemAdapter;
private ItemAdapter footerAdapter;
private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_issues, container, false);
setHasOptionsMenu(true);
TinyDB tinyDb = new TinyDB(getContext());
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
if (VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
noDataIssues = v.findViewById(R.id.noDataIssues);
mProgressBar = v.findViewById(R.id.progress_bar);
final SwipeRefreshLayout swipeRefreshLayout = v.findViewById(R.id.pullToRefresh);
RecyclerView recyclerView = v.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
fastItemAdapter = new FastItemAdapter<>();
fastItemAdapter.withSelectable(true);
footerAdapter = items();
//noinspection unchecked
fastItemAdapter.addAdapter(StaticGlobalVariables.issuesPageInit, footerAdapter);
fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<IssuesAdapter>) (item, constraint) -> item.getIssueTitle().toLowerCase().contains(constraint.toString().toLowerCase()));
fastItemAdapter.getItemFilter().withItemFilterListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(fastItemAdapter);
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
@Override
public void onLoadMore(final int currentPage) {
loadNext(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, requestType, currentPage);
}
};
swipeRefreshLayout.setOnRefreshListener(() -> {
mProgressBar.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
swipeRefreshLayout.setRefreshing(false);
});
recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
loadInitial(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, requestType);
fastItemAdapter.withEventHook(new IssuesAdapter.IssueTitleClickEvent());
assert savedInstanceState != null;
fastItemAdapter.withSavedInstanceState(savedInstanceState);
return v;
}
@Override
public void onResume() {
super.onResume();
TinyDB tinyDb = new TinyDB(getContext());
if(tinyDb.getBoolean("resumeIssues")) {
mProgressBar.setVisibility(View.VISIBLE);
fastItemAdapter.clear();
endlessRecyclerOnScrollListener.resetPageCount();
tinyDb.putBoolean("resumeIssues", false);
}
}
private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String requestType) {
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getIssues(token, repoOwner, repoName, 1, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
if(response.body().size() == resultLimit) {
loadNextFlag = true;
}
for(int i = 0; i < response.body().size(); i++) {
items.add(new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
fastItemAdapter.add(items);
noDataIssues.setVisibility(View.GONE);
}
else {
noDataIssues.setVisibility(View.VISIBLE);
}
mProgressBar.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.e(TAG, t.toString());
}
});
}
private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String requestType, final int currentPage) {
footerAdapter.clear();
//noinspection unchecked
footerAdapter.add(new ProgressItem().withEnabled(false));
Call<List<Issues>> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getIssues(token, repoOwner, repoName, currentPage + 1, resultLimit, requestType);
call.enqueue(new Callback<List<Issues>>() {
@Override
public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
if(response.body().size() > 0) {
loadNextFlag = response.body().size() == resultLimit;
for(int i = 0; i < response.body().size(); i++) {
fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin()));
}
footerAdapter.clear();
noDataIssues.setVisibility(View.GONE);
}
else {
footerAdapter.clear();
}
mProgressBar.setVisibility(View.GONE);
}
else {
Log.i(TAG, String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
Log.i(TAG, t.toString());
}
});
if(!loadNextFlag) {
footerAdapter.clear();
}
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
fastItemAdapter.filter(newText);
return true;
}
});
endlessRecyclerOnScrollListener.enable();
}
@Override
public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<IssuesAdapter> results) {
endlessRecyclerOnScrollListener.disable();
}
@Override
public void onReset() {
endlessRecyclerOnScrollListener.enable();
}
}

View File

@ -24,7 +24,7 @@ import android.widget.ImageView;
import android.widget.ProgressBar; 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.activities.CreateRepoActivity; import org.mian.gitnex.activities.NewRepoActivity;
import org.mian.gitnex.adapters.MyReposListAdapter; import org.mian.gitnex.adapters.MyReposListAdapter;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
@ -91,7 +91,6 @@ public class MyRepositoriesFragment extends Fragment {
final String loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final String userLogin = tinyDb.getString("userLogin"); final String userLogin = tinyDb.getString("userLogin");
tinyDb.putBoolean("isRepoAdmin", true);
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
@ -101,18 +100,18 @@ public class MyRepositoriesFragment extends Fragment {
mRecyclerView.setHasFixedSize(true); mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
createNewRepo = v.findViewById(R.id.addNewRepo); createNewRepo = v.findViewById(R.id.addNewRepo);
createNewRepo.setOnClickListener(new View.OnClickListener() { createNewRepo.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
Intent intent = new Intent(view.getContext(), NewRepoActivity.class);
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
startActivity(intent); startActivity(intent);
} }
}); });
@ -120,14 +119,13 @@ public class MyRepositoriesFragment extends Fragment {
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override @Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (dy > 0 && createNewRepo.isShown()) { if (dy > 0 && createNewRepo.isShown()) {
createNewRepo.setVisibility(View.GONE); createNewRepo.setVisibility(View.GONE);
} else if (dy < 0 ) { } else if (dy < 0 ) {
createNewRepo.setVisibility(View.VISIBLE); createNewRepo.setVisibility(View.VISIBLE);
}
} }
}
@Override @Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {

View File

@ -16,12 +16,12 @@ import androidx.annotation.Nullable;
* Author M M Arif * Author M M Arif
*/ */
public class BottomSheetNavSubMenuFragment extends BottomSheetDialogFragment { public class NavSubMenuBottomSheetFragment extends BottomSheetDialogFragment {
@Nullable @Nullable
@Override @Override
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.bottom_sheet_nav_sub_menu_layout, container, false); View v = inflater.inflate(R.layout.nav_sub_menu_bottom_sheet_layout, container, false);
TextView adminUsers = v.findViewById(R.id.adminUsers); TextView adminUsers = v.findViewById(R.id.adminUsers);

View File

@ -15,17 +15,16 @@ import androidx.annotation.Nullable;
* Author M M Arif * Author M M Arif
*/ */
public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment { public class OrgBottomSheetFragment extends BottomSheetDialogFragment {
private BottomSheetOrganizationFragment.BottomSheetListener bmListener; private OrgBottomSheetFragment.BottomSheetListener bmListener;
@Nullable @Nullable
@Override @Override
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.bottom_sheet_organization_layout, container, false); View v = inflater.inflate(R.layout.org_bottom_sheet_layout, container, false);
TextView createTeam = v.findViewById(R.id.createTeam); TextView createTeam = v.findViewById(R.id.createTeam);
TextView createRepository = v.findViewById(R.id.createRepository);
createTeam.setOnClickListener(new View.OnClickListener() { createTeam.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -35,14 +34,6 @@ public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment {
} }
}); });
createRepository.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("repository");
dismiss();
}
});
return v; return v;
} }
@ -55,7 +46,7 @@ public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment {
super.onAttach(context); super.onAttach(context);
try { try {
bmListener = (BottomSheetOrganizationFragment.BottomSheetListener) context; bmListener = (OrgBottomSheetFragment.BottomSheetListener) context;
} catch (ClassCastException e) { } catch (ClassCastException e) {
throw new ClassCastException(context.toString() throw new ClassCastException(context.toString()
+ " must implement BottomSheetListener"); + " must implement BottomSheetListener");

View File

@ -14,8 +14,8 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
@ -104,7 +104,7 @@ public class OrganizationInfoFragment extends Fragment {
if (response.code() == 200) { if (response.code() == 200) {
assert orgInfo != null; assert orgInfo != null;
PicassoService.getInstance(ctx).get().load(orgInfo.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(orgAvatar); 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

@ -23,7 +23,7 @@ import android.widget.ImageView;
import android.widget.ProgressBar; 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.activities.CreateOrganizationActivity; import org.mian.gitnex.activities.NewOrganizationActivity;
import org.mian.gitnex.adapters.OrganizationsListAdapter; import org.mian.gitnex.adapters.OrganizationsListAdapter;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.AppUtil;
@ -77,7 +77,7 @@ public class OrganizationsFragment extends Fragment {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
Intent intent = new Intent(view.getContext(), CreateOrganizationActivity.class); Intent intent = new Intent(view.getContext(), NewOrganizationActivity.class);
startActivity(intent); startActivity(intent);
} }

View File

@ -16,12 +16,12 @@ import androidx.annotation.Nullable;
* Author M M Arif * Author M M Arif
*/ */
public class BottomSheetProfileFragment extends BottomSheetDialogFragment { public class ProfileBottomSheetFragment extends BottomSheetDialogFragment {
@Nullable @Nullable
@Override @Override
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.bottom_sheet_profile_layout, container, false); View v = inflater.inflate(R.layout.profile_bottom_sheet_layout, container, false);
TextView addNewEmailAddress = v.findViewById(R.id.addNewEmailAddress); TextView addNewEmailAddress = v.findViewById(R.id.addNewEmailAddress);

View File

@ -18,9 +18,9 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.squareup.picasso.Picasso;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.util.TinyDB;
import java.util.Objects; import java.util.Objects;
@ -48,30 +48,34 @@ 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"));
PicassoService.getInstance(ctx).get().load(tinyDb.getString("userAvatar")).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).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"));
ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager()); ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new ProfileFragment.SectionsPagerAdapter(getFragmentManager());
ViewPager mViewPager = v.findViewById(R.id.container); ViewPager mViewPager = v.findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setAdapter(mSectionsPagerAdapter);
Typeface myTypeface; Typeface myTypeface;
if(tinyDb.getInt("customFontId") == 0) {
switch(tinyDb.getInt("customFontId", -1)) {
case 0:
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf"); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf");
break;
case 2: }
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/sourcecodeproregular.ttf"); else if (tinyDb.getInt("customFontId") == 1) {
break;
default:
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/manroperegular.ttf"); myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/manroperegular.ttf");
break;
}
else if (tinyDb.getInt("customFontId") == 2) {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/sourcecodeproregular.ttf");
}
else {
myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf");
} }
@ -97,10 +101,10 @@ public class ProfileFragment extends Fragment {
} }
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter { public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(FragmentManager fm) { SectionsPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); super(fm);
} }
@NonNull @NonNull
@ -143,8 +147,9 @@ public class ProfileFragment extends Fragment {
((MainActivity)ctx).finish(); ((MainActivity)ctx).finish();
return true; return true;
case R.id.profileMenu: case R.id.profileMenu:
BottomSheetProfileFragment bottomSheet = new BottomSheetProfileFragment(); ProfileBottomSheetFragment bottomSheet = new ProfileBottomSheetFragment();
bottomSheet.show(getChildFragmentManager(), "profileBottomSheet"); assert getFragmentManager() != null;
bottomSheet.show(getFragmentManager(), "profileBottomSheet");
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);

View File

@ -151,7 +151,6 @@ public class PullRequestsFragment extends Fragment {
loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit); loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit);
tinyDb.putBoolean("resumePullRequests", false); tinyDb.putBoolean("resumePullRequests", false);
tinyDb.putBoolean("prMerged", false);
} }

View File

@ -17,14 +17,14 @@ import androidx.annotation.Nullable;
* Author M M Arif * Author M M Arif
*/ */
public class BottomSheetRepoFragment extends BottomSheetDialogFragment { public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
private BottomSheetListener bmListener; private BottomSheetListener bmListener;
@Nullable @Nullable
@Override @Override
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.bottom_sheet_repo_layout, container, false); View v = inflater.inflate(R.layout.repo_bottom_sheet_layout, container, false);
final TinyDB tinyDb = new TinyDB(getContext()); final TinyDB tinyDb = new TinyDB(getContext());
@ -39,7 +39,6 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
TextView unStarRepository = v.findViewById(R.id.unStarRepository); TextView unStarRepository = v.findViewById(R.id.unStarRepository);
TextView watchRepository = v.findViewById(R.id.watchRepository); TextView watchRepository = v.findViewById(R.id.watchRepository);
TextView unWatchRepository = v.findViewById(R.id.unWatchRepository); TextView unWatchRepository = v.findViewById(R.id.unWatchRepository);
TextView shareRepository = v.findViewById(R.id.shareRepository);
createLabel.setOnClickListener(new View.OnClickListener() { createLabel.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -87,14 +86,6 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
} }
}); });
shareRepository.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("shareRepo");
dismiss();
}
});
openWebRepo.setOnClickListener(new View.OnClickListener() { openWebRepo.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {

View File

@ -6,7 +6,6 @@ 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.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
@ -31,7 +30,6 @@ import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@ -46,6 +44,9 @@ import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; 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 org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Locale; import java.util.Locale;
@ -57,7 +58,7 @@ import java.util.Objects;
public class RepoInfoFragment extends Fragment { public class RepoInfoFragment extends Fragment {
private Context ctx; private Context ctx = getContext();
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
private LinearLayout pageContent; private LinearLayout pageContent;
private static String repoNameF = "param2"; private static String repoNameF = "param2";
@ -65,17 +66,17 @@ public class RepoInfoFragment extends Fragment {
private String repoName; private String repoName;
private String repoOwner; private String repoOwner;
private TextView repoMetaName; private TextView repoNameInfo;
private TextView repoMetaDescription; private TextView repoOwnerInfo;
private TextView repoMetaStars; private TextView repoDescriptionInfo;
private TextView repoMetaPullRequests; private TextView repoWebsiteInfo;
private LinearLayout repoMetaPullRequestsFrame; private TextView repoSizeInfo;
private TextView repoMetaForks; private TextView repoDefaultBranchInfo;
private TextView repoMetaSize; private TextView repoSshUrlInfo;
private TextView repoMetaWatchers; private TextView repoCloneUrlInfo;
private TextView repoMetaCreatedAt; private TextView repoRepoUrlInfo;
private TextView repoMetaWebsite; private TextView repoForksCountInfo;
private Button repoAdditionalButton; private TextView repoCreatedAtInfo;
private TextView repoFileContents; private TextView repoFileContents;
private LinearLayout repoMetaFrame; private LinearLayout repoMetaFrame;
private ImageView repoMetaDataExpandCollapse; private ImageView repoMetaDataExpandCollapse;
@ -119,26 +120,25 @@ public class RepoInfoFragment extends Fragment {
final String locale = tinyDb.getString("locale"); final String locale = tinyDb.getString("locale");
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
ctx = getActivity();
pageContent = v.findViewById(R.id.repoInfoLayout); pageContent = v.findViewById(R.id.repoInfoLayout);
pageContent.setVisibility(View.GONE); pageContent.setVisibility(View.GONE);
mProgressBar = v.findViewById(R.id.progress_bar); mProgressBar = v.findViewById(R.id.progress_bar);
repoMetaName = v.findViewById(R.id.repoMetaName); repoNameInfo = v.findViewById(R.id.repoNameInfo);
repoMetaDescription = v.findViewById(R.id.repoMetaDescription); repoOwnerInfo = v.findViewById(R.id.repoOwnerInfo);
repoMetaStars = v.findViewById(R.id.repoMetaStars); repoDescriptionInfo = v.findViewById(R.id.repoDescriptionInfo);
repoMetaPullRequests = v.findViewById(R.id.repoMetaPullRequests); repoWebsiteInfo = v.findViewById(R.id.repoWebsiteInfo);
repoMetaPullRequestsFrame = v.findViewById(R.id.repoMetaPullRequestsFrame); repoSizeInfo = v.findViewById(R.id.repoSizeInfo);
repoMetaForks = v.findViewById(R.id.repoMetaForks); repoDefaultBranchInfo = v.findViewById(R.id.repoDefaultBranchInfo);
repoMetaSize = v.findViewById(R.id.repoMetaSize); repoSshUrlInfo = v.findViewById(R.id.repoSshUrlInfo);
repoMetaWatchers = v.findViewById(R.id.repoMetaWatchers); repoCloneUrlInfo = v.findViewById(R.id.repoCloneUrlInfo);
repoMetaCreatedAt = v.findViewById(R.id.repoMetaCreatedAt); repoRepoUrlInfo = v.findViewById(R.id.repoRepoUrlInfo);
repoMetaWebsite = v.findViewById(R.id.repoMetaWebsite); repoForksCountInfo = v.findViewById(R.id.repoForksCountInfo);
repoAdditionalButton = v.findViewById(R.id.repoAdditionalButton); repoCreatedAtInfo = v.findViewById(R.id.repoCreatedAtInfo);
repoFileContents = v.findViewById(R.id.repoFileContents); repoFileContents = v.findViewById(R.id.repoFileContents);
TextView repoFilename = v.findViewById(R.id.repoFilename);
repoMetaFrame = v.findViewById(R.id.repoMetaFrame); repoMetaFrame = v.findViewById(R.id.repoMetaFrame);
LinearLayout repoMetaFrameHeader = v.findViewById(R.id.repoMetaFrameHeader); TextView repoMetaData = v.findViewById(R.id.repoMetaData);
repoMetaDataExpandCollapse = v.findViewById(R.id.repoMetaDataExpandCollapse); repoMetaDataExpandCollapse = v.findViewById(R.id.repoMetaDataExpandCollapse);
repoFilenameExpandCollapse = v.findViewById(R.id.repoFilenameExpandCollapse); repoFilenameExpandCollapse = v.findViewById(R.id.repoFilenameExpandCollapse);
fileContentsFrameHeader = v.findViewById(R.id.fileContentsFrameHeader); fileContentsFrameHeader = v.findViewById(R.id.fileContentsFrameHeader);
@ -149,23 +149,15 @@ public class RepoInfoFragment extends Fragment {
getRepoInfo(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, locale, timeFormat); getRepoInfo(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, locale, timeFormat);
getFileContents(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getResources().getString(R.string.defaultFilename)); getFileContents(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getResources().getString(R.string.defaultFilename));
if(isExpandViewVisible()) { repoFilename.setOnClickListener(new View.OnClickListener() {
toggleExpandView();
}
if(!isExpandViewMetaVisible()) {
toggleExpandViewMeta();
}
fileContentsFrameHeader.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
toggleExpandView(); collapseExpandView();
} }
}); });
repoMetaFrameHeader.setOnClickListener(new View.OnClickListener() { repoMetaData.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
toggleExpandViewMeta(); collapseExpandViewMeta();
} }
}); });
@ -188,7 +180,7 @@ public class RepoInfoFragment extends Fragment {
void onFragmentInteraction(Uri uri); void onFragmentInteraction(Uri uri);
} }
private void toggleExpandView() { private void collapseExpandView() {
if (repoFileContents.getVisibility() == View.GONE) { if (repoFileContents.getVisibility() == View.GONE) {
repoFilenameExpandCollapse.setImageResource(R.drawable.ic_arrow_up); repoFilenameExpandCollapse.setImageResource(R.drawable.ic_arrow_up);
@ -202,14 +194,10 @@ public class RepoInfoFragment extends Fragment {
//Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up); //Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
//fileContentsFrame.startAnimation(slide_up); //fileContentsFrame.startAnimation(slide_up);
} }
} }
private boolean isExpandViewVisible() { private void collapseExpandViewMeta() {
return repoFileContents.getVisibility() == View.VISIBLE;
}
private void toggleExpandViewMeta() {
if (repoMetaFrame.getVisibility() == View.GONE) { if (repoMetaFrame.getVisibility() == View.GONE) {
repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_arrow_up); repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_arrow_up);
repoMetaFrame.setVisibility(View.VISIBLE); repoMetaFrame.setVisibility(View.VISIBLE);
@ -222,10 +210,7 @@ public class RepoInfoFragment extends Fragment {
//Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up); //Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
//repoMetaFrame.startAnimation(slide_up); //repoMetaFrame.startAnimation(slide_up);
} }
}
private boolean isExpandViewMetaVisible() {
return repoMetaFrame.getVisibility() == View.VISIBLE;
} }
private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) { private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) {
@ -251,64 +236,16 @@ public class RepoInfoFragment extends Fragment {
if (response.code() == 200) { if (response.code() == 200) {
assert repoInfo != null; assert repoInfo != null;
repoMetaName.setText(repoInfo.getName()); repoNameInfo.setText(repoInfo.getName());
repoMetaDescription.setText(repoInfo.getDescription()); repoOwnerInfo.setText(owner);
repoMetaStars.setText(repoInfo.getStars_count()); repoDescriptionInfo.setText(repoInfo.getDescription());
repoWebsiteInfo.setText(repoInfo.getWebsite());
if(repoInfo.getOpen_pull_count() != null) { repoSizeInfo.setText(AppUtil.formatFileSize(repoInfo.getSize()));
repoMetaPullRequests.setText(repoInfo.getOpen_pull_count()); repoDefaultBranchInfo.setText(repoInfo.getDefault_branch());
} repoSshUrlInfo.setText(repoInfo.getSsh_url());
else { repoCloneUrlInfo.setText(repoInfo.getClone_url());
repoMetaPullRequestsFrame.setVisibility(View.GONE); repoRepoUrlInfo.setText(repoInfo.getHtml_url());
} repoForksCountInfo.setText(repoInfo.getForks_count());
repoMetaForks.setText(repoInfo.getForks_count());
repoMetaWatchers.setText(repoInfo.getWatchers_count());
if(repoInfo.getSize() != 0) {
repoMetaSize.setText(AppUtil.formatFileSize(repoInfo.getSize()));
}
else {
repoMetaSize.setText("0");
}
repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx));
if(timeFormat.equals("pretty")) {
repoMetaCreatedAt.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), ctx));
}
String repoMetaUpdatedAt = TimeHelper.formatTime(repoInfo.getUpdated_at(), new Locale(locale), timeFormat, ctx);
String website = (repoInfo.getWebsite().isEmpty()) ? getResources().getString(R.string.noDataWebsite) : repoInfo.getWebsite();
repoMetaWebsite.setText(website);
repoAdditionalButton.setOnClickListener(v -> {
StringBuilder message = new StringBuilder();
message.append(getResources().getString(R.string.infoTabRepoDefaultBranch))
.append(" :\n").append(repoInfo.getDefault_branch()).append("\n\n");
message.append(getResources().getString(R.string.infoTabRepoUpdatedAt))
.append(" :\n").append(repoMetaUpdatedAt).append("\n\n");
message.append(getResources().getString(R.string.infoTabRepoSshUrl))
.append(" :\n").append(repoInfo.getSsh_url()).append("\n\n");
message.append(getResources().getString(R.string.infoTabRepoCloneUrl))
.append(" :\n").append(repoInfo.getClone_url()).append("\n\n");
message.append(getResources().getString(R.string.infoTabRepoRepoUrl))
.append(" :\n").append(repoInfo.getHtml_url());
AlertDialog.Builder alertDialog = new AlertDialog.Builder(ctx);
alertDialog.setTitle(getResources().getString(R.string.infoMoreInformation));
alertDialog.setMessage(message);
alertDialog.setPositiveButton(getResources().getString(R.string.close), (dialog, which) -> dialog.dismiss());
alertDialog.create().show();
});
if(repoInfo.getHas_issues() != null) { if(repoInfo.getHas_issues() != null) {
tinyDb.putBoolean("hasIssues", repoInfo.getHas_issues()); tinyDb.putBoolean("hasIssues", repoInfo.getHas_issues());
@ -317,7 +254,27 @@ public class RepoInfoFragment extends Fragment {
tinyDb.putBoolean("hasIssues", true); tinyDb.putBoolean("hasIssues", true);
} }
tinyDb.putString("repoHtmlUrl", repoInfo.getHtml_url()); switch (timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(repoInfo.getCreated_at());
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); mProgressBar.setVisibility(View.GONE);
pageContent.setVisibility(View.VISIBLE); pageContent.setVisibility(View.VISIBLE);
@ -417,14 +374,13 @@ public class RepoInfoFragment extends Fragment {
.build(); .build();
Spanned 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; assert bodyWithMD != null;
markwon.setParsedMarkdown(repoFileContents, bodyWithMD); markwon.setParsedMarkdown(repoFileContents, bodyWithMD);
} else if (response.code() == 401) { } else if (response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),

View File

@ -22,7 +22,7 @@ import android.widget.ImageView;
import android.widget.ProgressBar; 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.activities.CreateRepoActivity; import org.mian.gitnex.activities.NewRepoActivity;
import org.mian.gitnex.adapters.ReposListAdapter; import org.mian.gitnex.adapters.ReposListAdapter;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
@ -79,7 +79,7 @@ public class RepositoriesFragment extends Fragment {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class); Intent intent = new Intent(view.getContext(), NewRepoActivity.class);
startActivity(intent); startActivity(intent);
} }

View File

@ -1,25 +1,25 @@
package org.mian.gitnex.fragments; package org.mian.gitnex.fragments;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import 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.CompoundButton;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
import java.util.Objects;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.util.TinyDB;
import java.util.Objects;
/** /**
* Author M M Arif * Author M M Arif
@ -29,7 +29,7 @@ public class SettingsFragment extends Fragment {
private Context ctx = null; private Context ctx = null;
private static String[] langList = {"Arabic", "Chinese", "English", "Finnish", "French", "German", "Italian", "Latvian", "Persian", "Polish", "Portuguese/Brazilian", "Russian", "Serbian", "Spanish", "Turkish", "Ukrainian"}; private static String[] langList = {"Arabic", "Chinese", "English", "Finnish", "French", "German", "Italian", "Latvian", "Persian", "Portuguese/Brazilian", "Russian", "Serbian", "Turkish", "Ukrainian"};
private static int langSelectedChoice = 0; private static int langSelectedChoice = 0;
private static String[] timeList = {"Pretty", "Normal"}; private static String[] timeList = {"Pretty", "Normal"};
@ -44,12 +44,9 @@ public class SettingsFragment extends Fragment {
private static String[] customFontList = {"Roboto", "Manrope", "Source Code Pro"}; private static String[] customFontList = {"Roboto", "Manrope", "Source Code Pro"};
private static int customFontSelectedChoice = 0; private static int customFontSelectedChoice = 0;
private static String[] themeList = {"Dark", "Light", "Auto (Day/Night)"}; private static String[] themeList = {"Dark", "Light"};
private static int themeSelectedChoice = 0; private static int themeSelectedChoice = 0;
private static String[] fileveiwerSourceCodeThemesList = {"Sublime", "Arduino Light", "Github", "Far ", "Ir Black", "Android Studio"};
private static int fileveiwerSourceCodeThemesSelectedChoice = 0;
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -63,7 +60,6 @@ public class SettingsFragment extends Fragment {
final TextView homeScreenSelected = v.findViewById(R.id.homeScreenSelected); // setter for home screen final TextView homeScreenSelected = v.findViewById(R.id.homeScreenSelected); // setter for home screen
final TextView customFontSelected = v.findViewById(R.id.customFontSelected); // setter for custom font final TextView customFontSelected = v.findViewById(R.id.customFontSelected); // setter for custom font
final TextView themeSelected = v.findViewById(R.id.themeSelected); // setter for theme final TextView themeSelected = v.findViewById(R.id.themeSelected); // setter for theme
final TextView fileveiwerSourceCodeThemesSelected = v.findViewById(R.id.sourceCodeThemeSelected); // setter for fileviewer theme
LinearLayout langFrame = v.findViewById(R.id.langFrame); LinearLayout langFrame = v.findViewById(R.id.langFrame);
LinearLayout timeFrame = v.findViewById(R.id.timeFrame); LinearLayout timeFrame = v.findViewById(R.id.timeFrame);
@ -71,22 +67,19 @@ public class SettingsFragment extends Fragment {
LinearLayout homeScreenFrame = v.findViewById(R.id.homeScreenFrame); LinearLayout homeScreenFrame = v.findViewById(R.id.homeScreenFrame);
LinearLayout customFontFrame = v.findViewById(R.id.customFontFrame); LinearLayout customFontFrame = v.findViewById(R.id.customFontFrame);
LinearLayout themeFrame = v.findViewById(R.id.themeSelectionFrame); LinearLayout themeFrame = v.findViewById(R.id.themeSelectionFrame);
LinearLayout certsFrame = v.findViewById(R.id.certsFrame);
LinearLayout sourceCodeThemeFrame = v.findViewById(R.id.sourceCodeThemeFrame);
Switch counterBadgesSwitch = v.findViewById(R.id.switchCounterBadge); Switch issuesSwitch = v.findViewById(R.id.switchIssuesBadge);
Switch pdfModeSwitch = v.findViewById(R.id.switchPdfMode); Switch pdfModeSwitch = v.findViewById(R.id.switchPdfMode);
Switch crashReportsSwitch = v.findViewById(R.id.crashReportsSwitch);
TextView helpTranslate = v.findViewById(R.id.helpTranslate); TextView helpTranslate = v.findViewById(R.id.helpTranslate);
helpTranslate.setOnClickListener(v12 -> { helpTranslate.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(); Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW); intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE); intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse(getResources().getString(R.string.crowdInLink))); intent.setData(Uri.parse(getResources().getString(R.string.crowdInLink)));
startActivity(intent); startActivity(intent);
}
}); });
if(!tinyDb.getString("localeStr").isEmpty()) { if(!tinyDb.getString("localeStr").isEmpty()) {
@ -113,10 +106,6 @@ public class SettingsFragment extends Fragment {
themeSelected.setText(tinyDb.getString("themeStr")); themeSelected.setText(tinyDb.getString("themeStr"));
} }
if(!tinyDb.getString("fileviewerSourceCodeThemeStr").isEmpty()) {
fileveiwerSourceCodeThemesSelected.setText(tinyDb.getString("fileviewerSourceCodeThemeStr"));
}
if(langSelectedChoice == 0) { if(langSelectedChoice == 0) {
langSelectedChoice = tinyDb.getInt("langId"); langSelectedChoice = tinyDb.getInt("langId");
} }
@ -134,22 +123,18 @@ public class SettingsFragment extends Fragment {
} }
if(customFontSelectedChoice == 0) { if(customFontSelectedChoice == 0) {
customFontSelectedChoice = tinyDb.getInt("customFontId", 1); customFontSelectedChoice = tinyDb.getInt("customFontId");
} }
if(themeSelectedChoice == 0) { if(themeSelectedChoice == 0) {
themeSelectedChoice = tinyDb.getInt("themeId"); themeSelectedChoice = tinyDb.getInt("themeId");
} }
if(fileveiwerSourceCodeThemesSelectedChoice == 0) { if(tinyDb.getBoolean("enableCounterIssueBadge")) {
fileveiwerSourceCodeThemesSelectedChoice = tinyDb.getInt("fileviewerThemeId"); issuesSwitch.setChecked(true);
}
if(tinyDb.getBoolean("enableCounterBadges")) {
counterBadgesSwitch.setChecked(true);
} }
else { else {
counterBadgesSwitch.setChecked(false); issuesSwitch.setChecked(false);
} }
if(tinyDb.getBoolean("enablePdfMode")) { if(tinyDb.getBoolean("enablePdfMode")) {
@ -159,110 +144,40 @@ public class SettingsFragment extends Fragment {
pdfModeSwitch.setChecked(false); pdfModeSwitch.setChecked(false);
} }
if(tinyDb.getBoolean("crashReportingEnabled")) { // issues badge switcher
crashReportsSwitch.setChecked(true); issuesSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
} public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
else {
crashReportsSwitch.setChecked(false);
}
// fileviewer srouce code theme selection dialog
sourceCodeThemeFrame.setOnClickListener(view -> {
AlertDialog.Builder fvtsBuilder = new AlertDialog.Builder(ctx);
fvtsBuilder.setTitle(R.string.fileviewerSourceCodeThemeSelectorDialogTitle);
if(fileveiwerSourceCodeThemesSelectedChoice != -1) {
fvtsBuilder.setCancelable(true);
}
else {
fvtsBuilder.setCancelable(false);
}
fvtsBuilder.setSingleChoiceItems(fileveiwerSourceCodeThemesList, fileveiwerSourceCodeThemesSelectedChoice, (dialogInterfaceTheme, i) -> {
fileveiwerSourceCodeThemesSelectedChoice = i;
fileveiwerSourceCodeThemesSelected.setText(fileveiwerSourceCodeThemesList[i]);
tinyDb.putString("fileviewerSourceCodeThemeStr", fileveiwerSourceCodeThemesList[i]);
tinyDb.putInt("fileviewerSourceCodeThemeId", i);
Objects.requireNonNull(getActivity()).recreate();
getActivity().overridePendingTransition(0, 0);
dialogInterfaceTheme.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
});
AlertDialog cfDialog = fvtsBuilder.create();
cfDialog.show();
});
// certs deletion
certsFrame.setOnClickListener(v1 -> {
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle(getResources().getString(R.string.settingsCertsPopupTitle));
builder.setMessage(getResources().getString(R.string.settingsCertsPopupMessage));
builder.setPositiveButton(R.string.menuDeleteText, (dialog, which) -> {
ctx.getSharedPreferences(MemorizingTrustManager.KEYSTORE_NAME, Context.MODE_PRIVATE).edit().remove(MemorizingTrustManager.KEYSTORE_KEY).apply();
MainActivity.logout(Objects.requireNonNull(getActivity()), ctx);
});
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
builder.create().show();
});
// counter badge switcher
counterBadgesSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (isChecked) { if (isChecked) {
tinyDb.putBoolean("enableCounterBadges", true); tinyDb.putBoolean("enableCounterIssueBadge", true);
tinyDb.putString("enableCounterIssueBadgeInit", "yes");
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
} else {
tinyDb.putBoolean("enableCounterIssueBadge", false);
tinyDb.putString("enableCounterIssueBadgeInit", "yes");
Toasty.info(getContext(), getResources().getString(R.string.settingsSave)); Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
} }
else {
tinyDb.putBoolean("enableCounterBadges", false);
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
} }
}); });
// pdf night mode switcher // pdf night mode switcher
pdfModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { pdfModeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) { if (isChecked) {
tinyDb.putBoolean("enablePdfMode", true); tinyDb.putBoolean("enablePdfMode", true);
tinyDb.putString("enablePdfModeInit", "yes"); tinyDb.putString("enablePdfModeInit", "yes");
Toasty.info(getContext(), getResources().getString(R.string.settingsSave)); Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
} } else {
else {
tinyDb.putBoolean("enablePdfMode", false); tinyDb.putBoolean("enablePdfMode", false);
tinyDb.putString("enablePdfModeInit", "yes"); tinyDb.putString("enablePdfModeInit", "yes");
Toasty.info(getContext(), getResources().getString(R.string.settingsSave)); Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
} }
});
// crash reports switcher
crashReportsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked) {
tinyDb.putBoolean("crashReportingEnabled", true);
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
} }
else {
tinyDb.putBoolean("crashReportingEnabled", false);
Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
}); });
// theme selection dialog // theme selection dialog
themeFrame.setOnClickListener(view -> { themeFrame.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder tsBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder tsBuilder = new AlertDialog.Builder(ctx);
@ -274,7 +189,9 @@ public class SettingsFragment extends Fragment {
tsBuilder.setCancelable(false); tsBuilder.setCancelable(false);
} }
tsBuilder.setSingleChoiceItems(themeList, themeSelectedChoice, (dialogInterfaceTheme, i) -> { tsBuilder.setSingleChoiceItems(themeList, themeSelectedChoice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterfaceTheme, int i) {
themeSelectedChoice = i; themeSelectedChoice = i;
themeSelected.setText(themeList[i]); themeSelected.setText(themeList[i]);
@ -286,15 +203,19 @@ public class SettingsFragment extends Fragment {
dialogInterfaceTheme.dismiss(); dialogInterfaceTheme.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave)); Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
}); });
AlertDialog cfDialog = tsBuilder.create(); AlertDialog cfDialog = tsBuilder.create();
cfDialog.show(); cfDialog.show();
}
}); });
// custom font dialog // custom font dialog
customFontFrame.setOnClickListener(view -> { customFontFrame.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder cfBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder cfBuilder = new AlertDialog.Builder(ctx);
@ -306,7 +227,9 @@ public class SettingsFragment extends Fragment {
cfBuilder.setCancelable(false); cfBuilder.setCancelable(false);
} }
cfBuilder.setSingleChoiceItems(customFontList, customFontSelectedChoice, (dialogInterfaceCustomFont, i) -> { cfBuilder.setSingleChoiceItems(customFontList, customFontSelectedChoice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterfaceCustomFont, int i) {
customFontSelectedChoice = i; customFontSelectedChoice = i;
customFontSelected.setText(customFontList[i]); customFontSelected.setText(customFontList[i]);
@ -318,15 +241,19 @@ public class SettingsFragment extends Fragment {
dialogInterfaceCustomFont.dismiss(); dialogInterfaceCustomFont.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave)); Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
}); });
AlertDialog cfDialog = cfBuilder.create(); AlertDialog cfDialog = cfBuilder.create();
cfDialog.show(); cfDialog.show();
}
}); });
// home screen dialog // home screen dialog
homeScreenFrame.setOnClickListener(view -> { homeScreenFrame.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder hsBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder hsBuilder = new AlertDialog.Builder(ctx);
@ -338,7 +265,9 @@ public class SettingsFragment extends Fragment {
hsBuilder.setCancelable(false); hsBuilder.setCancelable(false);
} }
hsBuilder.setSingleChoiceItems(homeScreenList, homeScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> { hsBuilder.setSingleChoiceItems(homeScreenList, homeScreenSelectedChoice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterfaceHomeScreen, int i) {
homeScreenSelectedChoice = i; homeScreenSelectedChoice = i;
homeScreenSelected.setText(homeScreenList[i]); homeScreenSelected.setText(homeScreenList[i]);
@ -348,15 +277,19 @@ public class SettingsFragment extends Fragment {
dialogInterfaceHomeScreen.dismiss(); dialogInterfaceHomeScreen.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave)); Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
}); });
AlertDialog hsDialog = hsBuilder.create(); AlertDialog hsDialog = hsBuilder.create();
hsDialog.show(); hsDialog.show();
}
}); });
// code block dialog // code block dialog
codeBlockFrame.setOnClickListener(view -> { codeBlockFrame.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder cBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder cBuilder = new AlertDialog.Builder(ctx);
@ -368,7 +301,9 @@ public class SettingsFragment extends Fragment {
cBuilder.setCancelable(false); cBuilder.setCancelable(false);
} }
cBuilder.setSingleChoiceItems(codeBlockList, codeBlockSelectedChoice, (dialogInterfaceCodeBlock, i) -> { cBuilder.setSingleChoiceItems(codeBlockList, codeBlockSelectedChoice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterfaceCodeBlock, int i) {
codeBlockSelectedChoice = i; codeBlockSelectedChoice = i;
codeBlockSelected.setText(codeBlockList[i]); codeBlockSelected.setText(codeBlockList[i]);
@ -401,15 +336,19 @@ public class SettingsFragment extends Fragment {
dialogInterfaceCodeBlock.dismiss(); dialogInterfaceCodeBlock.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave)); Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
}); });
AlertDialog cDialog = cBuilder.create(); AlertDialog cDialog = cBuilder.create();
cDialog.show(); cDialog.show();
}
}); });
// language dialog // language dialog
langFrame.setOnClickListener(view -> { langFrame.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder lBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder lBuilder = new AlertDialog.Builder(ctx);
@ -421,7 +360,9 @@ public class SettingsFragment extends Fragment {
lBuilder.setCancelable(false); lBuilder.setCancelable(false);
} }
lBuilder.setSingleChoiceItems(langList, langSelectedChoice, (dialogInterface, i) -> { lBuilder.setSingleChoiceItems(langList, langSelectedChoice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
langSelectedChoice = i; langSelectedChoice = i;
tvLanguageSelected.setText(langList[i]); tvLanguageSelected.setText(langList[i]);
@ -453,9 +394,6 @@ public class SettingsFragment extends Fragment {
case "Persian": case "Persian":
tinyDb.putString("locale", "fa"); tinyDb.putString("locale", "fa");
break; break;
case "Polish":
tinyDb.putString("locale", "pl");
break;
case "Portuguese/Brazilian": case "Portuguese/Brazilian":
tinyDb.putString("locale", "pt"); tinyDb.putString("locale", "pt");
break; break;
@ -465,9 +403,6 @@ public class SettingsFragment extends Fragment {
case "Serbian": case "Serbian":
tinyDb.putString("locale", "sr"); tinyDb.putString("locale", "sr");
break; break;
case "Spanish":
tinyDb.putString("locale", "es");
break;
case "Turkish": case "Turkish":
tinyDb.putString("locale", "tr"); tinyDb.putString("locale", "tr");
break; break;
@ -484,17 +419,25 @@ public class SettingsFragment extends Fragment {
Objects.requireNonNull(getActivity()).recreate(); Objects.requireNonNull(getActivity()).recreate();
getActivity().overridePendingTransition(0, 0); getActivity().overridePendingTransition(0, 0);
}
});
lBuilder.setNegativeButton(getString(R.string.cancelButton), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}); });
lBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> dialog.dismiss());
AlertDialog lDialog = lBuilder.create(); AlertDialog lDialog = lBuilder.create();
lDialog.show(); lDialog.show();
}
}); });
// time n date dialog // time n date dialog
timeFrame.setOnClickListener(view -> { timeFrame.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder tBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder tBuilder = new AlertDialog.Builder(ctx);
@ -506,7 +449,9 @@ public class SettingsFragment extends Fragment {
tBuilder.setCancelable(false); tBuilder.setCancelable(false);
} }
tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, (dialogInterfaceTime, i) -> { tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterfaceTime, int i) {
timeSelectedChoice = i; timeSelectedChoice = i;
tvDateTimeSelected.setText(timeList[i]); tvDateTimeSelected.setText(timeList[i]);
@ -515,31 +460,29 @@ public class SettingsFragment extends Fragment {
if ("Normal".equals(timeList[i])) { if ("Normal".equals(timeList[i])) {
tinyDb.putString("dateFormat", "normal"); tinyDb.putString("dateFormat", "normal");
} } else {
else {
tinyDb.putString("dateFormat", "pretty"); tinyDb.putString("dateFormat", "pretty");
} }
dialogInterfaceTime.dismiss(); dialogInterfaceTime.dismiss();
Toasty.info(getContext(), getResources().getString(R.string.settingsSave)); Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
}
}); });
AlertDialog tDialog = tBuilder.create(); AlertDialog tDialog = tBuilder.create();
tDialog.show(); tDialog.show();
}
}); });
return v; return v;
} }
@Override @Override
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(context); super.onAttach(context);
ctx = context; ctx = context;
} }
} }

View File

@ -1,6 +1,5 @@
package org.mian.gitnex.fragments; package org.mian.gitnex.fragments;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -15,6 +14,7 @@ import org.mian.gitnex.activities.AddRemoveLabelsActivity;
import org.mian.gitnex.activities.EditIssueActivity; import org.mian.gitnex.activities.EditIssueActivity;
import org.mian.gitnex.activities.FileDiffActivity; import org.mian.gitnex.activities.FileDiffActivity;
import org.mian.gitnex.activities.MergePullRequestActivity; import org.mian.gitnex.activities.MergePullRequestActivity;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.helpers.Toasty; 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;
@ -27,17 +27,17 @@ import java.util.Objects;
* Author M M Arif * Author M M Arif
*/ */
public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { public class SingleIssueBottomSheetFragment extends BottomSheetDialogFragment {
@Nullable @Nullable
@Override @Override
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.bottom_sheet_single_issue_layout, container, false); View v = inflater.inflate(R.layout.single_issue_bottom_sheet_layout, container, false);
final Context ctx = getContext(); final TinyDB tinyDB = new TinyDB(getContext());
final TinyDB tinyDB = new TinyDB(ctx);
TextView replyToIssue = v.findViewById(R.id.replyToIssue);
TextView editIssue = v.findViewById(R.id.editIssue); TextView editIssue = v.findViewById(R.id.editIssue);
TextView editLabels = v.findViewById(R.id.editLabels); TextView editLabels = v.findViewById(R.id.editLabels);
TextView closeIssue = v.findViewById(R.id.closeIssue); TextView closeIssue = v.findViewById(R.id.closeIssue);
@ -46,15 +46,21 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
TextView copyIssueUrl = v.findViewById(R.id.copyIssueUrl); TextView copyIssueUrl = v.findViewById(R.id.copyIssueUrl);
TextView openFilesDiff = v.findViewById(R.id.openFilesDiff); TextView openFilesDiff = v.findViewById(R.id.openFilesDiff);
TextView mergePullRequest = v.findViewById(R.id.mergePullRequest); TextView mergePullRequest = v.findViewById(R.id.mergePullRequest);
TextView shareIssue = v.findViewById(R.id.shareIssue);
TextView subscribeIssue = v.findViewById(R.id.subscribeIssue); replyToIssue.setOnClickListener(new View.OnClickListener() {
TextView unsubscribeIssue = v.findViewById(R.id.unsubscribeIssue); @Override
public void onClick(View v) {
startActivity(new Intent(getContext(), ReplyToIssueActivity.class));
dismiss();
}
});
if(tinyDB.getString("issueType").equals("pr")) { if(tinyDB.getString("issueType").equals("pr")) {
editIssue.setText(R.string.editPrText); editIssue.setText(R.string.editPrText);
copyIssueUrl.setText(R.string.copyPrUrlText); copyIssueUrl.setText(R.string.copyPrUrlText);
shareIssue.setText(R.string.sharePr);
if(tinyDB.getBoolean("prMerged")) { if(tinyDB.getBoolean("prMerged")) {
mergePullRequest.setVisibility(View.GONE); mergePullRequest.setVisibility(View.GONE);
@ -81,7 +87,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startActivity(new Intent(ctx, MergePullRequestActivity.class)); startActivity(new Intent(getContext(), MergePullRequestActivity.class));
dismiss(); dismiss();
} }
@ -91,7 +97,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startActivity(new Intent(ctx, FileDiffActivity.class)); startActivity(new Intent(getContext(), FileDiffActivity.class));
dismiss(); dismiss();
} }
@ -101,7 +107,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startActivity(new Intent(ctx, EditIssueActivity.class)); startActivity(new Intent(getContext(), EditIssueActivity.class));
dismiss(); dismiss();
} }
@ -111,7 +117,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startActivity(new Intent(ctx, AddRemoveLabelsActivity.class)); startActivity(new Intent(getContext(), AddRemoveLabelsActivity.class));
dismiss(); dismiss();
} }
@ -121,35 +127,12 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startActivity(new Intent(ctx, AddRemoveAssigneesActivity.class)); startActivity(new Intent(getContext(), AddRemoveAssigneesActivity.class));
dismiss(); dismiss();
} }
}); });
shareIssue.setOnClickListener(v1 -> {
// get url of repo
String repoFullName = tinyDB.getString("repoFullName");
String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw");
if (!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) {
instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol");
}
// get issue Url
String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber");
// share issue
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, issueUrl);
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle")));
dismiss();
});
copyIssueUrl.setOnClickListener(new View.OnClickListener() { copyIssueUrl.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -165,14 +148,14 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber"); String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber");
// copy to clipboard // copy to clipboard
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(android.content.Context.CLIPBOARD_SERVICE); ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(getContext()).getSystemService(android.content.Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("issueUrl", issueUrl); ClipData clip = ClipData.newPlainText("issueUrl", issueUrl);
assert clipboard != null; assert clipboard != null;
clipboard.setPrimaryClip(clip); clipboard.setPrimaryClip(clip);
dismiss(); dismiss();
Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg)); Toasty.info(getContext(), getContext().getString(R.string.copyIssueUrlToastMsg));
} }
}); });
@ -182,26 +165,29 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
if (tinyDB.getString("issueState").equals("open")) { // close issue if (tinyDB.getString("issueState").equals("open")) { // close issue
reOpenIssue.setVisibility(View.GONE); reOpenIssue.setVisibility(View.GONE);
closeIssue.setVisibility(View.VISIBLE);
closeIssue.setOnClickListener(closeSingleIssue -> { closeIssue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "closed"); IssueActions.closeReopenIssue(getContext(), Integer.valueOf(tinyDB.getString("issueNumber")), "closed");
dismiss(); dismiss();
});
} }
else if (tinyDB.getString("issueState").equals("closed")) { });
} else if (tinyDB.getString("issueState").equals("closed")) {
closeIssue.setVisibility(View.GONE); closeIssue.setVisibility(View.GONE);
reOpenIssue.setVisibility(View.VISIBLE);
reOpenIssue.setOnClickListener(reOpenSingleIssue -> { reOpenIssue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "open"); IssueActions.closeReopenIssue(getContext(), Integer.valueOf(tinyDB.getString("issueNumber")), "open");
dismiss(); dismiss();
}
}); });
} }
@ -214,27 +200,6 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
} }
subscribeIssue.setOnClickListener(subscribeToIssue -> {
IssueActions.subscribe(ctx, subscribeIssue, unsubscribeIssue);
//dismiss();
});
unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> {
IssueActions.unsubscribe(ctx, subscribeIssue, unsubscribeIssue);
//dismiss();
});
//if RepoWatch True Provide Unsubscribe first
// ToDo: API to check if user is subscribed to an issue (do not exist can be guessed by many api endpoints :/)
if (tinyDB.getBoolean("repoWatch")) {
subscribeIssue.setVisibility(View.GONE);
unsubscribeIssue.setVisibility(View.VISIBLE);
}
return v; return v;
} }

View File

@ -24,7 +24,7 @@ import android.widget.ImageView;
import android.widget.ProgressBar; 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.activities.CreateRepoActivity; import org.mian.gitnex.activities.NewRepoActivity;
import org.mian.gitnex.adapters.StarredReposListAdapter; import org.mian.gitnex.adapters.StarredReposListAdapter;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
@ -104,7 +104,7 @@ public class StarredRepositoriesFragment extends Fragment {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class); Intent intent = new Intent(view.getContext(), NewRepoActivity.class);
startActivity(intent); startActivity(intent);
} }

View File

@ -1,103 +0,0 @@
package org.mian.gitnex.helpers;
import java.io.IOException;
import java.util.Objects;
import org.mian.gitnex.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.text.Html;
import android.util.Log;
import androidx.appcompat.app.AlertDialog;
/**
* Author M M Arif
*/
public class ChangeLog {
static final private String TAG = "ChangeLog";
static final private String CHANGELOG_XML_NODE = "changelog";
private Activity changelogActivity;
public ChangeLog(Activity context) {
changelogActivity = context;
}
private String ParseReleaseTag(XmlResourceParser aXml) throws XmlPullParserException, IOException {
StringBuilder strBuilder = new StringBuilder(aXml.getAttributeValue(null, "version") + "<br>");
int eventType = aXml.getEventType();
while ((eventType != XmlPullParser.END_TAG) || (aXml.getName().equals("change"))) {
if ((eventType == XmlPullParser.START_TAG) && (aXml.getName().equals("change"))) {
eventType = aXml.next();
strBuilder.append(aXml.getText()).append("<br>");
}
eventType = aXml.next();
}
strBuilder.append("<br>");
return strBuilder.toString();
}
private String getChangelog(int resId, Resources res) {
StringBuilder strBuilder = new StringBuilder();
try (XmlResourceParser xml = res.getXml(resId)) {
int eventType = xml.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if ((eventType == XmlPullParser.START_TAG) && (xml.getName().equals("release"))) {
strBuilder.append(ParseReleaseTag(xml));
}
eventType = xml.next();
}
}
catch (XmlPullParserException | IOException e) {
Log.e(TAG, Objects.requireNonNull(e.getMessage()));
}
return strBuilder.toString();
}
public void showDialog() {
String packageName = changelogActivity.getPackageName();
Resources res = null;
try {
res = changelogActivity.getPackageManager().getResourcesForApplication(packageName);
}
catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, Objects.requireNonNull(e.getMessage()));
}
assert res != null;
int resId = res.getIdentifier(CHANGELOG_XML_NODE, "xml", packageName);
String changelogMessage = getChangelog(resId, res);
androidx.appcompat.app.AlertDialog.Builder builder = new AlertDialog.Builder(changelogActivity);
builder.setTitle(R.string.changelogTitle);
builder.setMessage(Html.fromHtml("<small>" + changelogMessage + "</small>"));
builder.setNegativeButton(R.string.close, (dialog, which) -> dialog.cancel());
builder.setCancelable(false);
builder.create();
builder.show();
}
}

View File

@ -1,28 +1,11 @@
package org.mian.gitnex.helpers; package org.mian.gitnex.helpers;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class LabelWidthCalculator { public class LabelWidthCalculator {
public static int calculateLabelWidth(String text, Typeface typeface, int textSize, int paddingLeftRight) {
Paint paint = new Paint();
Rect rect = new Rect();
paint.setTextSize(textSize);
paint.setTypeface(typeface);
paint.getTextBounds(text, 0, text.length(), rect);
return rect.width() + (paddingLeftRight * 2);
}
public static int customWidth(int labelLength) { public static int customWidth(int labelLength) {
int width = 33; int width = 33;

View File

@ -1,82 +0,0 @@
package org.mian.gitnex.helpers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
/**
* Author M M Arif
*/
public class NetworkObserver implements LifecycleObserver {
private ConnectivityManager mConnectivityMgr;
private Context mContext;
private NetworkStateReceiver mNetworkStateReceiver;
public interface ConnectionStateListener {
void onAvailable(boolean isAvailable);
}
public NetworkObserver(Context context) {
mContext = context;
mConnectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
((AppCompatActivity) mContext).getLifecycle().addObserver(this);
}
public void onInternetStateListener(ConnectionStateListener listener) {
mNetworkStateReceiver = new NetworkStateReceiver(listener);
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(mNetworkStateReceiver, intentFilter);
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy() {
((AppCompatActivity) mContext).getLifecycle().removeObserver(this);
if (mNetworkStateReceiver != null) {
mContext.unregisterReceiver(mNetworkStateReceiver);
}
}
public class NetworkStateReceiver extends BroadcastReceiver {
ConnectionStateListener mListener;
public NetworkStateReceiver(ConnectionStateListener listener) {
mListener = listener;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getExtras() != null) {
NetworkInfo activeNetworkInfo = mConnectivityMgr.getActiveNetworkInfo();
if (activeNetworkInfo != null && activeNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
mListener.onAvailable(true); // connected
} else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
mListener.onAvailable(false); // disconnected
}
}
}
}
}

View File

@ -1,203 +0,0 @@
package org.mian.gitnex.helpers;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.squareup.picasso.Cache;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* Author anonTree1417
*/
public class PicassoCache implements Cache {
private String TAG = "PicassoCache";
private static final Bitmap.CompressFormat COMPRESS_FORMAT = Bitmap.CompressFormat.PNG;
private static final int COMPRESSION_QUALITY = 0; // 0 = high compression (low file size) | 100 = no compression
private static final String CACHE_MAP_FILE = "cacheMap";
private static final int CACHE_SIZE = 25 * 1024 * 1024; // Cache can hold twenty-five megabytes
private File cachePath;
private HashMap<String, String> cacheMap;
public PicassoCache(File cachePath) throws IOException, ClassNotFoundException {
this.cachePath = cachePath;
cacheMap = new HashMap<>();
if(cacheMapExists(cachePath)) {
cacheMap.putAll(loadCacheMap());
}
}
@Override
public Bitmap get(String key) {
try {
if(cacheMap.containsKey(key)) {
FileInputStream fileInputStream = new FileInputStream(new File(cachePath, cacheMap.get(key)));
Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream);
fileInputStream.close();
return bitmap;
}
}
catch(IOException e) {
Log.e(TAG, e.toString());
}
return null;
}
@Override
public void set(String key, Bitmap bitmap) {
try {
String uuid = generateRandomFilename();
File file = new File(cachePath, uuid);
FileOutputStream fileOutputStream = new FileOutputStream(file, false);
bitmap.compress(COMPRESS_FORMAT, COMPRESSION_QUALITY, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
cacheMap.put(key, uuid);
saveCacheMap(cacheMap);
}
catch(IOException e) {
Log.e(TAG, e.toString());
}
}
@Override
public int size() {
int currentSize = 0;
for(String key : cacheMap.keySet()) {
currentSize += new File(cachePath, cacheMap.get(key)).length();
}
return currentSize;
}
@Override
public int maxSize() {
return CACHE_SIZE;
}
@Override
public void clear() {
File[] files = cachePath.listFiles();
if(files != null) {
for(File file : files) {
//noinspection ResultOfMethodCallIgnored
file.delete();
}
}
}
@Override
public void clearKeyUri(String keyPrefix) {
for(String key : cacheMap.keySet()) {
int len = Math.min(keyPrefix.length(), key.length());
boolean match = true;
for(int i=0; i<len; i++) {
if(key.charAt(i) != keyPrefix.charAt(i)) {
match = false;
break;
}
}
if(match) {
//noinspection ResultOfMethodCallIgnored
new File(cachePath, cacheMap.get(key)).delete();
cacheMap.remove(key);
}
}
}
private String generateRandomFilename() {
return UUID.randomUUID().toString();
}
private void saveCacheMap(Map<String, String> cacheMap) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File(cachePath, CACHE_MAP_FILE), false));
objectOutputStream.writeObject(cacheMap);
objectOutputStream.flush();
objectOutputStream.close();
}
private Map<String, String> loadCacheMap() throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File(cachePath, CACHE_MAP_FILE)));
Map<String, String> map = (HashMap<String, String>) objectInputStream.readObject();
objectInputStream.close();
return map;
}
private boolean cacheMapExists(File cachePath) {
return new File(cachePath, CACHE_MAP_FILE).exists();
}
}

View File

@ -1,63 +0,0 @@
package org.mian.gitnex.helpers;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import org.mian.gitnex.R;
/**
* Author M M Arif
*/
public class SnackBar {
public static void info(Context context, View createRepository, String message) {
Snackbar snackBar = Snackbar.make(createRepository, message, Snackbar.LENGTH_LONG);
View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text);
textView.setTextColor(context.getResources().getColor(R.color.lightBlue));
snackBar.show();
}
public static void success(Context context, View createRepository, String message) {
Snackbar snackBar = Snackbar.make(createRepository, message, Snackbar.LENGTH_LONG);
View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text);
textView.setTextColor(context.getResources().getColor(R.color.white));
snackBar.show();
}
public static void warning(Context context, View createRepository, String message) {
Snackbar snackBar = Snackbar.make(createRepository, message, Snackbar.LENGTH_LONG);
View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text);
textView.setTextColor(context.getResources().getColor(R.color.lightYellow));
snackBar.show();
}
public static void error(Context context, View createRepository, String message) {
Snackbar snackBar = Snackbar.make(createRepository, message, Snackbar.LENGTH_LONG);
View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text);
textView.setTextColor(context.getResources().getColor(R.color.darkRed));
snackBar.show();
}
}

View File

@ -1,18 +0,0 @@
package org.mian.gitnex.helpers;
/**
* Author M M Arif
*/
public interface StaticGlobalVariables {
// issues variables
String tagIssuesListOpen = "IssuesListOpenFragment - ";
String tagIssuesListClosed = "IssuesListClosedFragment - ";
int issuesPageInit = 1;
int resultLimitNewGiteaInstances = 25; // Gitea 1.12 and above
int resultLimitOldGiteaInstances = 10; // Gitea 1.11 and below
String issuesRequestType = "issues";
String issueStateClosed = "closed";
}

View File

@ -1,19 +1,11 @@
package org.mian.gitnex.helpers; package org.mian.gitnex.helpers;
import android.content.Context;
import org.mian.gitnex.R;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
/**
* Author M M Arif
*/
public class TimeHelper { public class TimeHelper {
public static String customDateFormatForToast(String customDate) { public static String customDateFormatForToast(String customDate) {
@ -24,8 +16,7 @@ public class TimeHelper {
Date createdTime = null; Date createdTime = null;
try { try {
createdTime = formatter.parse(part1); createdTime = formatter.parse(part1);
} } catch (ParseException e) {
catch(ParseException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -34,34 +25,6 @@ public class TimeHelper {
} }
public static String formatTime(Date date, Locale locale, String timeFormat, Context context) {
if(date == null) {
return "";
}
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(Locale.getDefault());
return prettyTime.format(date);
}
case "normal": {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
return formatter.format(date);
}
case "normal1": {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
return formatter.format(date);
}
}
return "";
}
public static String customDateFormatForToastDateFormat(Date customDate) { public static String customDateFormatForToastDateFormat(Date customDate) {
DateFormat format = DateFormat.getDateTimeInstance(); DateFormat format = DateFormat.getDateTimeInstance();
@ -69,29 +32,4 @@ public class TimeHelper {
} }
public static boolean timeBetweenHours(int fromHour, int toHour) {
Calendar cal = Calendar.getInstance();
Calendar from = Calendar.getInstance();
from.set(Calendar.HOUR_OF_DAY, fromHour);
from.set(Calendar.MINUTE, 0);
Calendar to = Calendar.getInstance();
to.set(Calendar.HOUR_OF_DAY, toHour);
to.set(Calendar.MINUTE, 0);
if(to.before(from)) {
if(cal.after(to)) {
to.add(Calendar.DATE, 1);
}
else {
from.add(Calendar.DATE, -1);
}
}
return cal.after(from) && cal.before(to);
}
} }

View File

@ -102,22 +102,6 @@ public enum VersionCheck {
* 2 = more * 2 = more
*/ */
public static int compareVersion(String A, String B) { public static int compareVersion(String A, String B) {
final Pattern pattern_stable_release = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)");
final Pattern pattern_dev_release = Pattern.compile("^(\\d).(\\d+).(\\d+)(\\D)(.+)");
Matcher match;
match = pattern_dev_release.matcher(A);
if (match.find()) {
match = pattern_stable_release.matcher(A);
match.find();
A = match.group();
}
match = pattern_dev_release.matcher(B);
if (match.find()) {
match = pattern_stable_release.matcher(B);
match.find();
B = match.group();
}
//throw new IllegalArgumentException //throw new IllegalArgumentException
if((!A.matches("[0-9]+(\\.[0-9]+)*")) || (!B.matches("[0-9]+(\\.[0-9]+)*"))) throw new IllegalArgumentException("Invalid version format"); if((!A.matches("[0-9]+(\\.[0-9]+)*")) || (!B.matches("[0-9]+(\\.[0-9]+)*"))) throw new IllegalArgumentException("Invalid version format");

View File

@ -1,15 +0,0 @@
package org.mian.gitnex.helpers.ssl;
/**
* Author Georg Lukas, modified by anonTree1417
*/
class MTMDecision {
final static int DECISION_INVALID = 0;
final static int DECISION_ABORT = 1;
final static int DECISION_ALWAYS = 2;
int state = DECISION_INVALID;
}

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