Compare commits

..

4 Commits

Author SHA1 Message Date
f448e3dcad Prepare release 3.0.1 (#625)
Prepare release 3.0.1

Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/625
2020-07-29 20:49:41 +02:00
d448a06d95 Drop support for login with email (#622) (#623)
Drop support for login with email (#622)

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/623
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-29 20:27:43 +02:00
b6950e5238 [3.0.1] Fix draft creation (#618) (#621)
Backport fix draft creation

Co-authored-by: 6543 <6543@noreply.codeberg.org>
Co-authored-by: M M Arif <mmarif@swatian.com>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/621
Reviewed-by: 6543 <6543@noreply.codeberg.org>
2020-07-29 20:05:16 +02:00
17a4958a65 BasicAuth Login: Handle existing token (#611) (#619)
BasicAuth Login: Handle existing token (#611)

fix code comment

bugfix

code format

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/611
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/619
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
2020-07-29 17:38:03 +02:00
416 changed files with 7939 additions and 15613 deletions

View File

@ -66,7 +66,7 @@ steps:
- name: build - name: build
image: nextcloudci/android:android-49 image: nextcloudci/android:android-49
commands: commands:
- ./gradlew assembleFreeRelease - ./gradlew build
- name: sign - name: sign
image: nextcloudci/android:android-49 image: nextcloudci/android:android-49
@ -78,7 +78,7 @@ steps:
KEY_PASS: KEY_PASS:
from_secret: KEY_PASS from_secret: KEY_PASS
OUTPUT: signed.apk OUTPUT: signed.apk
INSTANCE: https://codeberg.org GITEA: https://gitea.com
KS_FILE: ci_keystore.jks KS_FILE: ci_keystore.jks
KS_REPO: KS_REPO:
from_secret: KS_REPO from_secret: KS_REPO

View File

@ -20,7 +20,6 @@ _(This step is optional; an example is shown below)_
* The version of **Gitea** you are using: * The version of **Gitea** you are using:
* The version of **GitNex** you are using: * The version of **GitNex** you are using:
* Source of installation(Google play, F-droid, APK):
* Phone **OS** version and model: * Phone **OS** version and model:
* The type of certificate you are using (self-signed, signed): * The type of certificate you are using (self-signed, signed):
* How you used to log in (via password or token): * How you used to log in (via password or token):

3
.gitignore vendored
View File

@ -11,9 +11,6 @@
# Release dir # Release dir
app/release/* app/release/*
# Pro dir
app/pro/*
# Files for the ART/Dalvik VM # Files for the ART/Dalvik VM
*.dex *.dex

View File

@ -7,9 +7,6 @@ stages:
test: test:
image: nextcloudci/android:android-49 image: nextcloudci/android:android-49
stage: test stage: test
only:
- master
- tags
script: script:
- ./gradlew test - ./gradlew test
@ -18,9 +15,8 @@ build:
stage: build stage: build
only: only:
- master - master
- tags
script: script:
- ./gradlew assembleFreeRelease - ./gradlew build
artifacts: artifacts:
paths: paths:
- app/build/outputs/ - app/build/outputs/
@ -31,10 +27,9 @@ sign:
stage: sign stage: sign
only: only:
- master - master
- tags
variables: variables:
OUTPUT: "signed.apk" OUTPUT: "signed.apk"
INSTANCE: "https://codeberg.org" GITEA: "https://gitea.com"
KS_FILE: "ci_keystore.jks" KS_FILE: "ci_keystore.jks"
script: script:
- ./scripts/sign-build.sh - ./scripts/sign-build.sh
@ -48,7 +43,6 @@ latest:
stage: publish stage: publish
only: only:
- master - master
- tags
variables: variables:
WEBDAV_USERNAME: "GitNexBot" WEBDAV_USERNAME: "GitNexBot"
PLUGIN_FILE: "signed.apk" PLUGIN_FILE: "signed.apk"

View File

@ -16,15 +16,6 @@
</value> </value>
</option> </option>
</JavaCodeStyleSettings> </JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" withSubpackages="false" static="false" />
<package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
<package name="io.ktor" withSubpackages="true" static="false" />
</value>
</option>
</JetCodeStyleSettings>
<codeStyleSettings language="JAVA"> <codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="220" /> <option name="RIGHT_MARGIN" value="220" />
<option name="KEEP_LINE_BREAKS" value="false" /> <option name="KEEP_LINE_BREAKS" value="false" />

View File

@ -1,17 +1,17 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) ![Pipeline status](https://img.shields.io/gitlab/pipeline/opyale/gitnex/master) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://codeberg.org/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://codeberg.org/gitnex/GitNex/releases) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://codeberg.org/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://codeberg.org/gitnex/GitNex/releases) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf)
[<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif) [<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate) [<img alt="Become a Patroen" src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="40"/>](https://www.patreon.com/mmarif) [<img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" height="40"/>](https://liberapay.com/mmarif/donate)
# GitNex - Android client for Gitea # GitNex - Android client for Gitea
GitNex is a free/paid, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go. GitNex is a free, open-source Android client for Git repository management tool Gitea. Gitea is a community managed fork of Gogs, lightweight code hosting solution written in Go.
GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. No trackers are used and source code is available here for anyone to audit. GitNex is licensed under GPLv3 License. See the LICENSE file for the full license text. No trackers are used and source code is available here for anyone to audit.
## Downloads ## Downloads
[<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/) [<img alt='Get it on F-droid' src='https://gitlab.com/fdroid/artwork/raw/master/badge/get-it-on.png' height="80"/>](https://f-droid.org/en/packages/org.mian.gitnex/)
[<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex.pro) [<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' height="80"/>](https://play.google.com/store/apps/details?id=org.mian.gitnex)
[<img alt='Download builds and releases' src='https://codeberg.org/gitnex/GitNex/src/branch/master/assets/apk-badge.png' height="82"/>](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE) [<img alt='Download builds and releases' src='assets/apk-badge.png' height="82"/>](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE)
## Note about Gitea version ## Note about Gitea version
Please make sure that you are on latest stable release or later for better app experience. Please make sure that you are on latest stable release or later for better app experience.
@ -21,10 +21,10 @@ Check the versions [compatibility page](https://codeberg.org/gitnex/GitNex/wiki/
## Build from source ## Build from source
Option 1 - Download the source code, open it in Android Studio and build it there. Option 1 - Download the source code, open it in Android Studio and build it there.
Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew assembleFree`. Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew build`.
## Features ## Features
- Multiple accounts support - Repositories / issues/ org list
- File and directory browser - File and directory browser
- File viewer - File viewer
- Create files - Create files
@ -33,7 +33,6 @@ Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew assemb
- Files diff for PRs - Files diff for PRs
- Notifications - Notifications
- Drafts - Drafts
- Repositories / issues / org list
- [MANY MORE](https://codeberg.org/gitnex/GitNex/wiki/Features) - [MANY MORE](https://codeberg.org/gitnex/GitNex/wiki/Features)
## Contributing ## Contributing
@ -72,21 +71,24 @@ Thanks to all the open source libraries, contributors and donators.
- Retrofit - Retrofit
- Gson - Gson
- Okhttp - Okhttp
- ViHtarb/tooltip
- Picasso - Picasso
- Markwon - Markwon
- Prettytime - Prettytime
- Amulyakhare/textdrawable - Amulyakhare/textdrawable
- Vdurmont/emoji-java - Vdurmont/emoji-java
- Abumoallim/android-multi-select-dialog
- Pes/materialcolorpicker - Pes/materialcolorpicker
- Hendraanggrian/socialview
- HamidrezaAmz/BreadcrumbsView - HamidrezaAmz/BreadcrumbsView
- Chrisbanes/PhotoView - Chrisbanes/PhotoView
- Pddstudio/highlightjs-android - Pddstudio/highlightjs-android
- Apache/commons-io - Apache/commons-io
- Caverock/androidsvg - Caverock/androidsvg
- Droidsonroids.gif/android-gif-drawable - Droidsonroids.gif/android-gif-drawable
- Barteksc/androidPdfViewer - Barteksc/AndroidPdfViewer
- Ge0rg/memorizingTrustManager - Ge0rg/MemorizingTrustManager
- Dimezis/blurView - Dimezis/BlurView
- Mikaelhg/urlbuilder - mikaelhg/urlbuilder
[Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif) [Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif)

View File

@ -1,28 +1,15 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 30 compileSdkVersion 29
defaultConfig { defaultConfig {
applicationId "org.mian.gitnex" applicationId "org.mian.gitnex"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 29
versionCode 327 versionCode 301
versionName "3.3.0-rc1" versionName "3.0.1"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
dexOptions {
javaMaxHeapSize "4g"
}
flavorDimensions "default"
productFlavors {
free {
applicationId "org.mian.gitnex"
}
pro {
applicationId "org.mian.gitnex.pro"
}
}
buildFeatures { buildFeatures {
viewBinding = true viewBinding = true
} }
@ -41,9 +28,6 @@ android {
targetCompatibility = "8" targetCompatibility = "8"
sourceCompatibility = "8" sourceCompatibility = "8"
} }
defaultConfig{
vectorDrawables.useSupportLibrary = true
}
} }
configurations { configurations {
@ -52,29 +36,30 @@ configurations {
} }
dependencies { dependencies {
def lifecycle_version = '2.3.0-beta01' def lifecycle_version = "2.3.0-alpha05"
def markwon_version = '4.6.0' def markwon_version = "4.4.0"
def work_version = "2.4.0" def work_version = "2.4.0"
def acra = "5.5.0" def acra = "5.5.0"
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.3.0-alpha02' implementation "androidx.appcompat:appcompat:1.3.0-alpha01"
implementation 'com.google.android.material:material:1.3.0-alpha03' implementation "com.google.android.material:material:1.3.0-alpha01"
implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
testImplementation 'junit:junit:4.13.1' testImplementation "junit:junit:4.13"
androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation "com.github.vihtarb:tooltip:0.2.0"
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
implementation "com.google.code.gson:gson:2.8.6" implementation "com.google.code.gson:gson:2.8.6"
implementation "com.squareup.picasso:picasso:2.71828" implementation "com.squareup.picasso:picasso:2.71828"
implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1" implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1"
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.8.0'
implementation 'org.ocpsoft.prettytime:prettytime:4.0.6.Final' implementation 'org.ocpsoft.prettytime:prettytime:4.0.5.Final'
implementation "com.vdurmont:emoji-java:5.1.1" implementation "com.vdurmont:emoji-java:5.1.1"
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"
@ -92,9 +77,11 @@ dependencies {
implementation "io.noties.markwon:syntax-highlight:$markwon_version" implementation "io.noties.markwon:syntax-highlight:$markwon_version"
implementation "com.caverock:androidsvg:1.4" implementation "com.caverock:androidsvg:1.4"
implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.19" implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.19"
implementation "com.hendraanggrian.appcompat:socialview:0.2"
implementation "com.hendraanggrian.appcompat:socialview-commons:0.2"
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:20030203.000550"
implementation 'org.apache.commons:commons-lang3:3.11' implementation "org.apache.commons:commons-lang3:3.10"
implementation "com.github.chrisbanes:PhotoView:2.3.0" implementation "com.github.chrisbanes:PhotoView:2.3.0"
implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1" implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
implementation "ch.acra:acra-mail:$acra" implementation "ch.acra:acra-mail:$acra"

View File

@ -17,79 +17,51 @@
android:supportsRtl="true" android:supportsRtl="true"
tools:targetApi="n"> tools:targetApi="n">
<activity <activity android:name=".activities.MergePullRequestActivity" />
android:name=".activities.MergePullRequestActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity <activity
android:name=".activities.FileViewActivity" android:name=".activities.FileViewActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.CreateFileActivity" android:name=".activities.CreateFileActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.RepoWatchersActivity" android:name=".activities.RepoWatchersActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".activities.RepoStargazersActivity" android:name=".activities.RepoStargazersActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".activities.AdminGetUsersActivity" />
<activity <activity
android:name=".activities.AdminGetUsersActivity" android:name=".activities.AddRemoveAssigneesActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> android:theme="@style/Theme.AppCompat.Light.Dialog" />
<activity android:name=".activities.CreateReleaseActivity" />
<activity android:name=".activities.EditIssueActivity" />
<activity android:name=".activities.CreateNewUserActivity" />
<activity <activity
android:name=".activities.CreateReleaseActivity" android:name=".activities.AddRemoveLabelsActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> android:theme="@style/Theme.AppCompat.Light.Dialog" />
<activity <activity android:name=".activities.ProfileEmailActivity" />
android:name=".activities.EditIssueActivity" <activity android:name=".activities.AddCollaboratorToRepositoryActivity" />
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> <activity android:name=".activities.CreateTeamByOrgActivity" />
<activity <activity android:name=".activities.OrganizationTeamMembersActivity" />
android:name=".activities.CreateNewUserActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.ProfileEmailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.AddCollaboratorToRepositoryActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.CreateTeamByOrgActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.OrganizationTeamMembersActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity <activity
android:name=".activities.OrganizationDetailActivity" android:name=".activities.OrganizationDetailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
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 <activity android:name=".activities.SponsorsActivity" />
android:name=".activities.CreateLabelActivity" <activity android:name=".activities.CreditsActivity" />
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> <activity android:name=".activities.CreateLabelActivity" />
<activity <activity android:name=".activities.CreateIssueActivity" />
android:name=".activities.CreateIssueActivity" <activity android:name=".activities.CreateMilestoneActivity" />
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> <activity android:name=".activities.ReplyToIssueActivity" />
<activity
android:name=".activities.CreateMilestoneActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.ReplyToIssueActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity <activity
android:name=".activities.IssueDetailActivity" android:name=".activities.IssueDetailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustNothing" /> android:windowSoftInputMode="adjustNothing" />
<activity <activity
android:name=".activities.RepoDetailActivity" android:name=".activities.RepoDetailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
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 <activity android:name=".activities.MainActivity" android:theme="@android:style/Theme.NoTitleBar" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation">
android:name=".activities.MainActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -98,86 +70,26 @@
</activity> </activity>
<activity <activity
android:name=".activities.LoginActivity" android:name=".activities.LoginActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" android:launchMode="singleTask" android:theme="@android:style/Theme.NoTitleBar"/>
android:launchMode="singleTask" <activity android:name=".activities.CreateRepoActivity" />
android:theme="@android:style/Theme.NoTitleBar"/> <activity android:name=".activities.CreateOrganizationActivity" />
<activity <activity android:name=".activities.OpenRepoInBrowserActivity" />
android:name=".activities.CreateRepoActivity" <activity android:name=".activities.FileDiffActivity" />
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> <activity android:name=".activities.CommitsActivity" />
<activity <activity android:name=".helpers.ssl.MemorizingActivity" android:theme="@android:style/Theme.Material.Dialog" />
android:name=".activities.CreateOrganizationActivity" <activity android:name=".activities.SettingsAppearanceActivity" />
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> <activity android:name=".activities.SettingsFileViewerActivity" />
<activity <activity android:name=".activities.SettingsSecurityActivity" />
android:name=".activities.OpenRepoInBrowserActivity" <activity android:name=".activities.SettingsTranslationActivity" />
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> <activity android:name=".activities.SettingsReportsActivity" />
<activity <activity android:name=".activities.AddNewTeamMemberActivity" />
android:name=".activities.FileDiffActivity" <activity android:name=".activities.SettingsDraftsActivity" />
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.CommitsActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".helpers.ssl.MemorizingActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
android:theme="@android:style/Theme.Material.Dialog" />
<activity
android:name=".activities.SettingsAppearanceActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.SettingsFileViewerActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.SettingsSecurityActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.SettingsTranslationActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.SettingsReportsActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.AddNewTeamMemberActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.SettingsDraftsActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.RepoForksActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.AddNewAccountActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.RepositorySettingsActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.CreatePullRequestActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<activity
android:name=".activities.SettingsGeneralActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
<!-- Version < 3.0. DeX Mode and Screen Mirroring support --> <!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
<meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/> <meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>
<!-- Version >= 3.0. DeX Dual Mode support --> <!-- Version >= 3.0. DeX Dual Mode support -->
<meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="true"/> <meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="true"/>
<!-- deep links -->
<activity
android:name=".activities.DeepLinksActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="*" />
</intent-filter>
</activity>
<!-- deep links -->
</application> </application>
</manifest> </manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,80 +0,0 @@
package org.mian.gitnex.actions;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* @author opyale
*/
public class ActionResult<R> {
public enum Status { SUCCESS, FAILED }
private final BlockingQueue<Boolean> blockingQueue;
private final List<OnFinishedListener<R>> onFinishedListeners;
private boolean invalidated = false;
public ActionResult() {
blockingQueue = new ArrayBlockingQueue<>(1);
onFinishedListeners = new ArrayList<>();
}
public void finish(@NonNull Status status) {
finish(status, null);
}
public void finish(@NonNull Status status, R result) {
try {
if(blockingQueue.poll(5, TimeUnit.SECONDS)) {
for(OnFinishedListener<R> onFinishedListener : onFinishedListeners)
onFinishedListener.onFinished(status, result);
}
} catch (InterruptedException ignored) {}
}
public void invalidate() {
if(invalidated) throw new IllegalStateException("Already invalidated");
this.invalidated = true;
}
@SafeVarargs
public synchronized final void accept(@NonNull OnFinishedListener<R>... onFinishedListeners) {
invalidate();
this.blockingQueue.add(true);
this.onFinishedListeners.addAll(Arrays.asList(onFinishedListeners));
}
public synchronized final void discard() {
invalidate();
this.blockingQueue.add(false);
}
public static class None {}
public interface OnFinishedListener<R> {
void onFinished(Status status, R result);
}
}

View File

@ -1,122 +0,0 @@
package org.mian.gitnex.actions;
import android.app.Dialog;
import android.content.Context;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.AssigneesListAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Issues;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class AssigneesActions {
public static void getCurrentIssueAssignees(Context ctx, String instanceUrl, String loginUid, String instanceToken, String repoOwner, String repoName, int issueIndex, List<String> currentAssignees) {
Call<Issues> callSingleIssueLabels = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueLabels.enqueue(new Callback<Issues>() {
@Override
public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
if(response.code() == 200) {
Issues issueAssigneesList = response.body();
assert issueAssigneesList != null;
if (issueAssigneesList.getAssignees() != null) {
if(issueAssigneesList.getAssignees().size() > 0) {
for(int i = 0; i < issueAssigneesList.getAssignees().size(); i++) {
currentAssignees.add(issueAssigneesList.getAssignees().get(i).getLogin());
}
}
}
}
}
@Override
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
public static void getRepositoryAssignees(Context ctx, String instanceUrl, String instanceToken, String repoOwner, String repoName, List<Collaborators> assigneesList, Dialog dialogAssignees, AssigneesListAdapter assigneesAdapter, CustomAssigneesSelectionDialogBinding assigneesBinding) {
TinyDB tinyDB = new TinyDB(ctx);
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(instanceToken, repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull retrofit2.Response<List<Collaborators>> response) {
assigneesList.clear();
List<Collaborators> assigneesList_ = response.body();
assigneesBinding.progressBar.setVisibility(View.GONE);
assigneesBinding.dialogFrame.setVisibility(View.VISIBLE);
if (response.code() == 200) {
assert assigneesList_ != null;
if(assigneesList_.size() > 0) {
dialogAssignees.show();
assigneesList.add(new Collaborators(tinyDB.getString("userFullname"), tinyDB.getString("loginUid"), tinyDB.getString("userAvatar")));
assigneesList.addAll(assigneesList_);
}
else {
dialogAssignees.dismiss();
Toasty.warning(ctx, ctx.getResources().getString(R.string.noAssigneesFound));
}
assigneesBinding.assigneesRecyclerView.setAdapter(assigneesAdapter);
}
else {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
}
});
}
}

View File

@ -12,10 +12,8 @@ import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Permission; import org.mian.gitnex.models.Permission;
import java.util.List;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -49,7 +47,7 @@ public class CollaboratorActions {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 204) { if(response.code() == 204) {
Toasty.success(context, context.getString(R.string.removeCollaboratorToastText)); Toasty.info(context, context.getString(R.string.removeCollaboratorToastText));
((AddCollaboratorToRepositoryActivity)context).finish(); ((AddCollaboratorToRepositoryActivity)context).finish();
//Log.i("addCollaboratorSearch", addCollaboratorSearch.getText().toString()); //Log.i("addCollaboratorSearch", addCollaboratorSearch.getText().toString());
//tinyDb.putBoolean("updateDataSet", true); //tinyDb.putBoolean("updateDataSet", true);
@ -68,17 +66,17 @@ public class CollaboratorActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(context, context.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(context, context.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(context, context.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }
@ -119,7 +117,7 @@ public class CollaboratorActions {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 204) { if(response.code() == 204) {
Toasty.success(context, context.getString(R.string.addCollaboratorToastText)); Toasty.info(context, context.getString(R.string.addCollaboratorToastText));
((AddCollaboratorToRepositoryActivity)context).finish(); ((AddCollaboratorToRepositoryActivity)context).finish();
//AddCollaboratorToRepositoryActivity usersSearchData = new AddCollaboratorToRepositoryActivity(); //AddCollaboratorToRepositoryActivity usersSearchData = new AddCollaboratorToRepositoryActivity();
//usersSearchData.loadUserSearchList(instanceUrl, instanceToken, searchKeyword, context); //usersSearchData.loadUserSearchList(instanceUrl, instanceToken, searchKeyword, context);
@ -136,17 +134,17 @@ public class CollaboratorActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(context, context.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(context, context.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(context, context.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }
@ -156,55 +154,8 @@ public class CollaboratorActions {
public void onFailure(@NonNull Call<Permission> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Permission> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
} }
public static ActionResult<List<Collaborators>> getCollaborators(Context context) {
ActionResult<List<Collaborators>> actionResult = new ActionResult<>();
TinyDB tinyDb = new TinyDB(context);
String instanceUrl = tinyDb.getString("instanceUrl");
String loginUid = tinyDb.getString("loginUid");
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, context)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
if (response.isSuccessful()) {
assert response.body() != null;
actionResult.finish(ActionResult.Status.SUCCESS, response.body());
}
else {
actionResult.finish(ActionResult.Status.FAILED);
}
}
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
actionResult.finish(ActionResult.Status.FAILED);
}
});
return actionResult;
}
} }

View File

@ -1,17 +1,17 @@
package org.mian.gitnex.actions; package org.mian.gitnex.actions;
import android.content.Context; import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.IssueComments; import org.mian.gitnex.models.IssueComments;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.UpdateIssueState; import org.mian.gitnex.models.UpdateIssueState;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -22,7 +22,7 @@ import retrofit2.Callback;
public class IssueActions { public class IssueActions {
public static void editIssueComment(final Context ctx, final int commentId, final String commentBody, long draftIdOnCreate) { public static void editIssueComment(final Context ctx, final int commentId, final String commentBody) {
final TinyDB tinyDb = new TinyDB(ctx); final TinyDB tinyDb = new TinyDB(ctx);
final String instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
@ -48,9 +48,7 @@ public class IssueActions {
tinyDb.putBoolean("commentEdited", true); tinyDb.putBoolean("commentEdited", true);
Toasty.info(ctx, ctx.getString(R.string.editCommentUpdatedText)); Toasty.info(ctx, ctx.getString(R.string.editCommentUpdatedText));
((ReplyToIssueActivity) ctx).finish();
DraftsApi draftsApi = new DraftsApi(ctx);
draftsApi.deleteSingleDraft((int) draftIdOnCreate);
} }
} }
@ -61,17 +59,17 @@ public class IssueActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(ctx, ctx.getString(R.string.genericError)); Toasty.info(ctx, ctx.getString(R.string.genericError));
} }
@ -80,7 +78,7 @@ public class IssueActions {
@Override @Override
public void onFailure(@NonNull Call<IssueComments> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<IssueComments> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); Log.e("onFailure", t.toString());
} }
}); });
@ -115,13 +113,13 @@ public class IssueActions {
if(issueState.equals("closed")) { if(issueState.equals("closed")) {
Toasty.success(ctx, ctx.getString(R.string.issueStateClosed)); Toasty.info(ctx, ctx.getString(R.string.issueStateClosed));
tinyDb.putString("issueState", "closed"); tinyDb.putString("issueState", "closed");
} }
else if(issueState.equals("open")) { else if(issueState.equals("open")) {
Toasty.success(ctx, ctx.getString(R.string.issueStateReopened)); Toasty.info(ctx, ctx.getString(R.string.issueStateReopened));
tinyDb.putString("issueState", "open"); tinyDb.putString("issueState", "open");
} }
@ -135,17 +133,17 @@ public class IssueActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(ctx, ctx.getString(R.string.genericError)); Toasty.info(ctx, ctx.getString(R.string.genericError));
} }
@ -154,7 +152,7 @@ public class IssueActions {
@Override @Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); Log.e("onFailure", t.toString());
} }
}); });
@ -186,14 +184,14 @@ public class IssueActions {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.success(ctx, ctx.getString(R.string.subscribedSuccessfully)); Toasty.info(ctx, ctx.getString(R.string.subscribedSuccessfully));
tinyDB.putBoolean("issueSubscribed", true); tinyDB.putBoolean("issueSubscribed", true);
} }
else if(response.code() == 200) { else if(response.code() == 200) {
tinyDB.putBoolean("issueSubscribed", true); tinyDB.putBoolean("issueSubscribed", true);
Toasty.success(ctx, ctx.getString(R.string.alreadySubscribed)); Toasty.info(ctx, ctx.getString(R.string.alreadySubscribed));
} }
@ -205,7 +203,7 @@ public class IssueActions {
} }
else { else {
Toasty.error(ctx, ctx.getString(R.string.subscriptionError)); Toasty.info(ctx, ctx.getString(R.string.subscriptionError));
} }
@ -214,7 +212,7 @@ public class IssueActions {
@Override @Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); Toasty.info(ctx, ctx.getString(R.string.unsubscribedSuccessfully));
} }
}); });
@ -246,14 +244,14 @@ public class IssueActions {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.success(ctx, ctx.getString(R.string.unsubscribedSuccessfully)); Toasty.info(ctx, ctx.getString(R.string.unsubscribedSuccessfully));
tinyDB.putBoolean("issueSubscribed", false); tinyDB.putBoolean("issueSubscribed", false);
} }
else if(response.code() == 200) { else if(response.code() == 200) {
tinyDB.putBoolean("issueSubscribed", false); tinyDB.putBoolean("issueSubscribed", false);
Toasty.success(ctx, ctx.getString(R.string.alreadyUnsubscribed)); Toasty.info(ctx, ctx.getString(R.string.alreadyUnsubscribed));
} }
@ -265,7 +263,7 @@ public class IssueActions {
} }
else { else {
Toasty.error(ctx, ctx.getString(R.string.unsubscriptionError)); Toasty.info(ctx, ctx.getString(R.string.unsubscriptionError));
} }
@ -274,69 +272,9 @@ public class IssueActions {
@Override @Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); Toasty.info(ctx, ctx.getString(R.string.unsubscriptionError));
} }
}); });
} }
public static ActionResult<ActionResult.None> reply(Context context, String comment, int issueIndex) {
ActionResult<ActionResult.None> actionResult = new ActionResult<>();
TinyDB tinyDb = new TinyDB(context);
String instanceUrl = tinyDb.getString("instanceUrl");
String loginUid = tinyDb.getString("loginUid");
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
Issues issueComment = new Issues(comment);
Call<Issues> call = RetrofitClient
.getInstance(instanceUrl, context)
.getApiInterface()
.replyCommentToIssue(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment);
call.enqueue(new Callback<Issues>() {
@Override
public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
if(response.code() == 201) {
actionResult.finish(ActionResult.Status.SUCCESS);
tinyDb.putBoolean("commentPosted", true);
tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("resumePullRequests", true);
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(context, context.getString(R.string.alertDialogTokenRevokedTitle),
context.getString(R.string.alertDialogTokenRevokedMessage),
context.getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
context.getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
actionResult.finish(ActionResult.Status.FAILED);
}
}
@Override
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
Toasty.error(context, context.getResources().getString(R.string.genericServerResponseError));
}
});
return actionResult;
}
} }

View File

@ -1,116 +0,0 @@
package org.mian.gitnex.actions;
import android.app.Dialog;
import android.content.Context;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import org.mian.gitnex.R;
import org.mian.gitnex.adapters.LabelsListAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Labels;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class LabelsActions {
public static void getCurrentIssueLabels(Context ctx, String instanceUrl, String loginUid, String instanceToken, String repoOwner, String repoName, int issueIndex, List<Integer> currentLabelsIds) {
Call<List<Labels>> callSingleIssueLabels = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueLabels.enqueue(new Callback<List<Labels>>() {
@Override
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
if(response.code() == 200) {
List<Labels> issueLabelsList = response.body();
assert issueLabelsList != null;
if(issueLabelsList.size() > 0) {
for (int i = 0; i < issueLabelsList.size(); i++) {
currentLabelsIds.add(issueLabelsList.get(i).getId());
}
}
}
}
@Override
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
public static void getRepositoryLabels(Context ctx, String instanceUrl, String instanceToken, String repoOwner, String repoName, List<Labels> labelsList, Dialog dialogLabels, LabelsListAdapter labelsAdapter, CustomLabelsSelectionDialogBinding labelsBinding) {
Call<List<Labels>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getlabels(instanceToken, repoOwner, repoName);
call.enqueue(new Callback<List<Labels>>() {
@Override
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
labelsList.clear();
List<Labels> labelsList_ = response.body();
labelsBinding.progressBar.setVisibility(View.GONE);
labelsBinding.dialogFrame.setVisibility(View.VISIBLE);
if (response.code() == 200) {
assert labelsList_ != null;
if(labelsList_.size() > 0) {
dialogLabels.show();
labelsList.addAll(labelsList_);
}
else {
dialogLabels.dismiss();
Toasty.warning(ctx, ctx.getResources().getString(R.string.noLabelsFound));
}
labelsBinding.labelsRecyclerView.setAdapter(labelsAdapter);
}
else {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError));
}
});
}
}

View File

@ -48,7 +48,7 @@ public class MilestoneActions {
if(response.isSuccessful()) { if(response.isSuccessful()) {
Toasty.success(ctx, ctx.getString(R.string.milestoneStatusUpdate)); Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate));
} }
else if(response.code() == 401) { else if(response.code() == 401) {
@ -61,7 +61,7 @@ public class MilestoneActions {
} }
else { else {
Toasty.error(ctx, ctx.getString(R.string.genericError)); Toasty.info(ctx, ctx.getString(R.string.genericError));
} }
@ -106,7 +106,7 @@ public class MilestoneActions {
if(response.isSuccessful()) { if(response.isSuccessful()) {
Toasty.success(ctx, ctx.getString(R.string.milestoneStatusUpdate)); Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate));
} }
else if(response.code() == 401) { else if(response.code() == 401) {
@ -119,7 +119,7 @@ public class MilestoneActions {
} }
else { else {
Toasty.error(ctx, ctx.getString(R.string.genericError)); Toasty.info(ctx, ctx.getString(R.string.genericError));
} }

View File

@ -46,7 +46,7 @@ public class RepositoryActions {
if(response.code() == 204) { if(response.code() == 204) {
tinyDb.putBoolean("repoCreated", true); tinyDb.putBoolean("repoCreated", true);
Toasty.success(context, context.getString(R.string.starRepositorySuccess)); Toasty.info(context, context.getString(R.string.starRepositorySuccess));
} }
} }
@ -60,17 +60,17 @@ public class RepositoryActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(context, context.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(context, context.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(context, context.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }
@ -111,7 +111,7 @@ public class RepositoryActions {
if(response.code() == 204) { if(response.code() == 204) {
tinyDb.putBoolean("repoCreated", true); tinyDb.putBoolean("repoCreated", true);
Toasty.success(context, context.getString(R.string.unStarRepositorySuccess)); Toasty.info(context, context.getString(R.string.unStarRepositorySuccess));
} }
} }
@ -125,17 +125,17 @@ public class RepositoryActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(context, context.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(context, context.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(context, context.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }
@ -176,7 +176,7 @@ public class RepositoryActions {
if(response.code() == 200) { if(response.code() == 200) {
tinyDb.putBoolean("repoCreated", true); tinyDb.putBoolean("repoCreated", true);
Toasty.success(context, context.getString(R.string.watchRepositorySuccess)); Toasty.info(context, context.getString(R.string.watchRepositorySuccess));
} }
} }
@ -190,17 +190,17 @@ public class RepositoryActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(context, context.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(context, context.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(context, context.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }
@ -240,7 +240,7 @@ public class RepositoryActions {
if(response.code() == 204) { if(response.code() == 204) {
tinyDb.putBoolean("repoCreated", true); tinyDb.putBoolean("repoCreated", true);
Toasty.success(context, context.getString(R.string.unWatchRepositorySuccess)); Toasty.info(context, context.getString(R.string.unWatchRepositorySuccess));
} }
else if(response.code() == 401) { else if(response.code() == 401) {
@ -253,17 +253,17 @@ public class RepositoryActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(context, context.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(context, context.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(context, context.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }

View File

@ -43,7 +43,7 @@ public class TeamActions {
if(response.code() == 204) { if(response.code() == 204) {
tinyDb.putBoolean("teamActionFlag", true); tinyDb.putBoolean("teamActionFlag", true);
Toasty.success(context, context.getString(R.string.memberRemovedMessage)); Toasty.info(context, context.getString(R.string.memberRemovedMessage));
((AddNewTeamMemberActivity)context).finish(); ((AddNewTeamMemberActivity)context).finish();
} }
@ -59,17 +59,17 @@ public class TeamActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(context, context.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(context, context.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(context, context.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }
@ -109,7 +109,7 @@ public class TeamActions {
if(response.code() == 204) { if(response.code() == 204) {
tinyDb.putBoolean("teamActionFlag", true); tinyDb.putBoolean("teamActionFlag", true);
Toasty.success(context, context.getString(R.string.memberAddedMessage)); Toasty.info(context, context.getString(R.string.memberAddedMessage));
((AddNewTeamMemberActivity)context).finish(); ((AddNewTeamMemberActivity)context).finish();
} }
@ -125,17 +125,17 @@ public class TeamActions {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(context, context.getString(R.string.authorizeError)); Toasty.info(context, context.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(context, context.getString(R.string.apiNotFound)); Toasty.info(context, context.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(context, context.getString(R.string.genericError)); Toasty.info(context, context.getString(R.string.genericError));
} }

View File

@ -63,7 +63,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
addCollaboratorSearch = findViewById(R.id.addCollaboratorSearch); addCollaboratorSearch = findViewById(R.id.addCollaboratorSearch);
mRecyclerView = findViewById(R.id.recyclerViewUserSearch); mRecyclerView = findViewById(R.id.recyclerViewUserSearch);
mProgressBar = findViewById(R.id.progressBar); mProgressBar = findViewById(R.id.progress_bar);
noData = findViewById(R.id.noData); noData = findViewById(R.id.noData);
addCollaboratorSearch.requestFocus(); addCollaboratorSearch.requestFocus();
@ -76,10 +76,7 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
addCollaboratorSearch.setOnEditorActionListener((v, actionId, event) -> { addCollaboratorSearch.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_SEND) { if (actionId == EditorInfo.IME_ACTION_SEND) {
if(!addCollaboratorSearch.getText().toString().equals("")) { if(!addCollaboratorSearch.getText().toString().equals("")) {
mProgressBar.setVisibility(View.VISIBLE);
loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), loginUid); loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), loginUid);
} }
} }
@ -102,15 +99,10 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
@Override @Override
public void onResponse(@NonNull Call<UserSearch> call, @NonNull Response<UserSearch> response) { public void onResponse(@NonNull Call<UserSearch> call, @NonNull Response<UserSearch> response) {
mProgressBar.setVisibility(View.GONE); if (response.isSuccessful()) {
if (response.code() == 200) {
assert response.body() != null; assert response.body() != null;
getUsersList(response.body().getData(), ctx); getUsersList(response.body().getData(), ctx);
} } else {
else {
Log.i("onResponse", String.valueOf(response.code())); Log.i("onResponse", String.valueOf(response.code()));
} }
@ -137,13 +129,11 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.VISIBLE);
if(adapter.getItemCount() > 0) { if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter); mRecyclerView.setAdapter(adapter);
noData.setVisibility(View.GONE); noData.setVisibility(View.GONE);
mProgressBar.setVisibility(View.GONE); mProgressBar.setVisibility(View.GONE);
} }
else { else {
noData.setVisibility(View.VISIBLE); noData.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE); mProgressBar.setVisibility(View.GONE);
} }
@ -154,4 +144,5 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity {
onClickListener = view -> finish(); onClickListener = view -> finish();
} }
} }

View File

@ -1,268 +0,0 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.databinding.ActivityAddNewAccountBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.PathsHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.UrlHelper;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.UserInfo;
import java.net.URI;
import io.mikael.urlbuilder.UrlBuilder;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class AddNewAccountActivity extends BaseActivity {
final Context ctx = this;
private Context appCtx;
private TinyDB tinyDB;
private View.OnClickListener onClickListener;
private ActivityAddNewAccountBinding viewBinding;
private enum Protocol {HTTPS, HTTP}
private String spinnerSelectedValue;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_add_new_account;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
tinyDB = new TinyDB(appCtx);
viewBinding = ActivityAddNewAccountBinding.inflate(getLayoutInflater());
View view = viewBinding.getRoot();
setContentView(view);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
initCloseListener();
viewBinding.close.setOnClickListener(onClickListener);
ArrayAdapter<Protocol> adapterProtocols = new ArrayAdapter<>(ctx, R.layout.list_spinner_items, Protocol.values());
viewBinding.protocolSpinner.setAdapter(adapterProtocols);
viewBinding.protocolSpinner.setOnItemClickListener((parent, view1, position, id) -> spinnerSelectedValue = String.valueOf(parent.getItemAtPosition(position)));
viewBinding.addNewAccount.setOnClickListener(login -> {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
}
else {
processLogin();
}
});
}
private void processLogin() {
try {
String instanceUrlET = String.valueOf(viewBinding.instanceUrl.getText());
String loginToken = String.valueOf(viewBinding.loginToken.getText());
String protocol = spinnerSelectedValue;
if(protocol == null) {
Toasty.error(ctx, getResources().getString(R.string.protocolEmptyError));
return;
}
if(instanceUrlET.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldURL));
return;
}
if(loginToken.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.loginTokenError));
return;
}
URI rawInstanceUrl = UrlBuilder.fromString(UrlHelper.fixScheme(instanceUrlET, "http")).toUri();
URI instanceUrl = UrlBuilder.fromUri(rawInstanceUrl).withScheme(protocol.toLowerCase()).withPath(PathsHelper.join(rawInstanceUrl.getPath(), "/api/v1/"))
.toUri();
versionCheck(instanceUrl.toString(), loginToken);
}
catch(Exception e) {
Log.e("onFailure-login", e.toString());
Toasty.error(ctx, getResources().getString(R.string.malformedUrl));
}
}
private void versionCheck(final String instanceUrl, final String loginToken) {
Call<GiteaVersion> callVersion;
callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken("token " + loginToken);
callVersion.enqueue(new Callback<GiteaVersion>() {
@Override
public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) {
if(responseVersion.code() == 200) {
GiteaVersion version = responseVersion.body();
assert version != null;
if(!Version.valid(version.getVersion())) {
Toasty.error(ctx, getResources().getString(R.string.versionUnknown));
return;
}
tinyDB.putString("giteaVersion", version.getVersion());
Version giteaVersion = new Version(version.getVersion());
if(giteaVersion.less(getString(R.string.versionLow))) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader))
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setIcon(R.drawable.ic_warning)
.setCancelable(true);
alertDialogBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
dialog.dismiss();
});
alertDialogBuilder.setPositiveButton(getString(R.string.textContinue), (dialog, which) -> {
dialog.dismiss();
login(instanceUrl, loginToken);
});
alertDialogBuilder.create().show();
}
else if(giteaVersion.lessOrEqual(getString(R.string.versionHigh))) {
login(instanceUrl, loginToken);
}
else {
Toasty.warning(ctx, getResources().getString(R.string.versionUnsupportedNew));
login(instanceUrl, loginToken);
}
}
else if(responseVersion.code() == 403) {
login(instanceUrl, loginToken);
}
}
private void login(String instanceUrl, String loginToken) {
setupNewAccountWithToken(instanceUrl, loginToken);
}
@Override
public void onFailure(@NonNull Call<GiteaVersion> callVersion, @NonNull Throwable t) {
Log.e("onFailure-versionCheck", t.toString());
Toasty.error(ctx, getResources().getString(R.string.errorOnLogin));
}
});
}
private void setupNewAccountWithToken(String instanceUrl, final String loginToken) {
Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo("token " + loginToken);
call.enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(@NonNull Call<UserInfo> call, @NonNull retrofit2.Response<UserInfo> response) {
UserInfo userDetails = response.body();
switch(response.code()) {
case 200:
assert userDetails != null;
// insert new account to db if does not exist
String accountName = userDetails.getUsername() + "@" + instanceUrl;
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
int checkAccount = userAccountsApi.getCount(accountName);
if(checkAccount == 0) {
userAccountsApi.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, "");
Toasty.success(ctx, getResources().getString(R.string.accountAddedMessage));
finish();
}
else {
Toasty.warning(ctx, getResources().getString(R.string.accountAlreadyExistsError));
}
break;
case 401:
Toasty.error(ctx, getResources().getString(R.string.unauthorizedApiError));
break;
default:
Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code());
}
}
@Override
public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
Toasty.error(ctx, getResources().getString(R.string.genericError));
}
});
}
private void initCloseListener() {
onClickListener = view -> finish();
}
}

View File

@ -28,10 +28,6 @@ import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
/**
* Author M M Arif
*/
public class AddNewTeamMemberActivity extends BaseActivity { public class AddNewTeamMemberActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
@ -68,7 +64,7 @@ public class AddNewTeamMemberActivity extends BaseActivity {
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
addNewTeamMember = findViewById(R.id.addNewTeamMember); addNewTeamMember = findViewById(R.id.addNewTeamMeber);
mRecyclerView = findViewById(R.id.recyclerViewUserSearch); mRecyclerView = findViewById(R.id.recyclerViewUserSearch);
mProgressBar = findViewById(R.id.progress_bar); mProgressBar = findViewById(R.id.progress_bar);
noData = findViewById(R.id.noData); noData = findViewById(R.id.noData);
@ -125,8 +121,6 @@ public class AddNewTeamMemberActivity extends BaseActivity {
Call<UserSearch> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserBySearch(Authorization.returnAuthentication(ctx, loginUid, token), searchKeyword, 10); Call<UserSearch> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserBySearch(Authorization.returnAuthentication(ctx, loginUid, token), searchKeyword, 10);
mProgressBar.setVisibility(View.VISIBLE);
call.enqueue(new Callback<UserSearch>() { call.enqueue(new Callback<UserSearch>() {
@Override @Override

View File

@ -0,0 +1,294 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
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.MultiSelectDialog;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.MultiSelectModel;
import org.mian.gitnex.models.UpdateIssueAssignees;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class AddRemoveAssigneesActivity extends BaseActivity {
private ArrayList<MultiSelectModel> listOfCollaborators = new ArrayList<>();
private ArrayList<Integer> issueAssigneesIds = new ArrayList<>();
private Boolean assigneesFlag = false;
private MultiSelectDialog multiSelectDialogAssignees;
final Context ctx = this;
private Context appCtx;
@Override
protected int getLayoutResourceId(){
return R.layout.activity_add_remove_assignees;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
getAssignees(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
}
private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
final TinyDB tinyDb = new TinyDB(appCtx);
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull final Call<List<Collaborators>> call, @NonNull final retrofit2.Response<List<Collaborators>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
final List<Collaborators> collaboratorsList_ = response.body();
assert collaboratorsList_ != null;
if(collaboratorsList_.size() > 0) {
for (int i = 0; i < collaboratorsList_.size(); i++) {
listOfCollaborators.add(new MultiSelectModel(collaboratorsList_.get(i).getId(), collaboratorsList_.get(i).getUsername().trim()));
}
}
// get current issue assignees
Call<Issues> callSingleIssueAssignees = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueAssignees.enqueue(new Callback<Issues>() {
@Override
public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
if(response.code() == 200) {
Issues issueAssigneesList = response.body();
assert issueAssigneesList != null;
if (issueAssigneesList.getAssignees() != null) {
if (issueAssigneesList.getAssignees().size() > 0) {
for (int i = 0; i < issueAssigneesList.getAssignees().size(); i++) {
issueAssigneesIds.add(issueAssigneesList.getAssignees().get(i).getId());
if(issueAssigneesList.getAssignees().get(i).getUsername().equals(loginUid)) {
listOfCollaborators.add(new MultiSelectModel(issueAssigneesList.getAssignees().get(i).getId(), issueAssigneesList.getAssignees().get(i).getUsername().trim()));
}
}
assigneesFlag = true;
}
}
else {
listOfCollaborators.add(new MultiSelectModel(tinyDb.getInt("userId"), loginUid));
}
if(assigneesFlag) {
multiSelectDialogAssignees = new MultiSelectDialog()
.title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
.titleSize(25)
.positiveText(getResources().getString(R.string.saveButton))
.negativeText(getResources().getString(R.string.cancelButton))
.setMinSelectionLimit(0)
.preSelectIDsList(issueAssigneesIds)
.setMaxSelectionLimit(listOfCollaborators.size())
.multiSelectList(listOfCollaborators)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
Log.i("selectedNames", String.valueOf(selectedNames));
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity();
}
@Override
public void onCancel() {
CloseActivity();
}
});
}
else {
multiSelectDialogAssignees = new MultiSelectDialog()
.title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
.titleSize(25)
.positiveText(getResources().getString(R.string.saveButton))
.negativeText(getResources().getString(R.string.cancelButton))
.setMinSelectionLimit(0)
.setMaxSelectionLimit(listOfCollaborators.size())
.multiSelectList(listOfCollaborators)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity();
}
@Override
public void onCancel() {
CloseActivity();
}
});
}
multiSelectDialogAssignees.show(getSupportFragmentManager(), "issueMultiSelectDialog");
}
}
@Override
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
// get current issue assignees
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.info(ctx, getString(R.string.genericError));
}
}
}
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void CloseActivity() {
this.finish();
}
private void updateIssueAssignees(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, int issueIndex, List<String> issueAssigneesList) {
UpdateIssueAssignees updateAssigneeJson = new UpdateIssueAssignees(issueAssigneesList);
Call<JsonElement> call3;
call3 = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.patchIssueAssignees(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson);
call3.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response2) {
if(response2.code() == 201) {
Toasty.info(ctx, ctx.getString(R.string.assigneesUpdated));
}
else if(response2.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response2.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
}
else if(response2.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.info(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
}

View File

@ -0,0 +1,308 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
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.MultiSelectDialog;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Labels;
import org.mian.gitnex.models.MultiSelectModel;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class AddRemoveLabelsActivity extends BaseActivity {
private ArrayList<MultiSelectModel> listOfLabels = new ArrayList<>();
private ArrayList<Integer> issueLabelIds = new ArrayList<>();
private Boolean labelsFlag = false;
private MultiSelectDialog multiSelectDialogLabels;
final Context ctx = this;
private Context appCtx;
@Override
protected int getLayoutResourceId(){
return R.layout.activity_add_remove_labels;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
//supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
getLabels(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
}
private void getLabels(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
final TinyDB tinyDb = new TinyDB(appCtx);
Call<List<Labels>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getlabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Labels>>() {
@Override
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
List<Labels> labelsList_ = response.body();
assert labelsList_ != null;
if(labelsList_.size() > 0) {
for (int i = 0; i < labelsList_.size(); i++) {
listOfLabels.add(new MultiSelectModel(labelsList_.get(i).getId(), labelsList_.get(i).getName().trim()));
}
}
// get current issue labels
Call<List<Labels>> callSingleIssueLabels = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex);
callSingleIssueLabels.enqueue(new Callback<List<Labels>>() {
@Override
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
if(response.code() == 200) {
List<Labels> issueLabelsList = response.body();
assert issueLabelsList != null;
if(issueLabelsList.size() > 0) {
for (int i = 0; i < issueLabelsList.size(); i++) {
issueLabelIds.add(issueLabelsList.get(i).getId());
}
labelsFlag = true;
}
if(labelsFlag) {
multiSelectDialogLabels = new MultiSelectDialog()
.title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
.titleSize(25)
.positiveText(getResources().getString(R.string.saveButton))
.negativeText(getResources().getString(R.string.cancelButton))
.setMinSelectionLimit(0)
.preSelectIDsList(issueLabelIds)
.setMaxSelectionLimit(listOfLabels.size())
.multiSelectList(listOfLabels)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
String labelIds = selectedIds.toString();
int[] integers;
if (selectedIds.size() > 0) {
String[] items = labelIds.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
integers = new int[items.length];
for (int i = 0; i < integers.length; i++) {
integers[i] = Integer.parseInt(items[i]);
}
}
else {
integers = new int[0];
}
updateIssueLabels(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity();
}
@Override
public void onCancel() {
CloseActivity();
}
});
}
else {
multiSelectDialogLabels = new MultiSelectDialog()
.title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
.titleSize(25)
.positiveText(getResources().getString(R.string.saveButton))
.negativeText(getResources().getString(R.string.cancelButton))
.setMinSelectionLimit(0)
.setMaxSelectionLimit(listOfLabels.size())
.multiSelectList(listOfLabels)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
String labelIds = selectedIds.toString();
int[] integers;
if (selectedIds.size() > 0) {
String[] items = labelIds.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
integers = new int[items.length];
for (int i = 0; i < integers.length; i++) {
integers[i] = Integer.parseInt(items[i]);
}
}
else {
integers = new int[0];
}
updateIssueLabels(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
tinyDb.putBoolean("singleIssueUpdate", true);
CloseActivity();
}
@Override
public void onCancel() {
CloseActivity();
}
});
}
multiSelectDialogLabels.show(getSupportFragmentManager(), "issueMultiSelectDialog");
}
}
@Override
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
// get current issue labels
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.info(ctx, getString(R.string.genericError));
}
}
}
@Override
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void updateIssueLabels(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, int issueIndex, int[] issueLabels, String loginUid) {
Labels patchIssueLabels = new Labels(issueLabels);
Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.updateIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 200) {
Toasty.info(ctx, ctx.getString(R.string.labelsUpdated));
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
Toasty.info(ctx, ctx.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.info(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void CloseActivity() {
this.finish();
}
}

View File

@ -4,7 +4,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
@ -76,7 +75,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
DividerItemDecoration.VERTICAL); DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setRefreshing(false); swipeRefresh.setRefreshing(false);
AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken)); AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken));
@ -117,7 +116,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd
final MenuInflater inflater = getMenuInflater(); final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu); inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
new Handler(Looper.getMainLooper()).postDelayed(() -> { new Handler().postDelayed(() -> {
if(searchFilter) { if(searchFilter) {

View File

@ -5,7 +5,6 @@ import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import org.acra.ACRA; import org.acra.ACRA;
import org.acra.BuildConfig; import org.acra.BuildConfig;
import org.acra.annotation.AcraCore;
import org.acra.annotation.AcraNotification; import org.acra.annotation.AcraNotification;
import org.acra.config.CoreConfigurationBuilder; import org.acra.config.CoreConfigurationBuilder;
import org.acra.config.LimiterConfigurationBuilder; import org.acra.config.LimiterConfigurationBuilder;
@ -17,9 +16,6 @@ import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.notifications.NotificationsMaster; import org.mian.gitnex.notifications.NotificationsMaster;
import static org.acra.ReportField.ANDROID_VERSION;
import static org.acra.ReportField.PHONE_MODEL;
import static org.acra.ReportField.STACK_TRACE;
/** /**
* Author M M Arif * Author M M Arif
@ -29,7 +25,6 @@ import static org.acra.ReportField.STACK_TRACE;
resTitle = R.string.crashTitle, resTitle = R.string.crashTitle,
resChannelName = R.string.setCrashReports, resChannelName = R.string.setCrashReports,
resText = R.string.crashMessage) resText = R.string.crashMessage)
@AcraCore(reportContent = { ANDROID_VERSION, PHONE_MODEL, STACK_TRACE })
public abstract class BaseActivity extends AppCompatActivity { public abstract class BaseActivity extends AppCompatActivity {
@ -56,19 +51,6 @@ public abstract class BaseActivity extends AppCompatActivity {
} }
break; break;
case 3:
setTheme(R.style.AppThemeRetro);
break;
case 4:
if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am
setTheme(R.style.AppTheme);
}
else {
setTheme(R.style.AppThemeRetro);
}
break;
default: default:
setTheme(R.style.AppTheme); setTheme(R.style.AppTheme);
break; break;
@ -138,6 +120,11 @@ public abstract class BaseActivity extends AppCompatActivity {
tinyDb.putString("draftsCommentsDeletionEnabledInit", "yes"); tinyDb.putString("draftsCommentsDeletionEnabledInit", "yes");
} }
if(!tinyDb.getString("instanceUrlWithProtocol").endsWith("/")) {
tinyDb.putString("instanceUrlWithProtocol", tinyDb.getString("instanceUrlWithProtocol") + "/");
}
if (tinyDb.getBoolean("crashReportingEnabled")) { if (tinyDb.getBoolean("crashReportingEnabled")) {
CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this); CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this);
@ -147,6 +134,7 @@ public abstract class BaseActivity extends AppCompatActivity {
ACRA.init(getApplication(), ACRABuilder); ACRA.init(getApplication(), ACRABuilder);
} }
} }
protected abstract int getLayoutResourceId(); protected abstract int getLayoutResourceId();

View File

@ -3,7 +3,6 @@ package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
@ -25,7 +24,6 @@ import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Commits; import org.mian.gitnex.models.Commits;
@ -54,7 +52,6 @@ public class CommitsActivity extends BaseActivity {
private List<Commits> commitsList; private List<Commits> commitsList;
private CommitsAdapter adapter; private CommitsAdapter adapter;
private ApiInterface api; private ApiInterface api;
private ProgressBar progressLoadMore;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId() {
@ -87,7 +84,6 @@ public class CommitsActivity extends BaseActivity {
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
noData = findViewById(R.id.noDataCommits); noData = findViewById(R.id.noDataCommits);
progressLoadMore = findViewById(R.id.progressLoadMore);
progressBar = findViewById(R.id.progress_bar); progressBar = findViewById(R.id.progress_bar);
SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh); SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh);
@ -102,7 +98,7 @@ public class CommitsActivity extends BaseActivity {
recyclerView = findViewById(R.id.recyclerView); recyclerView = findViewById(R.id.recyclerView);
commitsList = new ArrayList<>(); commitsList = new ArrayList<>();
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
swipeRefresh.setRefreshing(false); swipeRefresh.setRefreshing(false);
loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit); loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit);
@ -117,6 +113,7 @@ public class CommitsActivity extends BaseActivity {
int page = (commitsList.size() + resultLimit) / resultLimit; int page = (commitsList.size() + resultLimit) / resultLimit;
loadMore(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, branchName, resultLimit); loadMore(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, branchName, resultLimit);
} }
})); }));
@ -139,7 +136,7 @@ public class CommitsActivity extends BaseActivity {
@Override @Override
public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) { public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> response) {
if(response.code() == 200) { if(response.isSuccessful()) {
assert response.body() != null; assert response.body() != null;
if(response.body().size() > 0) { if(response.body().size() > 0) {
@ -151,15 +148,13 @@ public class CommitsActivity extends BaseActivity {
} }
else { else {
commitsList.clear(); commitsList.clear();
adapter.notifyDataChanged(); adapter.notifyDataChanged();
noData.setVisibility(View.VISIBLE); noData.setVisibility(View.VISIBLE);
} }
}
if(response.code() == 409) {
noData.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE);
} }
else { else {
@ -167,13 +162,12 @@ public class CommitsActivity extends BaseActivity {
} }
progressBar.setVisibility(View.GONE);
} }
@Override @Override
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
Toasty.error(ctx, getResources().getString(R.string.errorOnLogin)); Log.e(TAG, t.toString());
} }
}); });
@ -182,7 +176,9 @@ public class CommitsActivity extends BaseActivity {
private void loadMore(String token, String repoOwner, String repoName, final int page, String branchName, int resultLimit) { private void loadMore(String token, String repoOwner, String repoName, final int page, String branchName, int resultLimit) {
progressLoadMore.setVisibility(View.VISIBLE); //add loading progress view
commitsList.add(new Commits("load"));
adapter.notifyItemInserted((commitsList.size() - 1));
Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, page, branchName, resultLimit); Call<List<Commits>> call = api.getRepositoryCommits(token, repoOwner, repoName, page, branchName, resultLimit);
@ -193,20 +189,26 @@ public class CommitsActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
List<Commits> result = response.body(); //remove loading view
assert result != null; commitsList.remove(commitsList.size() - 1);
List<Commits> result = response.body();
assert result != null;
if(result.size() > 0) { if(result.size() > 0) {
pageSize = result.size(); pageSize = result.size();
commitsList.addAll(result); commitsList.addAll(result);
} }
else { else {
adapter.setMoreDataAvailable(false); adapter.setMoreDataAvailable(false);
} }
adapter.notifyDataChanged(); adapter.notifyDataChanged();
} }
else { else {
@ -214,13 +216,13 @@ public class CommitsActivity extends BaseActivity {
} }
progressLoadMore.setVisibility(View.GONE);
} }
@Override @Override
public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
Toasty.error(ctx, getResources().getString(R.string.errorOnLogin)); Log.e(TAG, t.toString());
} }
}); });

View File

@ -1,15 +1,18 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.graphics.PorterDuff;
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.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -21,8 +24,6 @@ import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.DeleteFile;
import org.mian.gitnex.models.EditFile;
import org.mian.gitnex.models.NewFile; import org.mian.gitnex.models.NewFile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -43,24 +44,12 @@ public class CreateFileActivity extends BaseActivity {
private EditText newFileContent; private EditText newFileContent;
private EditText newFileBranchName; private EditText newFileBranchName;
private EditText newFileCommitMessage; private EditText newFileCommitMessage;
private AutoCompleteTextView newFileBranchesSpinner; private Spinner newFileBranchesSpinner;
private String filePath;
private String fileSha;
private int fileAction = 0; // 0 = create, 1 = delete, 2 = edit
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private TinyDB tinyDb;
List<Branches> branchesList = new ArrayList<>(); List<Branches> branchesList = new ArrayList<>();
private String instanceUrl;
private String loginUid;
private String repoOwner;
private String repoName;
private String instanceToken;
private String selectedBranch;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
return R.layout.activity_new_file; return R.layout.activity_new_file;
@ -71,26 +60,27 @@ public class CreateFileActivity extends BaseActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
instanceUrl = tinyDb.getString("instanceUrl"); TinyDB tinyDb = new TinyDB(appCtx);
loginUid = tinyDb.getString("loginUid"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
repoOwner = parts[0]; final String repoOwner = parts[0];
repoName = parts[1]; final String repoName = parts[1];
instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
closeActivity = findViewById(R.id.close); closeActivity = findViewById(R.id.close);
newFileName = findViewById(R.id.newFileName); newFileName = findViewById(R.id.newFileName);
newFileContent = findViewById(R.id.newFileContent); newFileContent = findViewById(R.id.newFileContent);
newFileBranchName = findViewById(R.id.newFileBranchName); newFileBranchName = findViewById(R.id.newFileBranchName);
newFileCommitMessage = findViewById(R.id.newFileCommitMessage); newFileCommitMessage = findViewById(R.id.newFileCommitMessage);
TextView toolbarTitle = findViewById(R.id.toolbarTitle); TextView branchNameId = findViewById(R.id.branchNameId);
TextView branchNameHintText = findViewById(R.id.branchNameHintText);
newFileName.requestFocus(); newFileName.requestFocus();
assert imm != null; assert imm != null;
@ -101,59 +91,53 @@ public class CreateFileActivity extends BaseActivity {
newFileCreate = findViewById(R.id.newFileCreate); newFileCreate = findViewById(R.id.newFileCreate);
if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", 1) == 1) {
fileAction = getIntent().getIntExtra("fileAction", 1);
filePath = getIntent().getStringExtra("filePath");
String fileContents = getIntent().getStringExtra("fileContents");
fileSha = getIntent().getStringExtra("fileSha");
toolbarTitle.setText(getString(R.string.deleteFileText, filePath));
newFileCreate.setText(R.string.deleteFile);
newFileName.setText(filePath);
newFileName.setEnabled(false);
newFileName.setFocusable(false);
newFileContent.setText(fileContents);
newFileContent.setEnabled(false);
newFileContent.setFocusable(false);
}
if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", 2) == 2) {
fileAction = getIntent().getIntExtra("fileAction", 2);
filePath = getIntent().getStringExtra("filePath");
String fileContents = getIntent().getStringExtra("fileContents");
fileSha = getIntent().getStringExtra("fileSha");
toolbarTitle.setText(getString(R.string.editFileText, filePath));
newFileCreate.setText(R.string.editFile);
newFileName.setText(filePath);
newFileName.setEnabled(false);
newFileName.setFocusable(false);
newFileContent.setText(fileContents);
}
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
newFileBranchesSpinner = findViewById(R.id.newFileBranchesSpinner); newFileBranchesSpinner = findViewById(R.id.newFileBranchesSpinner);
newFileBranchesSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid); getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
newFileBranchesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> arg0,
View arg1, int arg2, long arg3)
{
Branches bModelValue = (Branches) newFileBranchesSpinner.getSelectedItem();
if(bModelValue.toString().equals("No branch")) {
newFileBranchName.setEnabled(true);
newFileBranchName.setVisibility(View.VISIBLE);
branchNameId.setVisibility(View.VISIBLE);
branchNameHintText.setVisibility(View.VISIBLE);
}
else {
newFileBranchName.setEnabled(false);
newFileBranchName.setVisibility(View.GONE);
branchNameId.setVisibility(View.GONE);
branchNameHintText.setVisibility(View.GONE);
newFileBranchName.setText("");
}
}
public void onNothingSelected(AdapterView<?> arg0) {}
});
disableProcessButton(); disableProcessButton();
if(!connToInternet) { if(!connToInternet) {
newFileCreate.setEnabled(false); newFileCreate.setEnabled(false);
} GradientDrawable shape = new GradientDrawable();
else { shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
newFileCreate.setBackground(shape);
} else {
newFileCreate.setOnClickListener(createFileListener); newFileCreate.setOnClickListener(createFileListener);
} }
} }
@ -164,37 +148,48 @@ public class CreateFileActivity extends BaseActivity {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
String newFileName_ = newFileName.getText().toString(); String newFileName_ = newFileName.getText().toString();
String newFileContent_ = newFileContent.getText().toString(); String newFileContent_ = newFileContent.getText().toString();
String newFileBranchName_ = newFileBranchName.getText().toString(); String newFileBranchName_ = newFileBranchName.getText().toString();
String newFileCommitMessage_ = newFileCommitMessage.getText().toString(); String newFileCommitMessage_ = newFileCommitMessage.getText().toString();
//Branches currentBranch = (Branches) newFileBranchesSpinner.getSelectedItem(); Branches currentBranch = (Branches) newFileBranchesSpinner.getSelectedItem();
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) { if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) {
Toasty.error(ctx, getString(R.string.newFileRequiredFields)); Toasty.info(ctx, getString(R.string.newFileRequiredFields));
return; return;
} }
if(selectedBranch.equals("No branch")) { if(currentBranch.toString().equals("No branch")) {
if(newFileBranchName_.equals("")) { if(newFileBranchName_.equals("")) {
Toasty.error(ctx, getString(R.string.newFileRequiredFieldNewBranchName)); Toasty.info(ctx, getString(R.string.newFileRequiredFieldNewBranchName));
return; return;
} }
else { else {
if(!appUtil.checkStringsWithDash(newFileBranchName_)) { if(!appUtil.checkStringsWithDash(newFileBranchName_)) {
Toasty.error(ctx, getString(R.string.newFileInvalidBranchName)); Toasty.info(ctx, getString(R.string.newFileInvalidBranchName));
return; return;
} }
} }
@ -202,27 +197,13 @@ public class CreateFileActivity extends BaseActivity {
if(appUtil.charactersLength(newFileCommitMessage_) > 255) { if(appUtil.charactersLength(newFileCommitMessage_) > 255) {
Toasty.warning(ctx, getString(R.string.newFileCommitMessageError)); Toasty.info(ctx, getString(R.string.newFileCommitMessageError));
} }
else { else {
disableProcessButton(); disableProcessButton();
createNewFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newFileName_, appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString());
if(fileAction == 1) {
deleteFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, filePath,
newFileBranchName_, newFileCommitMessage_, selectedBranch, fileSha);
}
else if(fileAction == 2) {
editFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, filePath,
appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, selectedBranch, fileSha);
}
else {
createNewFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newFileName_,
appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, selectedBranch);
}
} }
@ -232,11 +213,9 @@ public class CreateFileActivity extends BaseActivity {
NewFile createNewFileJsonStr; NewFile createNewFileJsonStr;
if(currentBranch.equals("No branch")) { if(currentBranch.equals("No branch")) {
createNewFileJsonStr = new NewFile("", fileContent, fileCommitMessage, fileBranchName); createNewFileJsonStr = new NewFile("", fileContent, fileCommitMessage, fileBranchName);
} }
else { else {
createNewFileJsonStr = new NewFile(currentBranch, fileContent, fileCommitMessage, ""); createNewFileJsonStr = new NewFile(currentBranch, fileContent, fileCommitMessage, "");
} }
@ -253,7 +232,7 @@ public class CreateFileActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
enableProcessButton(); enableProcessButton();
Toasty.success(ctx, getString(R.string.newFileSuccessMessage)); Toasty.info(ctx, getString(R.string.newFileSuccessMessage));
finish(); finish();
} }
@ -269,81 +248,12 @@ public class CreateFileActivity extends BaseActivity {
else { else {
if(response.code() == 404) { if(response.code() == 404) {
enableProcessButton();
Toasty.warning(ctx, getString(R.string.apiNotFound));
}
else {
enableProcessButton();
Toasty.error(ctx, getString(R.string.orgCreatedError));
}
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
enableProcessButton();
}
});
}
private void deleteFile(final String instanceUrl, final String token, String repoOwner, String repoName, String fileName, String fileBranchName, String fileCommitMessage, String currentBranch, String fileSha) {
String branchName;
DeleteFile deleteFileJsonStr;
if(currentBranch.equals("No branch")) {
branchName = fileBranchName;
deleteFileJsonStr = new DeleteFile("", fileCommitMessage, fileBranchName, fileSha);
}
else {
branchName = currentBranch;
deleteFileJsonStr = new DeleteFile(currentBranch, fileCommitMessage, "", fileSha);
}
Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.deleteFile(token, repoOwner, repoName, fileName, deleteFileJsonStr);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 200) {
enableProcessButton();
Toasty.info(ctx, getString(R.string.deleteFileMessage, branchName));
getIntent().removeExtra("filePath");
getIntent().removeExtra("fileSha");
getIntent().removeExtra("fileContents");
finish();
}
else if(response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.apiNotFound)); Toasty.info(ctx, getString(R.string.apiNotFound));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.info(ctx, getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.orgCreatedError));
} }
} }
@ -352,77 +262,6 @@ public class CreateFileActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
enableProcessButton();
}
});
}
private void editFile(final String instanceUrl, final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileBranchName, String fileCommitMessage, String currentBranch, String fileSha) {
String branchName;
EditFile editFileJsonStr;
if(currentBranch.equals("No branch")) {
branchName = fileBranchName;
editFileJsonStr = new EditFile("", fileCommitMessage, fileBranchName, fileSha, fileContent);
}
else {
branchName = currentBranch;
editFileJsonStr = new EditFile(currentBranch, fileCommitMessage, "", fileSha, fileContent);
}
Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.editFile(token, repoOwner, repoName, fileName, editFileJsonStr);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 200) {
enableProcessButton();
Toasty.info(ctx, getString(R.string.editFileMessage, branchName));
getIntent().removeExtra("filePath");
getIntent().removeExtra("fileSha");
getIntent().removeExtra("fileContents");
tinyDb.putBoolean("fileModified", true);
finish();
}
else if(response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else {
if(response.code() == 404) {
enableProcessButton();
Toasty.info(ctx, getString(R.string.apiNotFound));
}
else {
enableProcessButton();
Toasty.info(ctx, getString(R.string.genericError));
}
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
enableProcessButton(); enableProcessButton();
} }
@ -461,29 +300,12 @@ public class CreateFileActivity extends BaseActivity {
} }
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateFileActivity.this, ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateFileActivity.this,
R.layout.list_spinner_items, branchesList); R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
newFileBranchesSpinner.setAdapter(adapter); newFileBranchesSpinner.setAdapter(adapter);
enableProcessButton(); enableProcessButton();
newFileBranchesSpinner.setOnItemClickListener ((parent, view, position, id) -> {
selectedBranch = branchesList.get(position).getName();
if(selectedBranch.equals("No branch")) {
newFileBranchName.setEnabled(true);
newFileBranchName.setVisibility(View.VISIBLE);
}
else {
newFileBranchName.setEnabled(false);
newFileBranchName.setVisibility(View.GONE);
newFileBranchName.setText("");
}
});
} }
} }
@ -491,7 +313,6 @@ public class CreateFileActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
@ -499,18 +320,27 @@ public class CreateFileActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> finish(); onClickListener = view -> finish();
} }
private void disableProcessButton() { private void disableProcessButton() {
newFileCreate.setEnabled(false); newFileCreate.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
newFileCreate.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
newFileCreate.setEnabled(true); newFileCreate.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
newFileCreate.setBackground(shape);
} }
} }

View File

@ -1,29 +1,31 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.AssigneesActions;
import org.mian.gitnex.actions.LabelsActions;
import org.mian.gitnex.adapters.AssigneesListAdapter;
import org.mian.gitnex.adapters.LabelsListAdapter;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateIssueBinding;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
@ -32,50 +34,45 @@ import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.Labels; import org.mian.gitnex.models.Labels;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.models.MultiSelectModel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
*/ */
public class CreateIssueActivity extends BaseActivity implements View.OnClickListener, LabelsListAdapter.LabelsListAdapterListener, AssigneesListAdapter.AssigneesListAdapterListener { public class CreateIssueActivity extends BaseActivity implements View.OnClickListener {
private ActivityCreateIssueBinding viewBinding;
private CustomLabelsSelectionDialogBinding labelsBinding;
private CustomAssigneesSelectionDialogBinding assigneesBinding;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
MultiSelectDialog multiSelectDialog;
MultiSelectDialog multiSelectDialogLabels;
private TextView assigneesList;
private TextView newIssueLabels;
private TextView newIssueDueDate;
private Spinner newIssueMilestoneSpinner;
private EditText newIssueTitle;
private SocialAutoCompleteTextView newIssueDescription;
private Button createNewIssueButton;
private TextView labelsIdHolder;
private boolean assigneesFlag;
private boolean labelsFlag;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private TinyDB tinyDb;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private Dialog dialogLabels;
private Dialog dialogAssignees;
private String labelsSetter;
private String assigneesSetter;
private int milestoneId;
private String instanceUrl; List<Milestones> milestonesList = new ArrayList<>();
private String loginUid; ArrayList<MultiSelectModel> listOfAssignees = new ArrayList<>();
private String instanceToken; ArrayList<MultiSelectModel> listOfLabels= new ArrayList<>();
private String repoOwner; private ArrayAdapter<Mention> defaultMentionAdapter;
private String repoName;
private LabelsListAdapter labelsAdapter;
private AssigneesListAdapter assigneesAdapter;
private List<Integer> labelsIds = new ArrayList<>();
private List<Labels> labelsList = new ArrayList<>();
private List<Milestones> milestonesList = new ArrayList<>();
private List<Collaborators> assigneesList = new ArrayList<>();
private List<String> assigneesListData = new ArrayList<>();
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId(){
return R.layout.activity_create_issue; return R.layout.activity_create_issue;
} }
@ -84,169 +81,204 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
viewBinding = ActivityCreateIssueBinding.inflate(getLayoutInflater());
View view = viewBinding.getRoot();
setContentView(view);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
instanceUrl = tinyDb.getString("instanceUrl"); TinyDB tinyDb = new TinyDB(appCtx);
loginUid = tinyDb.getString("loginUid"); final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String loginFullName = tinyDb.getString("userFullname"); final String loginFullName = tinyDb.getString("userFullname");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
repoOwner = parts[0]; final String repoOwner = parts[0];
repoName = parts[1]; final String repoName = parts[1];
instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
// require gitea 1.12 or higher // if gitea is 1.12 or higher use the new limit
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
} }
viewBinding.newIssueTitle.requestFocus(); ImageView closeActivity = findViewById(R.id.close);
assert imm != null; assigneesList = findViewById(R.id.newIssueAssigneesList);
imm.showSoftInput(viewBinding.newIssueTitle, InputMethodManager.SHOW_IMPLICIT); newIssueLabels = findViewById(R.id.newIssueLabels);
newIssueDueDate = findViewById(R.id.newIssueDueDate);
createNewIssueButton = findViewById(R.id.createNewIssueButton);
newIssueTitle = findViewById(R.id.newIssueTitle);
newIssueDescription = findViewById(R.id.newIssueDescription);
labelsIdHolder = findViewById(R.id.labelsIdHolder);
labelsAdapter = new LabelsListAdapter(labelsList, CreateIssueActivity.this, labelsIds); newIssueTitle.requestFocus();
assigneesAdapter = new AssigneesListAdapter(ctx, assigneesList, CreateIssueActivity.this, assigneesListData); assert imm != null;
imm.showSoftInput(newIssueTitle, InputMethodManager.SHOW_IMPLICIT);
defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList();
newIssueDescription.setMentionAdapter(defaultMentionAdapter);
initCloseListener(); initCloseListener();
viewBinding.close.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
viewBinding.newIssueAssigneesList.setOnClickListener(this); assigneesList.setOnClickListener(this);
viewBinding.newIssueLabels.setOnClickListener(this); newIssueLabels.setOnClickListener(this);
viewBinding.newIssueDueDate.setOnClickListener(this); newIssueDueDate.setOnClickListener(this);
newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner);
newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit); getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit);
getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName);
disableProcessButton(); disableProcessButton();
viewBinding.newIssueLabels.setOnClickListener(newIssueLabels ->
showLabels()
);
viewBinding.newIssueAssigneesList.setOnClickListener(newIssueAssigneesList ->
showAssignees()
);
if(!connToInternet) { if(!connToInternet) {
viewBinding.createNewIssueButton.setEnabled(false); createNewIssueButton.setEnabled(false);
} GradientDrawable shape = new GradientDrawable();
else { shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createNewIssueButton.setBackground(shape);
viewBinding.createNewIssueButton.setOnClickListener(this); } else {
}
createNewIssueButton.setOnClickListener(this);
} }
@Override
public void assigneesInterface(List<String> data) {
assigneesSetter = String.valueOf(data);
viewBinding.newIssueAssigneesList.setText(assigneesSetter.replace("]", "").replace("[", ""));
assigneesListData = data;
}
@Override
public void labelsInterface(List<String> data) {
labelsSetter = String.valueOf(data);
viewBinding.newIssueLabels.setText(labelsSetter.replace("]", "").replace("[", ""));
}
@Override
public void labelsIdsInterface(List<Integer> data) {
labelsIds = data;
}
private void showAssignees() {
dialogAssignees = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
if (dialogAssignees.getWindow() != null) {
dialogAssignees.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
assigneesBinding = CustomAssigneesSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
View view = assigneesBinding.getRoot();
dialogAssignees.setContentView(view);
assigneesBinding.cancel.setOnClickListener(assigneesBinding_ ->
dialogAssignees.dismiss()
);
AssigneesActions.getRepositoryAssignees(ctx, instanceUrl, instanceToken, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding);
}
private void showLabels() {
dialogLabels = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
if (dialogLabels.getWindow() != null) {
dialogLabels.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
labelsBinding = CustomLabelsSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
View view = labelsBinding.getRoot();
dialogLabels.setContentView(view);
labelsBinding.cancel.setOnClickListener(labelsBinding_ ->
dialogLabels.dismiss()
);
LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding);
} }
private void processNewIssue() { private void processNewIssue() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String newIssueTitleForm = Objects.requireNonNull(viewBinding.newIssueTitle.getText()).toString(); Milestones mModel = (Milestones) newIssueMilestoneSpinner.getSelectedItem();
String newIssueDescriptionForm = Objects.requireNonNull(viewBinding.newIssueDescription.getText()).toString();
String newIssueDueDateForm = Objects.requireNonNull(viewBinding.newIssueDueDate.getText()).toString(); int newIssueMilestoneIdForm = mModel.getId();
String newIssueTitleForm = newIssueTitle.getText().toString();
String newIssueDescriptionForm = newIssueDescription.getText().toString();
String newIssueAssigneesListForm = assigneesList.getText().toString();
//String newIssueLabelsForm = newIssueLabels.getText().toString();
String newIssueDueDateForm = newIssueDueDate.getText().toString();
String newIssueLabelsIdHolderForm = labelsIdHolder.getText().toString();
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (newIssueTitleForm.equals("")) { if (newIssueTitleForm.equals("")) {
Toasty.error(ctx, getString(R.string.issueTitleEmpty)); Toasty.info(ctx, getString(R.string.issueTitleEmpty));
return; return;
} }
/*if (newIssueDescriptionForm.equals("")) {
Toasty.info(ctx, getString(R.string.issueDescriptionEmpty));
return;
}*/
if (newIssueDueDateForm.equals("")) { if (newIssueDueDateForm.equals("")) {
newIssueDueDateForm = null; newIssueDueDateForm = null;
} } else {
else {
newIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(newIssueDueDateForm))); newIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(newIssueDueDateForm)));
} }
List<String> newIssueAssigneesListForm_ = new ArrayList<>(Arrays.asList(newIssueAssigneesListForm.split(",")));
for (int i = 0; i < newIssueAssigneesListForm_.size(); i++) {
newIssueAssigneesListForm_.set(i, newIssueAssigneesListForm_.get(i).trim());
}
int[] integers;
if (!newIssueLabelsIdHolderForm.equals("")) {
String[] items = newIssueLabelsIdHolderForm.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
integers = new int[items.length];
for (int i = 0; i < integers.length; i++) {
integers[i] = Integer.parseInt(items[i]);
}
}
else {
integers = new int[0];
}
//Log.i("FormData", String.valueOf(newIssueLabelsForm));
disableProcessButton(); disableProcessButton();
createNewIssueFunc(instanceUrl, instanceToken, repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, milestoneId, newIssueTitleForm); createNewIssueFunc(instanceUrl, instanceToken, repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, newIssueAssigneesListForm_, integers);
} }
private void createNewIssueFunc(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm) { public void loadCollaboratorsList() {
CreateIssue createNewIssueJson = new CreateIssue(loginUid, newIssueDescriptionForm, false, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, assigneesListData, labelsIds); final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
if (response.isSuccessful()) {
assert response.body() != null;
String fullName = "";
for (int i = 0; i < response.body().size(); i++) {
if(!response.body().get(i).getFull_name().equals("")) {
fullName = response.body().get(i).getFull_name();
}
defaultMentionAdapter.add(
new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
}
} else {
Log.i("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.toString());
}
});
}
private void createNewIssueFunc(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm, List<String> newIssueAssigneesListForm, int[] newIssueLabelsForm) {
CreateIssue createNewIssueJson = new CreateIssue(loginUid, newIssueDescriptionForm, false, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, newIssueAssigneesListForm, newIssueLabelsForm);
Call<JsonElement> call3; Call<JsonElement> call3;
@ -260,14 +292,19 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
@Override @Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response2) { public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response2) {
if(response2.isSuccessful()) {
if(response2.code() == 201) { if(response2.code() == 201) {
//Log.i("isSuccessful1", String.valueOf(response2.body()));
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
Toasty.success(ctx, getString(R.string.issueCreated)); Toasty.info(ctx, getString(R.string.issueCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
}
} }
else if(response2.code() == 401) { else if(response2.code() == 401) {
@ -276,19 +313,21 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else { else {
Toasty.error(ctx, getString(R.string.issueCreatedError)); Toasty.info(ctx, getString(R.string.issueCreatedError));
enableProcessButton(); enableProcessButton();
//Log.i("isSuccessful2", String.valueOf(response2.body()));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
Toasty.error(ctx, getString(R.string.genericServerResponseError));
enableProcessButton(); enableProcessButton();
} }
}); });
@ -296,8 +335,12 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) { private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) {
@ -336,16 +379,12 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
} }
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreateIssueActivity.this, ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreateIssueActivity.this,
R.layout.list_spinner_items, milestonesList); R.layout.spinner_item, milestonesList);
viewBinding.newIssueMilestoneSpinner.setAdapter(adapter); adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
newIssueMilestoneSpinner.setAdapter(adapter);
enableProcessButton(); enableProcessButton();
viewBinding.newIssueMilestoneSpinner.setOnItemClickListener ((parent, view, position, id) ->
milestoneId = milestonesList.get(position).getId()
);
} }
} }
@ -353,8 +392,143 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
@Override @Override
public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
Toasty.error(ctx, getString(R.string.genericServerResponseError)); }
private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, String loginFullName) {
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
listOfAssignees.add(new MultiSelectModel(-1, loginFullName));
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull retrofit2.Response<List<Collaborators>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
List<Collaborators> assigneesList_ = response.body();
assert assigneesList_ != null;
if(assigneesList_.size() > 0) {
for (int i = 0; i < assigneesList_.size(); i++) {
/*String assigneesCopy;
if(!assigneesList_.get(i).getFull_name().equals("")) {
assigneesCopy = getString(R.string.dialogAssignessText, assigneesList_.get(i).getFull_name(), assigneesList_.get(i).getLogin());
}
else {
assigneesCopy = assigneesList_.get(i).getLogin();
}*/
listOfAssignees.add(new MultiSelectModel(assigneesList_.get(i).getId(), assigneesList_.get(i).getLogin().trim()));
}
assigneesFlag = true;
}
multiSelectDialog = new MultiSelectDialog()
.title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
.titleSize(25)
.positiveText(getResources().getString(R.string.okButton))
.negativeText(getResources().getString(R.string.cancelButton))
.setMinSelectionLimit(0)
.setMaxSelectionLimit(listOfAssignees.size())
.multiSelectList(listOfAssignees)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
assigneesList.setText(dataString);
}
@Override
public void onCancel() {
//Log.d("multiSelect","Dialog cancelled");
}
});
}
}
}
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
Call<List<Labels>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getlabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Labels>>() {
@Override
public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
List<Labels> labelsList_ = response.body();
assert labelsList_ != null;
if(labelsList_.size() > 0) {
for (int i = 0; i < labelsList_.size(); i++) {
listOfLabels.add(new MultiSelectModel(labelsList_.get(i).getId(), labelsList_.get(i).getName().trim()));
}
labelsFlag = true;
}
multiSelectDialogLabels = new MultiSelectDialog()
.title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
.titleSize(25)
.positiveText(getResources().getString(R.string.okButton))
.negativeText(getResources().getString(R.string.cancelButton))
.setMinSelectionLimit(0)
.setMaxSelectionLimit(listOfLabels.size())
.multiSelectList(listOfLabels)
.onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
@Override
public void onSelected(List<Integer> selectedIds, List<String> selectedNames, String dataString) {
newIssueLabels.setText(dataString.trim());
labelsIdHolder.setText(selectedIds.toString());
}
@Override
public void onCancel() {
//Log.d("multiSelect","Dialog cancelled");
}
});
}
}
}
@Override
public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
} }
}); });
@ -362,8 +536,23 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (v == assigneesList) {
if (v == viewBinding.newIssueDueDate) { if(assigneesFlag) {
multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog");
}
else {
Toasty.info(ctx, getResources().getString(R.string.noAssigneesFound));
}
}
else if (v == newIssueLabels) {
if(labelsFlag) {
multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels");
}
else {
Toasty.info(ctx, getResources().getString(R.string.noLabelsFound));
}
}
else if (v == newIssueDueDate) {
final Calendar c = Calendar.getInstance(); final Calendar c = Calendar.getInstance();
int mYear = c.get(Calendar.YEAR); int mYear = c.get(Calendar.YEAR);
@ -371,10 +560,19 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
final int mDay = c.get(Calendar.DAY_OF_MONTH); final int mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(this, DatePickerDialog datePickerDialog = new DatePickerDialog(this,
(view, year, monthOfYear, dayOfMonth) -> viewBinding.newIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay); new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
newIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth));
}
}, mYear, mMonth, mDay);
datePickerDialog.show(); datePickerDialog.show();
} }
else if(v == viewBinding.createNewIssueButton) { else if(v == createNewIssueButton) {
processNewIssue(); processNewIssue();
} }
@ -382,11 +580,21 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis
private void disableProcessButton() { private void disableProcessButton() {
viewBinding.createNewIssueButton.setEnabled(false); createNewIssueButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createNewIssueButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
viewBinding.createNewIssueButton.setEnabled(true); createNewIssueButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
createNewIssueButton.setBackground(shape);
} }
} }

View File

@ -2,6 +2,7 @@ package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
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;
@ -117,23 +118,38 @@ public class CreateLabelActivity extends BaseActivity {
createLabelButton.setText(getResources().getString(R.string.newUpdateButtonCopy)); createLabelButton.setText(getResources().getString(R.string.newUpdateButtonCopy));
createLabelButton.setOnClickListener(updateLabelListener); createLabelButton.setOnClickListener(updateLabelListener);
return; return;
} }
if(!connToInternet) { if(!connToInternet) {
createLabelButton.setEnabled(false); createLabelButton.setEnabled(false);
} GradientDrawable shape = new GradientDrawable();
else { shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createLabelButton.setBackground(shape);
} else {
createLabelButton.setOnClickListener(createLabelListener); createLabelButton.setOnClickListener(createLabelListener);
} }
} }
private View.OnClickListener createLabelListener = v -> processCreateLabel(); private View.OnClickListener createLabelListener = new View.OnClickListener() {
public void onClick(View v) {
processCreateLabel();
}
};
private View.OnClickListener updateLabelListener = v -> processUpdateLabel(); private View.OnClickListener updateLabelListener = new View.OnClickListener() {
public void onClick(View v) {
processUpdateLabel();
}
};
private void processUpdateLabel() { private void processUpdateLabel() {
@ -160,28 +176,27 @@ public class CreateLabelActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(updateLabelName.equals("")) { if(updateLabelName.equals("")) {
Toasty.error(ctx, getString(R.string.labelEmptyError)); Toasty.info(ctx, getString(R.string.labelEmptyError));
return; return;
} }
if(!appUtil.checkStrings(updateLabelName)) { if(!appUtil.checkStrings(updateLabelName)) {
Toasty.error(ctx, getString(R.string.labelNameError)); Toasty.info(ctx, getString(R.string.labelNameError));
return; return;
} }
disableProcessButton(); disableProcessButton();
patchLabel(instanceUrl, instanceToken, repoOwner, repoName, updateLabelName, updateLabelColor, Integer.parseInt( patchLabel(instanceUrl, instanceToken, repoOwner, repoName, updateLabelName, updateLabelColor, Integer.valueOf(getIntent().getStringExtra("labelId")), loginUid);
Objects.requireNonNull(getIntent().getStringExtra("labelId"))), loginUid);
} }
@ -209,21 +224,21 @@ public class CreateLabelActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newLabelName.equals("")) { if(newLabelName.equals("")) {
Toasty.error(ctx, getString(R.string.labelEmptyError)); Toasty.info(ctx, getString(R.string.labelEmptyError));
return; return;
} }
if(!appUtil.checkStrings(newLabelName)) { if(!appUtil.checkStrings(newLabelName)) {
Toasty.error(ctx, getString(R.string.labelNameError)); Toasty.info(ctx, getString(R.string.labelNameError));
return; return;
} }
@ -252,7 +267,7 @@ public class CreateLabelActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.success(ctx, getString(R.string.labelCreated)); Toasty.info(ctx, getString(R.string.labelCreated));
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putBoolean("labelsRefresh", true); tinyDb.putBoolean("labelsRefresh", true);
finish(); finish();
@ -271,7 +286,7 @@ public class CreateLabelActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
Toasty.error(ctx, getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }
@ -279,7 +294,6 @@ public class CreateLabelActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<CreateLabel> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<CreateLabel> call, @NonNull Throwable t) {
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
enableProcessButton(); enableProcessButton();
@ -308,7 +322,7 @@ public class CreateLabelActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 200) { if(response.code() == 200) {
Toasty.success(ctx, getString(R.string.labelUpdated)); Toasty.info(ctx, getString(R.string.labelUpdated));
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putBoolean("labelsRefresh", true); tinyDb.putBoolean("labelsRefresh", true);
tinyDb.putString("labelColorDefault", ""); tinyDb.putString("labelColorDefault", "");
@ -334,7 +348,7 @@ public class CreateLabelActivity extends BaseActivity {
enableProcessButton(); enableProcessButton();
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putString("labelColorDefault", ""); tinyDb.putString("labelColorDefault", "");
Toasty.error(ctx, getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }
@ -342,7 +356,6 @@ public class CreateLabelActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<CreateLabel> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<CreateLabel> call, @NonNull Throwable t) {
tinyDb.putString("labelColor", ""); tinyDb.putString("labelColor", "");
tinyDb.putString("labelColorDefault", ""); tinyDb.putString("labelColorDefault", "");
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
@ -382,7 +395,7 @@ public class CreateLabelActivity extends BaseActivity {
if(response.isSuccessful()) { if(response.isSuccessful()) {
if(response.code() == 204) { if(response.code() == 204) {
Toasty.success(ctx, getString(R.string.labelDeleteText)); Toasty.info(ctx, getString(R.string.labelDeleteText));
LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, ctx); LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, ctx);
getIntent().removeExtra("labelAction"); getIntent().removeExtra("labelAction");
getIntent().removeExtra("labelId"); getIntent().removeExtra("labelId");
@ -399,7 +412,7 @@ public class CreateLabelActivity extends BaseActivity {
} }
else { else {
Toasty.error(ctx, getString(R.string.labelDeleteErrorText)); Toasty.info(ctx, getString(R.string.labelDeleteErrorText));
} }
@ -416,11 +429,21 @@ public class CreateLabelActivity extends BaseActivity {
private void disableProcessButton() { private void disableProcessButton() {
createLabelButton.setEnabled(false); createLabelButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createLabelButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
createLabelButton.setEnabled(true); createLabelButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
createLabelButton.setBackground(shape);
} }
} }

View File

@ -2,6 +2,7 @@ package org.mian.gitnex.activities;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@ -70,15 +71,24 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(!connToInternet) { if(!connToInternet) {
createNewMilestoneButton.setEnabled(false); createNewMilestoneButton.setEnabled(false);
} GradientDrawable shape = new GradientDrawable();
else { shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createNewMilestoneButton.setBackground(shape);
} else {
createNewMilestoneButton.setOnClickListener(createMilestoneListener); createNewMilestoneButton.setOnClickListener(createMilestoneListener);
} }
} }
private View.OnClickListener createMilestoneListener = v -> processNewMilestone(); private View.OnClickListener createMilestoneListener = new View.OnClickListener() {
public void onClick(View v) {
processNewMilestone();
}
};
private void processNewMilestone() { private void processNewMilestone() {
@ -100,14 +110,14 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newMilestoneTitle.equals("")) { if(newMilestoneTitle.equals("")) {
Toasty.error(ctx, getString(R.string.milestoneNameErrorEmpty)); Toasty.info(ctx, getString(R.string.milestoneNameErrorEmpty));
return; return;
} }
@ -115,7 +125,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if(!newMilestoneDescription.equals("")) { if(!newMilestoneDescription.equals("")) {
if (appUtil.charactersLength(newMilestoneDescription) > 255) { if (appUtil.charactersLength(newMilestoneDescription) > 255) {
Toasty.warning(ctx, getString(R.string.milestoneDescError)); Toasty.info(ctx, getString(R.string.milestoneDescError));
return; return;
} }
@ -123,13 +133,10 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
String finalMilestoneDueDate = null; String finalMilestoneDueDate = null;
if(!newMilestoneDueDate.isEmpty()) { if(!newMilestoneDueDate.isEmpty()) {
finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate))); finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate)));
} } else if (new Version(tinyDb.getString("giteaVersion")).less("1.10.0")) {
else if (new Version(tinyDb.getString("giteaVersion")).less("1.10.0")) {
// if Gitea version is less than 1.10.0 DueDate is required // if Gitea version is less than 1.10.0 DueDate is required
Toasty.warning(ctx, getString(R.string.milestoneDateEmpty)); Toasty.info(ctx, getString(R.string.milestoneDateEmpty));
return; return;
} }
@ -159,7 +166,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("milestoneCreated", true); tinyDb.putBoolean("milestoneCreated", true);
Toasty.success(ctx, getString(R.string.milestoneCreated)); Toasty.info(ctx, getString(R.string.milestoneCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -177,7 +184,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, getString(R.string.milestoneCreatedError)); Toasty.info(ctx, getString(R.string.milestoneCreatedError));
} }
@ -219,18 +226,32 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
private void disableProcessButton() { private void disableProcessButton() {
createNewMilestoneButton.setEnabled(false); createNewMilestoneButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createNewMilestoneButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
createNewMilestoneButton.setEnabled(true); createNewMilestoneButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
createNewMilestoneButton.setBackground(shape);
} }
} }

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.util.Patterns; import android.util.Patterns;
@ -68,10 +69,11 @@ public class CreateNewUserActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
disableProcessButton(); disableProcessButton();
}
else { } else {
createUserButton.setOnClickListener(createNewUserListener); createUserButton.setOnClickListener(createNewUserListener);
} }
} }
@ -92,35 +94,35 @@ public class CreateNewUserActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) { if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) {
Toasty.error(ctx, getString(R.string.emptyFields)); Toasty.info(ctx, getString(R.string.emptyFields));
return; return;
} }
if(!appUtil.checkStrings(newFullName)) { if(!appUtil.checkStrings(newFullName)) {
Toasty.error(ctx, getString(R.string.userInvalidFullName)); Toasty.info(ctx, getString(R.string.userInvalidFullName));
return; return;
} }
if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) { if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) {
Toasty.error(ctx, getString(R.string.userInvalidUserName)); Toasty.info(ctx, getString(R.string.userInvalidUserName));
return; return;
} }
if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
Toasty.error(ctx, getString(R.string.userInvalidEmail)); Toasty.info(ctx, getString(R.string.userInvalidEmail));
return; return;
} }
@ -148,7 +150,7 @@ public class CreateNewUserActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.success(ctx, getString(R.string.userCreatedText)); Toasty.info(ctx, getString(R.string.userCreatedText));
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -165,25 +167,25 @@ public class CreateNewUserActivity extends BaseActivity {
else if(response.code() == 403) { else if(response.code() == 403) {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else if(response.code() == 422) { else if(response.code() == 422) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, ctx.getString(R.string.userExistsError)); Toasty.info(ctx, ctx.getString(R.string.userExistsError));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }
@ -191,7 +193,6 @@ public class CreateNewUserActivity extends BaseActivity {
@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());
enableProcessButton(); enableProcessButton();
} }
@ -199,21 +200,39 @@ public class CreateNewUserActivity extends BaseActivity {
} }
private View.OnClickListener createNewUserListener = v -> processCreateNewUser(); private View.OnClickListener createNewUserListener = new View.OnClickListener() {
public void onClick(View v) {
processCreateNewUser();
}
};
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
private void disableProcessButton() { private void disableProcessButton() {
createUserButton.setEnabled(false); createUserButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createUserButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
createUserButton.setEnabled(true); createUserButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
createUserButton.setBackground(shape);
} }
} }

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@ -66,10 +67,15 @@ public class CreateOrganizationActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
createOrganizationButton.setEnabled(false); createOrganizationButton.setEnabled(false);
} GradientDrawable shape = new GradientDrawable();
else { shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createOrganizationButton.setBackground(shape);
} else {
createOrganizationButton.setOnClickListener(createOrgListener); createOrganizationButton.setOnClickListener(createOrgListener);
} }
} }
@ -103,7 +109,7 @@ public class CreateOrganizationActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
@ -111,7 +117,7 @@ public class CreateOrganizationActivity extends BaseActivity {
if(!newOrgDesc.equals("")) { if(!newOrgDesc.equals("")) {
if (appUtil.charactersLength(newOrgDesc) > 255) { if (appUtil.charactersLength(newOrgDesc) > 255) {
Toasty.warning(ctx, getString(R.string.orgDescError)); Toasty.info(ctx, getString(R.string.orgDescError));
return; return;
} }
@ -119,12 +125,12 @@ public class CreateOrganizationActivity extends BaseActivity {
if(newOrgName.equals("")) { if(newOrgName.equals("")) {
Toasty.error(ctx, getString(R.string.orgNameErrorEmpty)); Toasty.info(ctx, getString(R.string.orgNameErrorEmpty));
} }
else if(!appUtil.checkStrings(newOrgName)) { else if(!appUtil.checkStrings(newOrgName)) {
Toasty.warning(ctx, getString(R.string.orgNameErrorInvalid)); Toasty.info(ctx, getString(R.string.orgNameErrorInvalid));
} }
else { else {
@ -155,7 +161,7 @@ public class CreateOrganizationActivity extends BaseActivity {
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("orgCreated", true); tinyDb.putBoolean("orgCreated", true);
enableProcessButton(); enableProcessButton();
Toasty.success(ctx, getString(R.string.orgCreated)); Toasty.info(ctx, getString(R.string.orgCreated));
finish(); finish();
} }
@ -171,24 +177,24 @@ public class CreateOrganizationActivity extends BaseActivity {
else if(response.code() == 409) { else if(response.code() == 409) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, getString(R.string.orgExistsError)); Toasty.info(ctx, getString(R.string.orgExistsError));
} }
else if(response.code() == 422) { else if(response.code() == 422) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, getString(R.string.orgExistsError)); Toasty.info(ctx, getString(R.string.orgExistsError));
} }
else { else {
if(response.code() == 404) { if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, getString(R.string.apiNotFound)); Toasty.info(ctx, getString(R.string.apiNotFound));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, getString(R.string.orgCreatedError)); Toasty.info(ctx, getString(R.string.orgCreatedError));
} }
} }
@ -207,11 +213,21 @@ public class CreateOrganizationActivity extends BaseActivity {
private void disableProcessButton() { private void disableProcessButton() {
createOrganizationButton.setEnabled(false); createOrganizationButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createOrganizationButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
createOrganizationButton.setEnabled(true); createOrganizationButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
createOrganizationButton.setBackground(shape);
} }
} }

View File

@ -1,382 +0,0 @@
package org.mian.gitnex.activities;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.LabelsActions;
import org.mian.gitnex.adapters.LabelsListAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreatePrBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.CreatePullRequest;
import org.mian.gitnex.models.Labels;
import org.mian.gitnex.models.Milestones;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class CreatePullRequestActivity extends BaseActivity implements LabelsListAdapter.LabelsListAdapterListener {
private View.OnClickListener onClickListener;
private Context ctx = this;
private Context appCtx;
private TinyDB tinyDb;
private ActivityCreatePrBinding viewBinding;
private CustomLabelsSelectionDialogBinding labelsBinding;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private Dialog dialogLabels;
private String labelsSetter;
private List<Integer> labelsIds = new ArrayList<>();
private List<String> assignees = new ArrayList<>();
private int milestoneId;
private String instanceUrl;
private String loginUid;
private String instanceToken;
private String repoOwner;
private String repoName;
private LabelsListAdapter labelsAdapter;
List<Milestones> milestonesList = new ArrayList<>();
List<Branches> branchesList = new ArrayList<>();
List<Labels> labelsList = new ArrayList<>();
public CreatePullRequestActivity() {
}
@Override
protected int getLayoutResourceId(){
return R.layout.activity_create_pr;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
viewBinding = ActivityCreatePrBinding.inflate(getLayoutInflater());
View view = viewBinding.getRoot();
setContentView(view);
instanceUrl = tinyDb.getString("instanceUrl");
loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
repoOwner = parts[0];
repoName = parts[1];
instanceToken = "token " + tinyDb.getString(loginUid + "-token");
// require gitea 1.12 or higher
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}
labelsAdapter = new LabelsListAdapter(labelsList, CreatePullRequestActivity.this, labelsIds);
ImageView closeActivity = findViewById(R.id.close);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
viewBinding.prDueDate.setOnClickListener(dueDate ->
setDueDate()
);
disableProcessButton();
getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit);
getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
viewBinding.prLabels.setOnClickListener(prLabels ->
showLabels()
);
viewBinding.createPr.setOnClickListener(createPr ->
processPullRequest()
);
}
private void processPullRequest() {
String prTitle = String.valueOf(viewBinding.prTitle.getText());
String prDescription = String.valueOf(viewBinding.prBody.getText());
String mergeInto = viewBinding.mergeIntoBranchSpinner.getText().toString();
String pullFrom = viewBinding.pullFromBranchSpinner.getText().toString();
String dueDate = String.valueOf(viewBinding.prDueDate.getText());
assignees.add("");
if (labelsIds.size() == 0) {
labelsIds.add(0);
}
if (dueDate.matches("")) {
dueDate = null;
}
else {
dueDate = AppUtil.customDateCombine(AppUtil.customDateFormat(dueDate));
}
if(prTitle.matches("")) {
Toasty.error(ctx, getString(R.string.titleError));
}
else if(mergeInto.matches("")) {
Toasty.error(ctx, getString(R.string.mergeIntoError));
}
else if(pullFrom.matches("")) {
Toasty.error(ctx, getString(R.string.pullFromError));
}
else if(pullFrom.equals(mergeInto)) {
Toasty.error(ctx, getString(R.string.sameBranchesError));
}
else {
createPullRequest(prTitle, prDescription, mergeInto, pullFrom, milestoneId, dueDate, assignees);
}
//Log.e("processPullRequest", String.valueOf(milestoneId));
}
private void createPullRequest(String prTitle, String prDescription, String mergeInto, String pullFrom, int milestoneId, String dueDate, List<String> assignees) {
CreatePullRequest createPullRequest = new CreatePullRequest(prTitle, prDescription, loginUid, mergeInto, pullFrom, milestoneId, dueDate, assignees, labelsIds);
Call<ResponseBody> transferCall = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.createPullRequest(instanceToken, repoOwner, repoName, createPullRequest);
transferCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull retrofit2.Response<ResponseBody> response) {
disableProcessButton();
if (response.code() == 201) {
Toasty.success(ctx, getString(R.string.prCreateSuccess));
finish();
}
else if (response.code() == 409 && response.message().equals("Conflict")) {
enableProcessButton();
Toasty.error(ctx, getString(R.string.prAlreadyExists));
}
else if (response.code() == 404) {
enableProcessButton();
Toasty.error(ctx, getString(R.string.apiNotFound));
}
else {
enableProcessButton();
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
enableProcessButton();
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
}
@Override
public void labelsInterface(List<String> data) {
labelsSetter = String.valueOf(data);
viewBinding.prLabels.setText(labelsSetter.replace("]", "").replace("[", ""));
}
@Override
public void labelsIdsInterface(List<Integer> data) {
labelsIds = data;
}
private void showLabels() {
dialogLabels = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
if (dialogLabels.getWindow() != null) {
dialogLabels.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
labelsBinding = CustomLabelsSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
View view = labelsBinding.getRoot();
dialogLabels.setContentView(view);
labelsBinding.cancel.setOnClickListener(editProperties ->
dialogLabels.dismiss()
);
LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding);
}
private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
Call<List<Branches>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getBranches(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Branches>>() {
@Override
public void onResponse(@NonNull Call<List<Branches>> call, @NonNull retrofit2.Response<List<Branches>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) {
List<Branches> branchesList_ = response.body();
assert branchesList_ != null;
if(branchesList_.size() > 0) {
for (int i = 0; i < branchesList_.size(); i++) {
Branches data = new Branches(
branchesList_.get(i).getName()
);
branchesList.add(data);
}
}
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreatePullRequestActivity.this,
R.layout.list_spinner_items, branchesList);
viewBinding.mergeIntoBranchSpinner.setAdapter(adapter);
viewBinding.pullFromBranchSpinner.setAdapter(adapter);
enableProcessButton();
}
}
}
@Override
public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
}
private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) {
String msState = "open";
Call<List<Milestones>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState);
call.enqueue(new Callback<List<Milestones>>() {
@Override
public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull retrofit2.Response<List<Milestones>> response) {
if(response.code() == 200) {
List<Milestones> milestonesList_ = response.body();
milestonesList.add(new Milestones(0,getString(R.string.issueCreatedNoMilestone)));
assert milestonesList_ != null;
if(milestonesList_.size() > 0) {
for (int i = 0; i < milestonesList_.size(); i++) {
//Don't translate "open" is a enum
if(milestonesList_.get(i).getState().equals("open")) {
Milestones data = new Milestones(
milestonesList_.get(i).getId(),
milestonesList_.get(i).getTitle()
);
milestonesList.add(data);
}
}
}
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(CreatePullRequestActivity.this,
R.layout.list_spinner_items, milestonesList);
viewBinding.milestonesSpinner.setAdapter(adapter);
enableProcessButton();
viewBinding.milestonesSpinner.setOnItemClickListener ((parent, view, position, id) ->
milestoneId = milestonesList.get(position).getId()
);
}
}
@Override
public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
}
private void setDueDate() {
final Calendar c = Calendar.getInstance();
int mYear = c.get(Calendar.YEAR);
final int mMonth = c.get(Calendar.MONTH);
final int mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
(view, year, monthOfYear, dayOfMonth) -> viewBinding.prDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay);
datePickerDialog.show();
}
private void initCloseListener() {
onClickListener = view -> finish();
}
private void disableProcessButton() {
viewBinding.createPr.setEnabled(false);
}
private void enableProcessButton() {
viewBinding.createPr.setEnabled(true);
}
}

View File

@ -1,16 +1,19 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.graphics.PorterDuff;
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.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
@ -35,7 +38,7 @@ public class CreateReleaseActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
public ImageView closeActivity; public ImageView closeActivity;
private EditText releaseTagName; private EditText releaseTagName;
private AutoCompleteTextView releaseBranch; private Spinner releaseBranch;
private EditText releaseTitle; private EditText releaseTitle;
private EditText releaseContent; private EditText releaseContent;
private CheckBox releaseType; private CheckBox releaseType;
@ -43,14 +46,6 @@ public class CreateReleaseActivity extends BaseActivity {
private Button createNewRelease; private Button createNewRelease;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private TinyDB tinyDb;
private String selectedBranch;
private String instanceUrl;
private String loginUid;
private String instanceToken;
private String repoOwner;
private String repoName;
List<Branches> branchesList = new ArrayList<>(); List<Branches> branchesList = new ArrayList<>();
@ -64,19 +59,19 @@ public class CreateReleaseActivity extends BaseActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
instanceUrl = tinyDb.getString("instanceUrl"); TinyDB tinyDb = new TinyDB(appCtx);
loginUid = tinyDb.getString("loginUid"); final String instanceUrl = tinyDb.getString("instanceUrl");
instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
repoOwner = parts[0]; final String repoOwner = parts[0];
repoName = parts[1]; final String repoName = parts[1];
closeActivity = findViewById(R.id.close); closeActivity = findViewById(R.id.close);
releaseTagName = findViewById(R.id.releaseTagName); releaseTagName = findViewById(R.id.releaseTagName);
@ -85,15 +80,27 @@ 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);
releaseTitle.requestFocus(); releaseTagName.requestFocus();
assert imm != null; assert imm != null;
imm.showSoftInput(releaseTitle, InputMethodManager.SHOW_IMPLICIT); imm.showSoftInput(releaseTagName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
releaseBranch = findViewById(R.id.releaseBranch); releaseBranch = findViewById(R.id.releaseBranch);
releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getBranches(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); getBranches(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Branches branch = (Branches) parent.getSelectedItem();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
createNewRelease = findViewById(R.id.createNewRelease); createNewRelease = findViewById(R.id.createNewRelease);
disableProcessButton(); disableProcessButton();
@ -101,60 +108,70 @@ public class CreateReleaseActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
disableProcessButton(); disableProcessButton();
}
else { } else {
createNewRelease.setOnClickListener(createReleaseListener); createNewRelease.setOnClickListener(createReleaseListener);
} }
} }
private View.OnClickListener createReleaseListener = v -> processNewRelease(); private View.OnClickListener createReleaseListener = new View.OnClickListener() {
public void onClick(View v) {
processNewRelease();
}
};
private void processNewRelease() { private void processNewRelease() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
String newReleaseTagName = releaseTagName.getText().toString(); String newReleaseTagName = releaseTagName.getText().toString();
String newReleaseTitle = releaseTitle.getText().toString(); String newReleaseTitle = releaseTitle.getText().toString();
String newReleaseContent = releaseContent.getText().toString(); String newReleaseContent = releaseContent.getText().toString();
String checkBranch = selectedBranch; String newReleaseBranch = releaseBranch.getSelectedItem().toString();
boolean newReleaseType = releaseType.isChecked(); boolean newReleaseType = releaseType.isChecked();
boolean newReleaseDraft = releaseDraft.isChecked(); boolean newReleaseDraft = releaseDraft.isChecked();
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if(newReleaseTagName.equals("")) {
Toasty.info(ctx, getString(R.string.tagNameErrorEmpty));
return; return;
} }
if(newReleaseTitle.equals("")) { if(newReleaseTitle.equals("")) {
Toasty.error(ctx, getString(R.string.titleErrorEmpty)); Toasty.info(ctx, getString(R.string.titleErrorEmpty));
return; return;
}
if(newReleaseTagName.equals("")) {
Toasty.error(ctx, getString(R.string.tagNameErrorEmpty));
return;
}
if(checkBranch == null) {
Toasty.error(ctx, getString(R.string.selectBranchError));
return;
} }
disableProcessButton(); disableProcessButton();
createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, selectedBranch, newReleaseType, newReleaseDraft); createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, newReleaseBranch, newReleaseType, newReleaseDraft);
} }
private void createNewReleaseFunc(final String instanceUrl, final String token, String repoOwner, String repoName, String newReleaseTagName, String newReleaseTitle, String newReleaseContent, String selectedBranch, boolean newReleaseType, boolean newReleaseDraft) { private void createNewReleaseFunc(final String instanceUrl, final String token, String repoOwner, String repoName, String newReleaseTagName, String newReleaseTitle, String newReleaseContent, String newReleaseBranch, boolean newReleaseType, boolean newReleaseDraft) {
Releases createReleaseJson = new Releases(newReleaseContent, newReleaseDraft, newReleaseTitle, newReleaseType, newReleaseTagName, selectedBranch); Releases createReleaseJson = new Releases(newReleaseContent, newReleaseDraft, newReleaseTitle, newReleaseType, newReleaseTagName, newReleaseBranch);
Call<Releases> call; Call<Releases> call;
@ -170,10 +187,12 @@ public class CreateReleaseActivity extends BaseActivity {
if (response.code() == 201) { if (response.code() == 201) {
TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("updateReleases", true); tinyDb.putBoolean("updateReleases", true);
Toasty.success(ctx, getString(R.string.releaseCreatedText)); Toasty.info(ctx, getString(R.string.releaseCreatedText));
enableProcessButton(); enableProcessButton();
finish(); finish();
} }
else if(response.code() == 401) { else if(response.code() == 401) {
@ -187,19 +206,19 @@ public class CreateReleaseActivity extends BaseActivity {
else if(response.code() == 403) { else if(response.code() == 403) {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, ctx.getString(R.string.genericError)); Toasty.info(ctx, ctx.getString(R.string.genericError));
} }
@ -207,7 +226,6 @@ public class CreateReleaseActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<Releases> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Releases> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
enableProcessButton(); enableProcessButton();
} }
@ -234,20 +252,23 @@ public class CreateReleaseActivity extends BaseActivity {
assert branchesList_ != null; assert branchesList_ != null;
if(branchesList_.size() > 0) { if(branchesList_.size() > 0) {
for (int i = 0; i < branchesList_.size(); i++) {
branchesList.addAll(branchesList_); Branches data = new Branches(
branchesList_.get(i).getName()
);
branchesList.add(data);
}
} }
ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateReleaseActivity.this, ArrayAdapter<Branches> adapter = new ArrayAdapter<>(CreateReleaseActivity.this,
R.layout.list_spinner_items, branchesList); R.layout.spinner_item, branchesList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
releaseBranch.setAdapter(adapter); releaseBranch.setAdapter(adapter);
enableProcessButton(); enableProcessButton();
releaseBranch.setOnItemClickListener ((parent, view, position, id) ->
selectedBranch = branchesList.get(position).getName()
);
} }
} }
else if(response.code() == 401) { else if(response.code() == 401) {
@ -263,7 +284,6 @@ public class CreateReleaseActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
@ -271,18 +291,32 @@ public class CreateReleaseActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
private void disableProcessButton() { private void disableProcessButton() {
createNewRelease.setEnabled(false); createNewRelease.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createNewRelease.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
createNewRelease.setEnabled(true); createNewRelease.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
createNewRelease.setBackground(shape);
} }
} }

View File

@ -1,18 +1,19 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Spinner;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
@ -38,21 +39,13 @@ public class CreateRepoActivity extends BaseActivity {
public ImageView closeActivity; public ImageView closeActivity;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private AutoCompleteTextView spinner; private Spinner spinner;
private Button createRepo; private Button createRepo;
private EditText repoName; private EditText repoName;
private EditText repoDesc; private EditText repoDesc;
private CheckBox repoAccess; private CheckBox repoAccess;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private TinyDB tinyDb;
private String instanceUrl;
private String loginUid;
private String userLogin;
private String instanceToken;
private String selectedOwner;
List<OrgOwner> organizationsList = new ArrayList<>(); List<OrgOwner> organizationsList = new ArrayList<>();
@ -70,14 +63,14 @@ public class CreateRepoActivity extends BaseActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
boolean connToInternet = AppUtil.hasNetworkConnection(ctx); boolean connToInternet = AppUtil.hasNetworkConnection(ctx);
instanceUrl = tinyDb.getString("instanceUrl"); TinyDB tinyDb = new TinyDB(appCtx);
loginUid = tinyDb.getString("loginUid"); final String instanceUrl = tinyDb.getString("instanceUrl");
userLogin = tinyDb.getString("userLogin"); final String loginUid = tinyDb.getString("loginUid");
instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String userLogin = tinyDb.getString("userLogin");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -94,7 +87,19 @@ public class CreateRepoActivity extends BaseActivity {
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);
getOrganizations(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), userLogin); getOrganizations(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), userLogin);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
OrgOwner user = (OrgOwner) parent.getSelectedItem();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
createRepo = findViewById(R.id.createNewRepoButton); createRepo = findViewById(R.id.createNewRepoButton);
disableProcessButton(); disableProcessButton();
@ -102,83 +107,99 @@ public class CreateRepoActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
disableProcessButton(); disableProcessButton();
} }
else { else {
createRepo.setOnClickListener(createRepoListener); createRepo.setOnClickListener(createRepoListener);
} }
} }
private View.OnClickListener createRepoListener = v -> processNewRepo(); private View.OnClickListener createRepoListener = new View.OnClickListener() {
public void onClick(View v) {
processNewRepo();
}
};
private void processNewRepo() { private void processNewRepo() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
AppUtil appUtil = new AppUtil(); AppUtil appUtil = new AppUtil();
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String newRepoName = repoName.getText().toString(); String newRepoName = repoName.getText().toString();
String newRepoDesc = repoDesc.getText().toString(); String newRepoDesc = repoDesc.getText().toString();
String repoOwner = spinner.getSelectedItem().toString();
boolean newRepoAccess = repoAccess.isChecked(); boolean newRepoAccess = repoAccess.isChecked();
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(!newRepoDesc.equals("")) { if(!newRepoDesc.equals("")) {
if (appUtil.charactersLength(newRepoDesc) > 255) { if (appUtil.charactersLength(newRepoDesc) > 255) {
Toasty.warning(ctx, getString(R.string.repoDescError)); Toasty.info(ctx, getString(R.string.repoDescError));
return; return;
} }
} }
if(newRepoName.equals("")) { if(newRepoName.equals("")) {
Toasty.error(ctx, getString(R.string.repoNameErrorEmpty)); Toasty.info(ctx, getString(R.string.repoNameErrorEmpty));
} }
else if(!appUtil.checkStrings(newRepoName)) { else if(!appUtil.checkStrings(newRepoName)) {
Toasty.warning(ctx, getString(R.string.repoNameErrorInvalid)); Toasty.info(ctx, getString(R.string.repoNameErrorInvalid));
} }
else if (reservedRepoNames.contains(newRepoName)) { else if (reservedRepoNames.contains(newRepoName)) {
Toasty.warning(ctx, getString(R.string.repoNameErrorReservedName)); Toasty.info(ctx, getString(R.string.repoNameErrorReservedName));
} }
else if (reservedRepoPatterns.matcher(newRepoName).find()) { else if (reservedRepoPatterns.matcher(newRepoName).find()) {
Toasty.warning(ctx, getString(R.string.repoNameErrorReservedPatterns)); Toasty.info(ctx, getString(R.string.repoNameErrorReservedPatterns));
}
else if(selectedOwner == null) {
Toasty.error(ctx, getString(R.string.repoOwnerError));
} }
else { else {
disableProcessButton(); disableProcessButton();
createNewRepository(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, selectedOwner, newRepoAccess); createNewRepository(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess);
} }
} }
private void createNewRepository(final String instanceUrl, final String token, String loginUid, String repoName, String repoDesc, String selectedOwner, boolean isPrivate) { private void createNewRepository(final String instanceUrl, final String token, String loginUid, String repoName, String repoDesc, String repoOwner, boolean isPrivate) {
OrganizationRepository createRepository = new OrganizationRepository(true, repoDesc, null, null, repoName, isPrivate, "Default"); OrganizationRepository createRepository = new OrganizationRepository(true, repoDesc, null, null, repoName, isPrivate, "Default");
Call<OrganizationRepository> call; Call<OrganizationRepository> call;
if(selectedOwner.equals(loginUid)) { if(repoOwner.equals(loginUid)) {
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewUserRepository(token, createRepository); .createNewUserRepository(token, createRepository);
} }
else { else {
call = RetrofitClient call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
.createNewUserOrgRepository(token, selectedOwner, createRepository); .createNewUserOrgRepository(token, repoOwner, createRepository);
} }
call.enqueue(new Callback<OrganizationRepository>() { call.enqueue(new Callback<OrganizationRepository>() {
@ -190,7 +211,7 @@ public class CreateRepoActivity extends BaseActivity {
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("repoCreated", true); tinyDb.putBoolean("repoCreated", true);
Toasty.success(ctx, getString(R.string.repoCreated)); Toasty.info(ctx, getString(R.string.repoCreated));
enableProcessButton(); enableProcessButton();
finish(); finish();
} }
@ -201,23 +222,25 @@ public class CreateRepoActivity extends BaseActivity {
getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else if(response.code() == 409) { else if(response.code() == 409) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, getString(R.string.repoExistsError)); Toasty.info(ctx, getString(R.string.repoExistsError));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, getString(R.string.repoCreatedError)); Toasty.info(ctx, getString(R.string.repoCreatedError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<OrganizationRepository> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<OrganizationRepository> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
enableProcessButton(); enableProcessButton();
} }
@ -226,6 +249,8 @@ public class CreateRepoActivity extends BaseActivity {
private void getOrganizations(String instanceUrl, String instanceToken, final String userLogin) { private void getOrganizations(String instanceUrl, String instanceToken, final String userLogin) {
TinyDB tinyDb = new TinyDB(appCtx);
Call<List<OrgOwner>> call = RetrofitClient Call<List<OrgOwner>> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, ctx)
.getApiInterface() .getApiInterface()
@ -236,6 +261,7 @@ public class CreateRepoActivity extends BaseActivity {
@Override @Override
public void onResponse(@NonNull Call<List<OrgOwner>> call, @NonNull retrofit2.Response<List<OrgOwner>> response) { public void onResponse(@NonNull Call<List<OrgOwner>> call, @NonNull retrofit2.Response<List<OrgOwner>> response) {
if(response.isSuccessful()) {
if(response.code() == 200) { if(response.code() == 200) {
int organizationId = 0; int organizationId = 0;
@ -245,54 +271,50 @@ public class CreateRepoActivity extends BaseActivity {
organizationsList.add(new OrgOwner(userLogin)); organizationsList.add(new OrgOwner(userLogin));
assert organizationsList_ != null; assert organizationsList_ != null;
if(organizationsList_.size() > 0) { if(organizationsList_.size() > 0) {
for (int i = 0; i < organizationsList_.size(); i++) {
for(int i = 0; i < organizationsList_.size(); i++) {
if(!tinyDb.getString("organizationId").isEmpty()) { if(!tinyDb.getString("organizationId").isEmpty()) {
if (Integer.parseInt(tinyDb.getString("organizationId")) == organizationsList_.get(i).getId()) {
if(Integer.parseInt(tinyDb.getString("organizationId")) == organizationsList_.get(i).getId()) {
organizationId = i + 1; organizationId = i + 1;
} }
} }
OrgOwner data = new OrgOwner(
OrgOwner data = new OrgOwner(organizationsList_.get(i).getUsername()); organizationsList_.get(i).getUsername()
);
organizationsList.add(data); organizationsList.add(data);
} }
} }
ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(CreateRepoActivity.this, R.layout.list_spinner_items, organizationsList); ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(CreateRepoActivity.this,
R.layout.spinner_item, organizationsList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
spinner.setAdapter(adapter); spinner.setAdapter(adapter);
spinner.setOnItemClickListener ((parent, view, position, id) -> selectedOwner = organizationsList.get(position).getUsername()); if (tinyDb.getBoolean("organizationAction") & organizationId != 0) {
spinner.setSelection(organizationId);
if(tinyDb.getBoolean("organizationAction") & organizationId != 0) {
int selectOwnerById = organizationId;
new Handler(Looper.getMainLooper()).postDelayed(() -> {
spinner.setText(organizationsList.get(selectOwnerById).getUsername(), false);
selectedOwner = organizationsList.get(selectOwnerById).getUsername();
}, 500);
tinyDb.putBoolean("organizationAction", false); tinyDb.putBoolean("organizationAction", false);
} }
enableProcessButton(); enableProcessButton();
}
}
}
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), AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<List<OrgOwner>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<OrgOwner>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
enableProcessButton(); enableProcessButton();
} }
@ -300,18 +322,32 @@ public class CreateRepoActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
private void disableProcessButton() { private void disableProcessButton() {
createRepo.setEnabled(false); createRepo.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
createRepo.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
createRepo.setEnabled(true); createRepo.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
createRepo.setBackground(shape);
} }
} }

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
@ -97,7 +98,9 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
teamPermission.setOnClickListener(view -> { teamPermission.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx);
@ -108,44 +111,44 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
else { else {
pBuilder.setCancelable(false); pBuilder.setCancelable(false);
} }
pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, (dialogInterface, i) -> { pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
permissionSelectedChoice = i; permissionSelectedChoice = i;
teamPermission.setText(permissionList[i]); teamPermission.setText(permissionList[i]);
switch(permissionList[i]) { if(permissionList[i].equals("Read")) {
case "Read":
teamPermissionDetail.setVisibility(View.VISIBLE); teamPermissionDetail.setVisibility(View.VISIBLE);
teamPermissionDetail.setText(R.string.newTeamPermissionRead); teamPermissionDetail.setText(R.string.newTeamPermissionRead);
break; }
case "Write": else if(permissionList[i].equals("Write")) {
teamPermissionDetail.setVisibility(View.VISIBLE); teamPermissionDetail.setVisibility(View.VISIBLE);
teamPermissionDetail.setText(R.string.newTeamPermissionWrite); teamPermissionDetail.setText(R.string.newTeamPermissionWrite);
break; }
case "Admin": else if(permissionList[i].equals("Admin")) {
teamPermissionDetail.setVisibility(View.VISIBLE); teamPermissionDetail.setVisibility(View.VISIBLE);
teamPermissionDetail.setText(R.string.newTeamPermissionAdmin); teamPermissionDetail.setText(R.string.newTeamPermissionAdmin);
break; }
default: else {
teamPermissionDetail.setVisibility(View.GONE); teamPermissionDetail.setVisibility(View.GONE);
break;
} }
dialogInterface.dismiss(); dialogInterface.dismiss();
}
}); });
AlertDialog pDialog = pBuilder.create(); AlertDialog pDialog = pBuilder.create();
pDialog.show(); pDialog.show();
}
}); });
teamAccessControls.setOnClickListener(v -> { teamAccessControls.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
teamAccessControls.setText(""); teamAccessControls.setText("");
teamAccessControlsArray.setText(""); teamAccessControlsArray.setText("");
@ -153,12 +156,20 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(ctx); AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(ctx);
aDialogBuilder.setMultiChoiceItems(accessControlsList, selectedAccessControlsTrueFalse, (dialog, which, isChecked) -> { aDialogBuilder.setMultiChoiceItems(accessControlsList, selectedAccessControlsTrueFalse, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
}
}) })
.setCancelable(false) .setCancelable(false)
.setTitle(R.string.newTeamAccessControls) .setTitle(R.string.newTeamAccessControls)
.setPositiveButton(R.string.okButton, (dialog, which) -> { .setPositiveButton(R.string.okButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int selectedVal = 0; int selectedVal = 0;
while(selectedVal < selectedAccessControlsTrueFalse.length) while(selectedVal < selectedAccessControlsTrueFalse.length)
@ -207,10 +218,14 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
} }
//Log.i("orgName", String.valueOf(teamAccessControlsArray.getText())); //Log.i("orgName", String.valueOf(teamAccessControlsArray.getText()));
}
}); });
AlertDialog aDialog = aDialogBuilder.create(); AlertDialog aDialog = aDialogBuilder.create();
aDialog.show(); aDialog.show();
}
}); });
createTeamButton.setEnabled(false); createTeamButton.setEnabled(false);
@ -249,21 +264,21 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (newTeamName.equals("")) { if (newTeamName.equals("")) {
Toasty.error(ctx, getString(R.string.teamNameEmpty)); Toasty.info(ctx, getString(R.string.teamNameEmpty));
return; return;
} }
if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) { if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
Toasty.warning(ctx, getString(R.string.teamNameError)); Toasty.info(ctx, getString(R.string.teamNameError));
return; return;
} }
@ -271,12 +286,12 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if(!newTeamDesc.equals("")) { if(!newTeamDesc.equals("")) {
if(!appUtil.checkStrings(newTeamDesc)) { if(!appUtil.checkStrings(newTeamDesc)) {
Toasty.warning(ctx, getString(R.string.teamDescError)); Toasty.info(ctx, getString(R.string.teamDescError));
return; return;
} }
if(newTeamDesc.length() > 100) { if(newTeamDesc.length() > 100) {
Toasty.warning(ctx, getString(R.string.teamDescLimit)); Toasty.info(ctx, getString(R.string.teamDescLimit));
return; return;
} }
@ -284,7 +299,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if (newTeamPermission.equals("")) { if (newTeamPermission.equals("")) {
Toasty.error(ctx, getString(R.string.teamPermissionEmpty)); Toasty.info(ctx, getString(R.string.teamPermissionEmpty));
return; return;
} }
@ -321,14 +336,16 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("resumeTeams", true); tinyDb.putBoolean("resumeTeams", true);
Toasty.success(ctx, getString(R.string.teamCreated)); Toasty.info(ctx, getString(R.string.teamCreated));
finish(); finish();
} }
} }
else if(response2.code() == 404) { else if(response2.code() == 404) {
Toasty.warning(ctx, getString(R.string.apiNotFound)); Toasty.info(ctx, getString(R.string.apiNotFound));
} }
else if(response2.code() == 401) { else if(response2.code() == 401) {
@ -336,10 +353,12 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else { else {
Toasty.error(ctx, getString(R.string.teamCreatedError)); Toasty.info(ctx, getString(R.string.teamCreatedError));
} }
} }
@ -354,15 +373,19 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if(v == createTeamButton) { if(v == createTeamButton) {
processCreateTeam(); processCreateTeam();
} }
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
} }

View File

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

View File

@ -1,486 +0,0 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.databinding.ActivityDeeplinksBinding;
import org.mian.gitnex.helpers.PathsHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.UrlHelper;
import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.PullRequests;
import org.mian.gitnex.models.UserRepositories;
import java.net.URI;
import java.util.List;
import java.util.Objects;
import io.mikael.urlbuilder.UrlBuilder;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class DeepLinksActivity extends BaseActivity {
private ActivityDeeplinksBinding viewBinding;
private Context ctx = this;
private Context appCtx;
private TinyDB tinyDb;
private String currentInstance;
private String instanceToken;
private Intent mainIntent;
private Intent issueIntent;
private Intent repoIntent;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_deeplinks;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
viewBinding = ActivityDeeplinksBinding.inflate(getLayoutInflater());
View view = viewBinding.getRoot();
setContentView(view);
mainIntent = new Intent(ctx, MainActivity.class);
issueIntent = new Intent(ctx, IssueDetailActivity.class);
repoIntent = new Intent(ctx, RepoDetailActivity.class);
Intent intent = getIntent();
Uri data = intent.getData();
assert data != null;
// check for login
if(!tinyDb.getBoolean("loggedInMode")) {
finish();
ctx.startActivity(new Intent(ctx, LoginActivity.class));
}
// check for the links(URI) to be in the db
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
List<UserAccount> userAccounts = userAccountsApi.usersAccounts();
if(userAccounts.size() > 0) {
String hostUri;
for(int i = 0; i < userAccounts.size(); i++) {
hostUri = userAccounts.get(i).getInstanceUrl();
currentInstance = userAccounts.get(i).getInstanceUrl();
instanceToken = userAccounts.get(i).getToken();
if(!hostUri.contains(Objects.requireNonNull(data.getHost()))) {
// check for valid instance
checkInstance(data);
return;
}
}
}
// redirect to proper fragment/activity, If no action is there, show options where user to want to go like repos, profile, notifications etc
if(data.getPathSegments().size() > 0) {
viewBinding.progressBar.setVisibility(View.GONE);
String[] restOfUrl = Objects.requireNonNull(data.getPath()).split("/");
if(data.getPathSegments().contains("issues")) { // issue
if(!Objects.requireNonNull(data.getLastPathSegment()).contains("issues") & StringUtils.isNumeric(data.getLastPathSegment())) {
issueIntent.putExtra("issueNumber", data.getLastPathSegment());
tinyDb.putString("issueNumber", data.getLastPathSegment());
tinyDb.putString("issueType", "Issue");
tinyDb.putString("repoFullName", restOfUrl[restOfUrl.length - 4] + "/" + restOfUrl[restOfUrl.length - 3]);
final String repoOwner = restOfUrl[restOfUrl.length - 4];
final String repoName = restOfUrl[restOfUrl.length - 3];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(ctx);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository dataRepo = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", dataRepo.getRepositoryId());
}
ctx.startActivity(issueIntent);
finish();
}
else if(Objects.requireNonNull(data.getLastPathSegment()).contains("issues")) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 3], restOfUrl[restOfUrl.length - 2], "issue");
}, 500);
}
else {
ctx.startActivity(mainIntent);
finish();
}
}
else if(data.getPathSegments().contains("pulls")) { // pr
if(!Objects.requireNonNull(data.getLastPathSegment()).contains("pulls") & StringUtils.isNumeric(data.getLastPathSegment())) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
getPullRequest(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 4], restOfUrl[restOfUrl.length - 3],
Integer.parseInt(data.getLastPathSegment()));
}, 500);
}
else if(Objects.requireNonNull(data.getLastPathSegment()).contains("pulls")) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 3], restOfUrl[restOfUrl.length - 2], "pull");
}, 500);
}
else {
ctx.startActivity(mainIntent);
finish();
}
}
else if(!restOfUrl[restOfUrl.length - 2].equals("") & !restOfUrl[restOfUrl.length - 1].equals("")) { // go to repo
new Handler(Looper.getMainLooper()).postDelayed(() -> {
goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 2], restOfUrl[restOfUrl.length - 1], "repo");
}, 500);
}
else { // no action, show options
if(tinyDb.getInt("defaultScreenId") == 1) { // repos
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDb.getInt("defaultScreenId") == 2) { // org
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDb.getInt("defaultScreenId") == 3) { // notifications
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDb.getInt("defaultScreenId") == 4) { // explore
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
}
else if(tinyDb.getInt("defaultScreenId") == 0) { // show options
viewBinding.noActionFrame.setVisibility(View.VISIBLE);
viewBinding.addNewAccountFrame.setVisibility(View.GONE);
viewBinding.repository.setOnClickListener(repository -> {
tinyDb.putInt("defaultScreenId", 1);
tinyDb.putString("defaultScreenStr", getResources().getString(R.string.navRepos));
mainIntent.putExtra("launchFragmentByLinkHandler", "repos");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.organization.setOnClickListener(organization -> {
tinyDb.putInt("defaultScreenId", 2);
tinyDb.putString("defaultScreenStr", getResources().getString(R.string.navOrgs));
mainIntent.putExtra("launchFragmentByLinkHandler", "org");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.notification.setOnClickListener(notification -> {
tinyDb.putInt("defaultScreenId", 3);
tinyDb.putString("defaultScreenStr", getResources().getString(R.string.pageTitleNotifications));
mainIntent.putExtra("launchFragmentByLinkHandler", "notification");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.explore.setOnClickListener(explore -> {
tinyDb.putInt("defaultScreenId", 4);
tinyDb.putString("defaultScreenStr", getResources().getString(R.string.navExplore));
mainIntent.putExtra("launchFragmentByLinkHandler", "explore");
ctx.startActivity(mainIntent);
finish();
});
viewBinding.launchApp2.setOnClickListener(launchApp2 -> {
tinyDb.putInt("defaultScreenId", 0);
tinyDb.putString("defaultScreenStr", getResources().getString(R.string.generalDeepLinkSelectedText));
ctx.startActivity(mainIntent);
finish();
});
}
}
}
else {
ctx.startActivity(mainIntent);
finish();
}
}
private void checkInstance(Uri data) {
URI host;
if(data.getPort() > 0) {
host = UrlBuilder.fromString(UrlHelper.fixScheme(data.getHost(), "https")).withPort(data.getPort()).toUri();
}
else {
host = UrlBuilder.fromString(UrlHelper.fixScheme(data.getHost(), "https")).toUri();
}
URI instanceUrl = UrlBuilder.fromUri(host).withScheme(data.getScheme().toLowerCase()).withPath(PathsHelper.join(host.getPath(), "/api/v1/"))
.toUri();
Call<GiteaVersion> callVersion;
callVersion = RetrofitClient.getInstance(String.valueOf(instanceUrl), ctx).getApiInterface().getGiteaVersion();
callVersion.enqueue(new Callback<GiteaVersion>() {
@Override
public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) {
if(responseVersion.isSuccessful() || responseVersion.code() == 403) {
viewBinding.progressBar.setVisibility(View.GONE);
viewBinding.addNewAccountFrame.setVisibility(View.VISIBLE);
viewBinding.noActionFrame.setVisibility(View.GONE);
viewBinding.addAccountText.setText(String.format(getResources().getString(R.string.accountDoesNotExist), data.getHost()));
viewBinding.addNewAccount.setOnClickListener(addNewAccount -> {
Intent accountIntent = new Intent(ctx, AddNewAccountActivity.class);
startActivity(accountIntent);
finish();
});
viewBinding.openInBrowser.setOnClickListener(addNewAccount -> {
Intent intentBrowser = new Intent();
intentBrowser.setAction(Intent.ACTION_VIEW);
intentBrowser.addCategory(Intent.CATEGORY_BROWSABLE);
intentBrowser.setData(Uri.parse(String.valueOf(host)));
startActivity(intentBrowser);
finish();
});
viewBinding.launchApp.setOnClickListener(launchApp -> {
startActivity(mainIntent);
finish();
});
}
}
@Override
public void onFailure(@NonNull Call<GiteaVersion> callVersion, @NonNull Throwable t) {
Toasty.error(ctx, getResources().getString(R.string.versionUnknown));
finish();
}
});
}
private void getPullRequest(String url, String token, String repoOwner, String repoName, int index) {
Call<PullRequests> call = RetrofitClient
.getInstance(url, ctx)
.getApiInterface()
.getPullRequestByIndex(token, repoOwner, repoName, index);
call.enqueue(new Callback<PullRequests>() {
@Override
public void onResponse(@NonNull Call<PullRequests> call, @NonNull retrofit2.Response<PullRequests> response) {
PullRequests prInfo = response.body();
if (response.code() == 200) {
assert prInfo != null;
issueIntent.putExtra("issueNumber", index);
issueIntent.putExtra("prMergeable", prInfo.isMergeable());
if(prInfo.getHead() != null) {
issueIntent.putExtra("prHeadBranch", prInfo.getHead().getRef());
tinyDb.putString("prHeadBranch", prInfo.getHead().getRef());
if(prInfo.getHead().getRepo() != null) {
tinyDb.putString("prIsFork", String.valueOf(prInfo.getHead().getRepo().isFork()));
tinyDb.putString("prForkFullName", prInfo.getHead().getRepo().getFull_name());
}
else {
// pull was done from a deleted fork
tinyDb.putString("prIsFork", "true");
tinyDb.putString("prForkFullName", ctx.getString(R.string.prDeletedFrok));
}
}
tinyDb.putString("issueNumber", String.valueOf(index));
tinyDb.putString("prMergeable", String.valueOf(prInfo.isMergeable()));
tinyDb.putString("issueType", "Pull");
tinyDb.putString("repoFullName", repoOwner + "/" + repoName);
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(ctx);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository dataRepo = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", dataRepo.getRepositoryId());
}
ctx.startActivity(issueIntent);
finish();
}
else {
Log.e("onFailure-links-pr", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<PullRequests> call, @NonNull Throwable t) {
Log.e("onFailure-links-pr", t.toString());
}
});
}
private void goToRepoSection(String url, String token, String repoOwner, String repoName, String type) {
Call<UserRepositories> call = RetrofitClient
.getInstance(url, ctx)
.getApiInterface()
.getUserRepository(token, repoOwner, repoName);
call.enqueue(new Callback<UserRepositories>() {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
UserRepositories repoInfo = response.body();
if (response.code() == 200) {
assert repoInfo != null;
repoIntent.putExtra("repoFullName", repoInfo.getFullName());
repoIntent.putExtra("goToSection", "yes");
repoIntent.putExtra("goToSectionType", type);
tinyDb.putString("repoFullName", repoInfo.getFullName());
if(repoInfo.getPrivateFlag()) {
tinyDb.putString("repoType", getResources().getString(R.string.strPrivate));
}
else {
tinyDb.putString("repoType", getResources().getString(R.string.strPublic));
}
tinyDb.putBoolean("isRepoAdmin", repoInfo.getPermissions().isAdmin());
tinyDb.putString("repoBranch", repoInfo.getDefault_branch());
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(ctx);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
ctx.startActivity(repoIntent);
finish();
}
else {
Log.e("onFailure-links", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Log.e("onFailure-links", t.toString());
}
});
}
}

View File

@ -3,20 +3,24 @@ package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.content.Context; import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText; 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 androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
@ -26,6 +30,7 @@ import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.Milestones;
@ -36,6 +41,7 @@ import java.util.Calendar;
import java.util.List; import java.util.List;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -45,27 +51,19 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private TinyDB tinyDb;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
private EditText editIssueTitle; private EditText editIssueTitle;
private EditText editIssueDescription; private SocialAutoCompleteTextView editIssueDescription;
private TextView editIssueDueDate; private TextView editIssueDueDate;
private Button editIssueButton; private Button editIssueButton;
private AutoCompleteTextView editIssueMilestoneSpinner; private Spinner editIssueMilestoneSpinner;
private String msState = "open"; private String msState = "open";
private int milestoneId;
List<Milestones> milestonesList = new ArrayList<>(); List<Milestones> milestonesList = new ArrayList<>();
private ArrayAdapter<Mention> defaultMentionAdapter;
private String instanceUrl;
private String loginUid;
private String instanceToken;
private String repoOwner;
private String repoName;
private int issueIndex;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -77,18 +75,19 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
instanceUrl = tinyDb.getString("instanceUrl"); final TinyDB tinyDb = new TinyDB(appCtx);
loginUid = tinyDb.getString("loginUid");
instanceToken = "token " + tinyDb.getString(loginUid + "-token"); 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 repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
repoOwner = parts[0]; final String repoOwner = parts[0];
repoName = parts[1]; final String repoName = parts[1];
issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
editIssueButton = findViewById(R.id.editIssueButton); editIssueButton = findViewById(R.id.editIssueButton);
@ -106,7 +105,13 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
assert imm != null; assert imm != null;
imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT); imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT);
defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList();
editIssueMilestoneSpinner = findViewById(R.id.editIssueMilestoneSpinner); editIssueMilestoneSpinner = findViewById(R.id.editIssueMilestoneSpinner);
editIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
editIssueDescription.setMentionAdapter(defaultMentionAdapter);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -126,16 +131,85 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
disableProcessButton(); disableProcessButton();
getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit); getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit);
}
public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
if (response.isSuccessful()) {
assert response.body() != null;
String fullName = "";
for (int i = 0; i < response.body().size(); i++) {
if(!response.body().get(i).getFull_name().equals("")) {
fullName = response.body().get(i).getFull_name();
}
defaultMentionAdapter.add(
new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
}
} else {
Log.i("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.toString());
}
});
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
private void processEditIssue() { private void processEditIssue() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
Milestones mModel = (Milestones) editIssueMilestoneSpinner.getSelectedItem();
int editIssueMilestoneId = mModel.getId();
String editIssueTitleForm = editIssueTitle.getText().toString(); String editIssueTitleForm = editIssueTitle.getText().toString();
String editIssueDescriptionForm = editIssueDescription.getText().toString(); String editIssueDescriptionForm = editIssueDescription.getText().toString();
@ -143,32 +217,42 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if (editIssueTitleForm.equals("")) { if (editIssueTitleForm.equals("")) {
Toasty.error(ctx, getString(R.string.issueTitleEmpty)); Toasty.info(ctx, getString(R.string.issueTitleEmpty));
return; return;
} }
/*if (editIssueDescriptionForm.equals("")) {
Toasty.info(ctx, getString(R.string.issueDescriptionEmpty));
return;
}*/
if (editIssueDueDateForm.equals("")) { if (editIssueDueDateForm.equals("")) {
editIssueDueDateForm = null; editIssueDueDateForm = null;
} else { } else {
editIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(editIssueDueDateForm))); editIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(editIssueDueDateForm)));
} }
//Log.i("editIssueDueDateForm", String.valueOf(editIssueDueDateForm));
disableProcessButton(); disableProcessButton();
editIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid, editIssueTitleForm, editIssueDescriptionForm, editIssueDueDateForm, milestoneId); editIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid, editIssueTitleForm, editIssueDescriptionForm, editIssueDueDateForm, editIssueMilestoneId);
} }
private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int milestoneId) { private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int editIssueMilestoneId) {
CreateIssue issueData = new CreateIssue(title, description, dueDate, milestoneId); final TinyDB tinyDb = new TinyDB(appCtx);
CreateIssue issueData = new CreateIssue(title, description, dueDate, editIssueMilestoneId);
Call<JsonElement> call = RetrofitClient Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx) .getInstance(instanceUrl, ctx)
@ -183,12 +267,10 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if(response.code() == 201) { if(response.code() == 201) {
if(tinyDb.getString("issueType").equalsIgnoreCase("Pull")) { if(tinyDb.getString("issueType").equalsIgnoreCase("Pull")) {
Toasty.info(ctx, getString(R.string.editPrSuccessMessage));
Toasty.success(ctx, getString(R.string.editPrSuccessMessage));
} }
else { else {
Toasty.info(ctx, getString(R.string.editIssueSuccessMessage));
Toasty.success(ctx, getString(R.string.editIssueSuccessMessage));
} }
tinyDb.putBoolean("issueEdited", true); tinyDb.putBoolean("issueEdited", true);
@ -208,7 +290,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }
@ -223,6 +305,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -234,7 +317,16 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
final int mDay = c.get(Calendar.DAY_OF_MONTH); final int mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(this, DatePickerDialog datePickerDialog = new DatePickerDialog(this,
(view, year, monthOfYear, dayOfMonth) -> editIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay); new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
editIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth));
}
}, mYear, mMonth, mDay);
datePickerDialog.show(); datePickerDialog.show();
} }
@ -262,10 +354,9 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
editIssueTitle.setText(response.body().getTitle()); editIssueTitle.setText(response.body().getTitle());
editIssueDescription.setText(response.body().getBody()); editIssueDescription.setText(response.body().getBody());
int currentMilestoneId = 0; int msId = 0;
if(response.body().getMilestone() != null) { if(response.body().getMilestone() != null) {
msId = response.body().getMilestone().getId();
currentMilestoneId = response.body().getMilestone().getId();
} }
// get milestones list // get milestones list
@ -276,14 +367,14 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
.getApiInterface() .getApiInterface()
.getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState); .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState);
int checkMilestoneId = currentMilestoneId; final int finalMsId = msId;
call_.enqueue(new Callback<List<Milestones>>() { call_.enqueue(new Callback<List<Milestones>>() {
@Override @Override
public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull retrofit2.Response<List<Milestones>> response_) { public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull retrofit2.Response<List<Milestones>> response_) {
int getSelectedMilestoneId = 0; int finalMsId1 = 0;
if (response_.code() == 200) { if (response_.code() == 200) {
@ -291,33 +382,31 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
milestonesList.add(new Milestones(0, "No milestone")); milestonesList.add(new Milestones(0, "No milestone"));
assert milestonesList_ != null; assert milestonesList_ != null;
if (milestonesList_.size() > 0) { if (milestonesList_.size() > 0) {
milestonesList.addAll(milestonesList_);
for (int i = 0; i < milestonesList_.size(); i++) { for (int i = 0; i < milestonesList_.size(); i++) {
if(checkMilestoneId == milestonesList_.get(i).getId()) { Milestones data = new Milestones(
getSelectedMilestoneId = i + 1; milestonesList_.get(i).getId(),
} milestonesList_.get(i).getTitle()
} );
milestonesList.add(data);
if(finalMsId == milestonesList_.get(i).getId()) {
finalMsId1 = i + 1;
} }
ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(EditIssueActivity.this, }
R.layout.list_spinner_items, milestonesList); }
editIssueMilestoneSpinner.setAdapter(adapter); ArrayAdapter<Milestones> adapter_ = new ArrayAdapter<>(EditIssueActivity.this,
R.layout.spinner_item, milestonesList);
editIssueMilestoneSpinner.setOnItemClickListener ((parent, view, position, id) -> milestoneId = milestonesList.get(position).getId()); adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item);
editIssueMilestoneSpinner.setAdapter(adapter_);
int finalMsId = getSelectedMilestoneId;
new Handler(Looper.getMainLooper()).postDelayed(() -> {
editIssueMilestoneSpinner.setText(milestonesList.get(finalMsId).getTitle(),false);
milestoneId = milestonesList.get(finalMsId).getId();
}, 500);
if(milestonesList_.size() > 0) {
editIssueMilestoneSpinner.setSelection(finalMsId1);
}
enableProcessButton(); enableProcessButton();
} }
@ -326,7 +415,6 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
@Override @Override
public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
@ -339,6 +427,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
@SuppressLint("SimpleDateFormat") DateFormat formatter = new SimpleDateFormat("yyyy-M-dd"); @SuppressLint("SimpleDateFormat") DateFormat formatter = new SimpleDateFormat("yyyy-M-dd");
String dueDate = formatter.format(response.body().getDue_date()); String dueDate = formatter.format(response.body().getDue_date());
editIssueDueDate.setText(dueDate); editIssueDueDate.setText(dueDate);
} }
//enableProcessButton(); //enableProcessButton();
@ -349,17 +438,18 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else { else {
Toasty.error(ctx, getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
} }
}); });
@ -369,11 +459,21 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
private void disableProcessButton() { private void disableProcessButton() {
editIssueButton.setEnabled(false); editIssueButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
editIssueButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
editIssueButton.setEnabled(true); editIssueButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
editIssueButton.setBackground(shape);
} }
} }

View File

@ -82,9 +82,8 @@ public class FileDiffActivity extends BaseActivity {
// fallback for old gitea instances // fallback for old gitea instances
if(new Version(tinyDb.getString("giteaVersion")).less("1.13.0")) { if(new Version(tinyDb.getString("giteaVersion")).less("1.13.0")) {
apiCall = false; apiCall = false;
instanceUrl = instanceUrl.substring(0, instanceUrl.lastIndexOf("api/v1/")); instanceUrl = tinyDb.getString("instanceUrlWithProtocol");
} }
getPullDiffContent(instanceUrl, repoOwner, repoName, pullIndex, instanceToken, apiCall); getPullDiffContent(instanceUrl, repoOwner, repoName, pullIndex, instanceToken, apiCall);
@ -122,7 +121,7 @@ public class FileDiffActivity extends BaseActivity {
toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount))); toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount)));
} }
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, getSupportFragmentManager(), fileContentsArray); FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, fileContentsArray);
mListView.setAdapter(adapter); mListView.setAdapter(adapter);
mProgressBar.setVisibility(View.GONE); mProgressBar.setVisibility(View.GONE);
@ -140,17 +139,17 @@ public class FileDiffActivity extends BaseActivity {
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(ctx, getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }
@ -167,10 +166,14 @@ public class FileDiffActivity extends BaseActivity {
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> { onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
getIntent().removeExtra("singleFileName"); getIntent().removeExtra("singleFileName");
finish(); finish();
}
}; };
} }

View File

@ -8,7 +8,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.text.Spanned;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
@ -43,24 +42,7 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects; import java.util.Objects;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.CorePlugin;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.DefaultMediaDecoder;
import io.noties.markwon.image.ImageItem;
import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.image.SchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.linkify.LinkifyPlugin;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -83,10 +65,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
private LinearLayout pdfViewFrame; private LinearLayout pdfViewFrame;
private byte[] decodedPdf; private byte[] decodedPdf;
private Boolean pdfNightMode; private Boolean pdfNightMode;
private String singleFileName;
private String fileSha;
private AppUtil appUtil;
private TinyDB tinyDb;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId() {
@ -99,12 +77,11 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
appUtil = new AppUtil();
tinyDb = new TinyDB(appCtx);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
final TinyDB tinyDb = new TinyDB(appCtx);
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String repoBranch = tinyDb.getString("repoBranch"); String repoBranch = tinyDb.getString("repoBranch");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
@ -114,8 +91,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
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");
tinyDb.putBoolean("enableMarkdownInFileView", false);
ImageView closeActivity = findViewById(R.id.close); ImageView closeActivity = findViewById(R.id.close);
singleFileContents = findViewById(R.id.singleFileContents); singleFileContents = findViewById(R.id.singleFileContents);
singleCodeContents = findViewById(R.id.singleCodeContents); singleCodeContents = findViewById(R.id.singleCodeContents);
@ -125,7 +100,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
pdfViewFrame = findViewById(R.id.pdfViewFrame); pdfViewFrame = findViewById(R.id.pdfViewFrame);
singleFileContentsFrame = findViewById(R.id.singleFileContentsFrame); singleFileContentsFrame = findViewById(R.id.singleFileContentsFrame);
singleFileName = getIntent().getStringExtra("singleFileName"); String singleFileName = getIntent().getStringExtra("singleFileName");
TextView toolbar_title = findViewById(R.id.toolbar_title); TextView toolbar_title = findViewById(R.id.toolbar_title);
toolbar_title.setMovementMethod(new ScrollingMovementMethod()); toolbar_title.setMovementMethod(new ScrollingMovementMethod());
@ -144,6 +119,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
catch(UnsupportedEncodingException e) { catch(UnsupportedEncodingException e) {
assert singleFileName != null;
Log.i("singleFileName", singleFileName); Log.i("singleFileName", singleFileName);
} }
@ -154,29 +130,10 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
@Override
public void onResume() {
super.onResume();
String repoFullName = tinyDb.getString("repoFullName");
String repoBranch = tinyDb.getString("repoBranch");
String[] parts = repoFullName.split("/");
String repoOwner = parts[0];
String repoName = parts[1];
String instanceUrl = tinyDb.getString("instanceUrl");
String loginUid = tinyDb.getString("loginUid");
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getBoolean("fileModified")) {
getSingleFileContents(instanceUrl, instanceToken, repoOwner, repoName, singleFileName, repoBranch);
tinyDb.putBoolean("fileModified", false);
}
}
private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename, String ref) { private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename, String ref) {
final TinyDB tinyDb = new TinyDB(appCtx);
Call<Files> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getSingleFileContents(token, owner, repo, filename, ref); Call<Files> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getSingleFileContents(token, owner, repo, filename, ref);
call.enqueue(new Callback<Files>() { call.enqueue(new Callback<Files>() {
@ -186,6 +143,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if(response.code() == 200) { if(response.code() == 200) {
AppUtil appUtil = new AppUtil();
assert response.body() != null; assert response.body() != null;
if(!response.body().getContent().equals("")) { if(!response.body().getContent().equals("")) {
@ -193,8 +151,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
String fileExtension = FileUtils.getExtension(filename); String fileExtension = FileUtils.getExtension(filename);
mProgressBar.setVisibility(View.GONE); mProgressBar.setVisibility(View.GONE);
fileSha = response.body().getSha();
// download file meta // download file meta
tinyDb.putString("downloadFileName", filename); tinyDb.putString("downloadFileName", filename);
tinyDb.putString("downloadFileContents", response.body().getContent()); tinyDb.putString("downloadFileContents", response.body().getContent());
@ -291,17 +247,17 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(ctx, getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }
@ -321,13 +277,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.generic_nav_dotted_menu, menu); inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
inflater.inflate(R.menu.files_view_menu, menu);
String fileExtension = FileUtils.getExtension(singleFileName);
if(!fileExtension.equalsIgnoreCase("md")) {
menu.getItem(0).setVisible(false);
}
return true; return true;
} }
@ -338,82 +287,11 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
switch(id) { switch(id) {
case android.R.id.home: case android.R.id.home:
finish(); finish();
return true; return true;
case R.id.genericMenu: case R.id.genericMenu:
BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment(); BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment();
bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet"); bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet");
return true;
case R.id.markdown:
final Markwon markwon = Markwon.builder(Objects.requireNonNull(ctx)).usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> {
plugin.addSchemeHandler(new SchemeHandler() {
@NonNull
@Override
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
final int resourceId = ctx.getResources().getIdentifier(
raw.substring("drawable://".length()),
"drawable",
ctx.getPackageName());
final Drawable drawable = ctx.getDrawable(resourceId);
assert drawable != null;
return ImageItem.withResult(drawable);
}
@NonNull
@Override
public Collection<String> supportedSchemes() {
return Collections.singleton("drawable");
}
});
plugin.placeholderProvider(drawable -> null);
plugin.addMediaDecoder(GifMediaDecoder.create(false));
plugin.addMediaDecoder(SvgMediaDecoder.create(ctx.getResources()));
plugin.addMediaDecoder(SvgMediaDecoder.create());
plugin.defaultMediaDecoder(DefaultMediaDecoder.create(ctx.getResources()));
plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
}))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder.codeTextColor(tinyDb.getInt("codeBlockColor")).codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
.linkColor(getResources().getColor(R.color.lightBlue));
}
})
.usePlugin(TablePlugin.create(ctx))
.usePlugin(TaskListPlugin.create(ctx))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create())
.usePlugin(LinkifyPlugin.create())
.build();
if(!tinyDb.getBoolean("enableMarkdownInFileView")) {
singleCodeContents.setVisibility(View.GONE);
singleFileContentsFrame.setVisibility(View.VISIBLE);
singleFileContents.setVisibility(View.VISIBLE);
Spanned bodyWithMD = markwon.toMarkdown(appUtil.decodeBase64(tinyDb.getString("downloadFileContents")));
markwon.setParsedMarkdown(singleFileContents, bodyWithMD);
tinyDb.putBoolean("enableMarkdownInFileView", true);
}
else {
singleCodeContents.setVisibility(View.VISIBLE);
singleFileContentsFrame.setVisibility(View.GONE);
singleFileContents.setVisibility(View.GONE);
singleCodeContents.setSource(appUtil.decodeBase64(tinyDb.getString("downloadFileContents")));
tinyDb.putBoolean("enableMarkdownInFileView", false);
}
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@ -427,48 +305,15 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
if("downloadFile".equals(text)) { if("downloadFile".equals(text)) {
requestFileDownload(); requestFileDownload();
}
if("deleteFile".equals(text)) {
String fileExtension = FileUtils.getExtension(singleFileName);
String data = appUtil.decodeBase64(tinyDb.getString("downloadFileContents"));
Intent intent = new Intent(ctx, CreateFileActivity.class);
intent.putExtra("fileAction", 1);
intent.putExtra("filePath", singleFileName);
intent.putExtra("fileSha", fileSha);
if(!appUtil.imageExtension(fileExtension)) {
intent.putExtra("fileContents", data);
}
else {
intent.putExtra("fileContents", "");
}
ctx.startActivity(intent);
}
if("editFile".equals(text)) {
String fileExtension = FileUtils.getExtension(singleFileName);
String data = appUtil.decodeBase64(tinyDb.getString("downloadFileContents"));
Intent intent = new Intent(ctx, CreateFileActivity.class);
intent.putExtra("fileAction", 2);
intent.putExtra("filePath", singleFileName);
intent.putExtra("fileSha", fileSha);
if(!appUtil.imageExtension(fileExtension)) {
intent.putExtra("fileContents", data);
}
else {
intent.putExtra("fileContents", "");
}
ctx.startActivity(intent);
} }
} }
private void requestFileDownload() { private void requestFileDownload() {
final TinyDB tinyDb = new TinyDB(appCtx);
if(!tinyDb.getString("downloadFileContents").isEmpty()) { if(!tinyDb.getString("downloadFileContents").isEmpty()) {
int CREATE_REQUEST_CODE = 40; int CREATE_REQUEST_CODE = 40;
@ -485,8 +330,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
} }
else { else {
Toasty.error(ctx, getString(R.string.waitLoadingDownloadFile));
Toasty.warning(ctx, getString(R.string.waitLoadingDownloadFile));
} }
} }
@ -496,7 +340,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 40 && resultCode == RESULT_OK) { final TinyDB tinyDb = new TinyDB(appCtx);
if (requestCode == 40 && resultCode == RESULT_OK) {
try { try {
@ -512,11 +358,10 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
outputStream.write(dataAsBytes); outputStream.write(dataAsBytes);
outputStream.close(); outputStream.close();
Toasty.success(ctx, getString(R.string.downloadFileSaved)); Toasty.info(ctx, getString(R.string.downloadFileSaved));
} }
catch(IOException e) { catch (IOException e) {
Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage())); Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage()));
} }
@ -530,6 +375,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie
getIntent().removeExtra("singleFileName"); getIntent().removeExtra("singleFileName");
finish(); finish();
}; };
} }

View File

@ -1,49 +1,42 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.app.Dialog;
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.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
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.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.text.Html; import android.text.Html;
import android.text.Spanned; import android.text.Spanned;
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;
import android.view.View; import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.google.gson.JsonElement;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.AssigneesActions;
import org.mian.gitnex.actions.LabelsActions;
import org.mian.gitnex.adapters.AssigneesListAdapter;
import org.mian.gitnex.adapters.IssueCommentsAdapter; import org.mian.gitnex.adapters.IssueCommentsAdapter;
import org.mian.gitnex.adapters.LabelsListAdapter;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityIssueDetailBinding;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment; import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
@ -54,22 +47,15 @@ import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.helpers.UserMentions;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import org.mian.gitnex.models.Labels;
import org.mian.gitnex.models.UpdateIssueAssignees;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.models.WatchInfo;
import org.mian.gitnex.viewmodels.IssueCommentsViewModel; import org.mian.gitnex.viewmodels.IssueCommentsViewModel;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
@ -95,36 +81,28 @@ import retrofit2.Response;
* Author M M Arif * Author M M Arif
*/ */
public class IssueDetailActivity extends BaseActivity implements LabelsListAdapter.LabelsListAdapterListener, AssigneesListAdapter.AssigneesListAdapterListener, BottomSheetSingleIssueFragment.BottomSheetListener { public class IssueDetailActivity extends BaseActivity {
public ImageView closeActivity;
private IssueCommentsAdapter adapter; private IssueCommentsAdapter adapter;
private RecyclerView mRecyclerView;
private ImageView assigneeAvatar;
private TextView issueTitle;
private TextView issueDescription;
private TextView issueMilestone;
private TextView issueDueDate;
private TextView issueCreatedTime;
private HorizontalScrollView labelsScrollView;
private HorizontalScrollView assigneesScrollView;
private ScrollView scrollViewComments;
private TextView issueModified;
private ImageView createNewComment;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private TinyDB tinyDb; private LinearLayout labelsLayout;
private LinearLayout assigneesLayout;
private String instanceUrl; private View divider;
private String loginUid; private ProgressBar progressBar;
private String instanceToken;
private String repoOwner;
private String repoName;
private int issueIndex;
private LabelsListAdapter labelsAdapter;
private AssigneesListAdapter assigneesAdapter;
private List<Integer> currentLabelsIds = new ArrayList<>();
private List<Integer> labelsIds = new ArrayList<>();
private List<Labels> labelsList = new ArrayList<>();
private List<Collaborators> assigneesList = new ArrayList<>();
private List<String> assigneesListData = new ArrayList<>();
private List<String> currentAssignees = new ArrayList<>();
private Dialog dialogLabels;
private Dialog dialogAssignees;
private CustomLabelsSelectionDialogBinding labelsBinding;
private CustomAssigneesSelectionDialogBinding assigneesBinding;
private ActivityIssueDetailBinding viewBinding;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId() {
@ -137,65 +115,79 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
viewBinding = ActivityIssueDetailBinding.inflate(getLayoutInflater()); final TinyDB tinyDb = new TinyDB(appCtx);
View view = viewBinding.getRoot();
setContentView(view);
instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName"); String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/"); String[] parts = repoFullName.split("/");
repoOwner = parts[0]; final String repoOwner = parts[0];
repoName = parts[1]; final String repoName = parts[1];
issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
setSupportActionBar(viewBinding.toolbar); final SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh);
assigneeAvatar = findViewById(R.id.assigneeAvatar);
issueTitle = findViewById(R.id.issueTitle);
issueDescription = findViewById(R.id.issueDescription);
issueMilestone = findViewById(R.id.issueMilestone);
issueDueDate = findViewById(R.id.issueDueDate);
issueCreatedTime = findViewById(R.id.issueCreatedTime);
labelsScrollView = findViewById(R.id.labelsScrollView);
assigneesScrollView = findViewById(R.id.assigneesScrollView);
scrollViewComments = findViewById(R.id.scrollViewComments);
issueModified = findViewById(R.id.issueModified);
createNewComment = findViewById(R.id.addNewComment);
labelsLayout = findViewById(R.id.frameLabels);
assigneesLayout = findViewById(R.id.frameAssignees);
divider = findViewById(R.id.divider);
progressBar = findViewById(R.id.progressBar);
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setTitle(repoName); Objects.requireNonNull(getSupportActionBar()).setTitle(repoName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewBinding.recyclerView.setHasFixedSize(true); mRecyclerView = findViewById(R.id.recyclerView);
viewBinding.recyclerView.setNestedScrollingEnabled(false); mRecyclerView.setHasFixedSize(true);
viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx)); mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(viewBinding.recyclerView.getContext(), DividerItemDecoration.VERTICAL); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
viewBinding.recyclerView.addItemDecoration(dividerItemDecoration); mRecyclerView.addItemDecoration(dividerItemDecoration);
viewBinding.addNewComment.setOnClickListener(v -> BottomSheetReplyFragment.newInstance(new Bundle()).show(getSupportFragmentManager(), "replyBottomSheet")); createNewComment.setOnClickListener(v -> startActivity(new Intent(ctx, ReplyToIssueActivity.class)));
labelsAdapter = new LabelsListAdapter(labelsList, IssueDetailActivity.this, currentLabelsIds);
assigneesAdapter = new AssigneesListAdapter(ctx, assigneesList, IssueDetailActivity.this, currentAssignees);
LabelsActions.getCurrentIssueLabels(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentLabelsIds);
AssigneesActions.getCurrentIssueAssignees(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentAssignees);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
viewBinding.scrollViewComments.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { scrollViewComments.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if((scrollY - oldScrollY) > 0 && viewBinding.addNewComment.isShown()) { if((scrollY - oldScrollY) > 0 && createNewComment.isShown()) {
viewBinding.addNewComment.setVisibility(View.GONE); createNewComment.setVisibility(View.GONE);
} }
else if((scrollY - oldScrollY) < 0) { else if((scrollY - oldScrollY) < 0) {
viewBinding.addNewComment.setVisibility(View.VISIBLE); createNewComment.setVisibility(View.VISIBLE);
} }
if(!viewBinding.scrollViewComments.canScrollVertically(1)) { // bottom if(!scrollViewComments.canScrollVertically(1)) { // bottom
viewBinding.addNewComment.setVisibility(View.GONE); createNewComment.setVisibility(View.GONE);
} }
if(!viewBinding.scrollViewComments.canScrollVertically(-1)) { // top if(!scrollViewComments.canScrollVertically(-1)) { // top
viewBinding.addNewComment.setVisibility(View.VISIBLE); createNewComment.setVisibility(View.VISIBLE);
} }
}); });
} }
viewBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> {
viewBinding.pullToRefresh.setRefreshing(false); swipeRefresh.setRefreshing(false);
IssueCommentsViewModel IssueCommentsViewModel
.loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex,
ctx); ctx);
@ -220,231 +212,14 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
} }
viewBinding.toolbarTitle.setTypeface(myTypeface); toolbarTitle.setTypeface(myTypeface);
viewBinding.toolbarTitle.setText(repoName); toolbarTitle.setText(repoName);
getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
fetchDataAsync(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); fetchDataAsync(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
} }
@Override
public void onButtonClicked(String text) {
switch(text) {
case "showLabels":
showLabels();
break;
case "showAssignees":
showAssignees();
break;
}
}
@Override
public void labelsInterface(List<String> data) {
}
@Override
public void labelsIdsInterface(List<Integer> data) {
labelsIds = data;
}
@Override
public void assigneesInterface(List<String> data) {
assigneesListData = data;
}
private void showAssignees() {
assigneesAdapter.updateList(currentAssignees);
dialogAssignees = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
dialogAssignees.setCancelable(false);
if (dialogAssignees.getWindow() != null) {
dialogAssignees.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
assigneesBinding = CustomAssigneesSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
View view = assigneesBinding.getRoot();
dialogAssignees.setContentView(view);
assigneesBinding.cancel.setOnClickListener(assigneesBinding_ -> {
currentAssignees = new ArrayList<>(new LinkedHashSet<>(currentAssignees));
assigneesListData = new ArrayList<>(new LinkedHashSet<>(assigneesListData));
Collections.sort(assigneesListData);
Collections.sort(currentAssignees);
if(!assigneesListData.equals(currentAssignees)) {
updateIssueAssignees();
}
else {
dialogAssignees.dismiss();
}
});
AssigneesActions.getRepositoryAssignees(ctx, instanceUrl, instanceToken, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding);
}
public void showLabels() {
labelsAdapter.updateList(currentLabelsIds);
dialogLabels = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
dialogLabels.setCancelable(false);
if (dialogLabels.getWindow() != null) {
dialogLabels.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
labelsBinding = CustomLabelsSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
View view = labelsBinding.getRoot();
dialogLabels.setContentView(view);
labelsBinding.cancel.setOnClickListener(labelsBinding_ -> {
currentLabelsIds = new ArrayList<>(new LinkedHashSet<>(currentLabelsIds));
labelsIds = new ArrayList<>(new LinkedHashSet<>(labelsIds));
Collections.sort(labelsIds);
Collections.sort(currentLabelsIds);
if(!labelsIds.equals(currentLabelsIds)) {
updateIssueLabels();
}
else {
dialogLabels.dismiss();
}
});
LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding);
}
private void updateIssueAssignees() {
UpdateIssueAssignees updateAssigneeJson = new UpdateIssueAssignees(assigneesListData);
Call<JsonElement> call3;
call3 = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.patchIssueAssignees(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson);
call3.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response2) {
if(response2.code() == 201) {
Toasty.success(ctx, ctx.getString(R.string.assigneesUpdated));
dialogAssignees.dismiss();
viewBinding.frameAssignees.removeAllViews();
viewBinding.frameLabels.removeAllViews();
getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
currentAssignees.clear();
new Handler(Looper.getMainLooper()).postDelayed(() -> AssigneesActions.getCurrentIssueAssignees(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentAssignees), 1000);
}
else if(response2.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response2.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
}
else if(response2.code() == 404) {
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
private void updateIssueLabels() {
Labels patchIssueLabels = new Labels(labelsIds);
Call<JsonElement> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.updateIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
if(response.code() == 200) {
Toasty.success(ctx, ctx.getString(R.string.labelsUpdated));
dialogLabels.dismiss();
viewBinding.frameAssignees.removeAllViews();
viewBinding.frameLabels.removeAllViews();
getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
currentLabelsIds.clear();
new Handler(Looper.getMainLooper()).postDelayed(() -> LabelsActions.getCurrentIssueLabels(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentLabelsIds), 1000);
}
else if(response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
getResources().getString(R.string.alertDialogTokenRevokedMessage),
getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
else if(response.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
}
else if(response.code() == 404) {
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
}
else {
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString());
}
});
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
@ -476,15 +251,24 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
if(tinyDb.getBoolean("commentPosted")) { if(tinyDb.getBoolean("commentPosted")) {
viewBinding.scrollViewComments.post(() -> { scrollViewComments.post(() -> {
IssueCommentsViewModel IssueCommentsViewModel
.loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex,
ctx); ctx);
new Handler(Looper.getMainLooper()).postDelayed(() -> viewBinding.scrollViewComments.fullScroll(ScrollView.FOCUS_DOWN), 1000); new Handler().postDelayed(() -> scrollViewComments.fullScroll(ScrollView.FOCUS_DOWN), 1000);
tinyDb.putBoolean("commentPosted", false); tinyDb.putBoolean("commentPosted", false);
@ -492,7 +276,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
} }
if(tinyDb.getBoolean("commentEdited")) { if(tinyDb.getBoolean("commentEdited")) {
viewBinding.scrollViewComments.post(() -> { scrollViewComments.post(() -> {
IssueCommentsViewModel IssueCommentsViewModel
.loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex,
@ -504,10 +288,10 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
if(tinyDb.getBoolean("singleIssueUpdate")) { if(tinyDb.getBoolean("singleIssueUpdate")) {
new Handler(Looper.getMainLooper()).postDelayed(() -> { new Handler().postDelayed(() -> {
viewBinding.frameAssignees.removeAllViews(); assigneesLayout.removeAllViews();
viewBinding.frameLabels.removeAllViews(); labelsLayout.removeAllViews();
getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
tinyDb.putBoolean("singleIssueUpdate", false); tinyDb.putBoolean("singleIssueUpdate", false);
@ -517,10 +301,10 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
if(tinyDb.getBoolean("issueEdited")) { if(tinyDb.getBoolean("issueEdited")) {
new Handler(Looper.getMainLooper()).postDelayed(() -> { new Handler().postDelayed(() -> {
viewBinding.frameAssignees.removeAllViews(); assigneesLayout.removeAllViews();
viewBinding.frameLabels.removeAllViews(); labelsLayout.removeAllViews();
getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
tinyDb.putBoolean("issueEdited", false); tinyDb.putBoolean("issueEdited", false);
@ -540,11 +324,11 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
assert issueCommentsMain != null; assert issueCommentsMain != null;
if(issueCommentsMain.size() > 0) { if(issueCommentsMain.size() > 0) {
viewBinding.divider.setVisibility(View.VISIBLE); divider.setVisibility(View.VISIBLE);
} }
adapter = new IssueCommentsAdapter(ctx, getSupportFragmentManager(), issueCommentsMain); adapter = new IssueCommentsAdapter(ctx, issueCommentsMain);
viewBinding.recyclerView.setAdapter(adapter); mRecyclerView.setAdapter(adapter);
}); });
@ -566,27 +350,6 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
Issues singleIssue = response.body(); Issues singleIssue = response.body();
assert singleIssue != null; assert singleIssue != null;
viewBinding.issuePrState.setVisibility(View.VISIBLE);
if(singleIssue.getPull_request() != null) {
if(singleIssue.getPull_request().isMerged()) { // merged
viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request_merged);
}
else if(!singleIssue.getPull_request().isMerged() && singleIssue.getState().equals("closed")) { // closed
viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request_closed);
}
else { // open
viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request);
}
}
else if(singleIssue.getState().equals("closed")) { // issue closed
viewBinding.issuePrState.setImageResource(R.drawable.ic_issue_closed_red);
}
final Markwon markwon = Markwon.builder(Objects.requireNonNull(ctx)).usePlugin(CorePlugin.create()) final Markwon markwon = Markwon.builder(Objects.requireNonNull(ctx)).usePlugin(CorePlugin.create())
.usePlugin(ImagesPlugin.create(plugin -> { .usePlugin(ImagesPlugin.create(plugin -> {
plugin.addSchemeHandler(new SchemeHandler() { plugin.addSchemeHandler(new SchemeHandler() {
@ -634,24 +397,23 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
final String timeFormat = tinyDb.getString("dateFormat"); final String timeFormat = tinyDb.getString("dateFormat");
tinyDb.putString("issueState", singleIssue.getState()); tinyDb.putString("issueState", singleIssue.getState());
tinyDb.putString("issueTitle", singleIssue.getTitle()); tinyDb.putString("issueTitle", singleIssue.getTitle());
tinyDb.putString("singleIssueHtmlUrl", singleIssue.getHtml_url());
PicassoService.getInstance(ctx).get().load(singleIssue.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated) PicassoService.getInstance(ctx).get().load(singleIssue.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated)
.transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(viewBinding.assigneeAvatar); .transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar);
String issueNumber_ = "<font color='" + appCtx.getResources().getColor(R.color.lightGray) + "'>" + appCtx.getResources() String issueNumber_ = "<font color='" + appCtx.getResources().getColor(R.color.lightGray) + "'>" + appCtx.getResources()
.getString(R.string.hash) + singleIssue.getNumber() + "</font>"; .getString(R.string.hash) + singleIssue.getNumber() + "</font>";
viewBinding.issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle())); issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle()));
String cleanIssueDescription = singleIssue.getBody().trim(); String cleanIssueDescription = singleIssue.getBody().trim();
Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription)); Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
markwon.setParsedMarkdown(viewBinding.issueDescription, UserMentions.UserMentionsFunc(ctx, bodyWithMD, cleanIssueDescription)); markwon.setParsedMarkdown(issueDescription, UserMentions.UserMentionsFunc(ctx, bodyWithMD, cleanIssueDescription));
RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams) viewBinding.issueDescription.getLayoutParams(); RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams) issueDescription.getLayoutParams();
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(80, 80); LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(80, 80);
params1.setMargins(15, 0, 0, 0); params1.setMargins(15, 0, 0, 0);
if(singleIssue.getAssignees() != null) { if(singleIssue.getAssignees() != null) {
viewBinding.assigneesScrollView.setVisibility(View.VISIBLE); assigneesScrollView.setVisibility(View.VISIBLE);
for(int i = 0; i < singleIssue.getAssignees().size(); i++) { for(int i = 0; i < singleIssue.getAssignees().size(); i++) {
ImageView assigneesView = new ImageView(ctx); ImageView assigneesView = new ImageView(ctx);
@ -660,7 +422,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
.placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(100, 100).centerCrop() .placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(100, 100).centerCrop()
.into(assigneesView); .into(assigneesView);
viewBinding.frameAssignees.addView(assigneesView); assigneesLayout.addView(assigneesView);
assigneesView.setLayoutParams(params1); assigneesView.setLayoutParams(params1);
if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) { if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) {
assigneesView.setOnClickListener( assigneesView.setOnClickListener(
@ -674,7 +436,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
} }
} }
else { else {
viewBinding.assigneesScrollView.setVisibility(View.GONE); assigneesScrollView.setVisibility(View.GONE);
} }
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
@ -682,7 +444,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
params.setMargins(0, 0, 15, 0); params.setMargins(0, 0, 15, 0);
if(singleIssue.getLabels() != null) { if(singleIssue.getLabels() != null) {
viewBinding.labelsScrollView.setVisibility(View.VISIBLE); labelsScrollView.setVisibility(View.VISIBLE);
for(int i = 0; i < singleIssue.getLabels().size(); i++) { for(int i = 0; i < singleIssue.getLabels().size(); i++) {
@ -691,8 +453,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
int color = Color.parseColor("#" + labelColor); int color = Color.parseColor("#" + labelColor);
ImageView labelsView = new ImageView(ctx); ImageView labelsView = new ImageView(ctx);
viewBinding.frameLabels.setOrientation(LinearLayout.HORIZONTAL); labelsLayout.setOrientation(LinearLayout.HORIZONTAL);
viewBinding.frameLabels.setGravity(Gravity.START | Gravity.TOP); labelsLayout.setGravity(Gravity.START | Gravity.TOP);
labelsView.setLayoutParams(params); labelsView.setLayoutParams(params);
int height = AppUtil.getPixelsFromDensity(ctx, 25); int height = AppUtil.getPixelsFromDensity(ctx, 25);
@ -704,12 +466,12 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
.height(height).endConfig().buildRoundRect(labelName, color, AppUtil.getPixelsFromDensity(ctx, 5)); .height(height).endConfig().buildRoundRect(labelName, color, AppUtil.getPixelsFromDensity(ctx, 5));
labelsView.setImageDrawable(drawable); labelsView.setImageDrawable(drawable);
viewBinding.frameLabels.addView(labelsView); labelsLayout.addView(labelsView);
} }
} }
else { else {
viewBinding.labelsScrollView.setVisibility(View.GONE); labelsScrollView.setVisibility(View.GONE);
} }
if(singleIssue.getDue_date() != null) { if(singleIssue.getDue_date() != null) {
@ -717,80 +479,80 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
if(timeFormat.equals("normal") || timeFormat.equals("pretty")) { if(timeFormat.equals("normal") || timeFormat.equals("pretty")) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale)); DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
String dueDate = formatter.format(singleIssue.getDue_date()); String dueDate = formatter.format(singleIssue.getDue_date());
viewBinding.issueDueDate.setText(dueDate); issueDueDate.setText(dueDate);
viewBinding.issueDueDate issueDueDate
.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getDue_date()), ctx)); .setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getDue_date()), ctx));
} }
else if(timeFormat.equals("normal1")) { else if(timeFormat.equals("normal1")) {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale)); DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
String dueDate = formatter.format(singleIssue.getDue_date()); String dueDate = formatter.format(singleIssue.getDue_date());
viewBinding.issueDueDate.setText(dueDate); issueDueDate.setText(dueDate);
} }
} }
else { else {
viewBinding.issueDueDate.setVisibility(View.GONE); issueDueDate.setVisibility(View.GONE);
} }
String edited; String edited;
if(!singleIssue.getUpdated_at().equals(singleIssue.getCreated_at())) { if(!singleIssue.getUpdated_at().equals(singleIssue.getCreated_at())) {
edited = getString(R.string.colorfulBulletSpan) + getString(R.string.modifiedText); edited = getString(R.string.colorfulBulletSpan) + getString(R.string.modifiedText);
viewBinding.issueModified.setVisibility(View.VISIBLE); issueModified.setVisibility(View.VISIBLE);
viewBinding.issueModified.setText(edited); issueModified.setText(edited);
viewBinding.issueModified issueModified
.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getUpdated_at()), ctx)); .setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getUpdated_at()), ctx));
} }
else { else {
viewBinding.issueModified.setVisibility(View.INVISIBLE); issueModified.setVisibility(View.INVISIBLE);
} }
if((singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) && singleIssue.getAssignees() != null) { if((singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) && singleIssue.getAssignees() != null) {
paramsDesc.setMargins(0, 35, 0, 0); paramsDesc.setMargins(0, 35, 0, 0);
viewBinding.issueDescription.setLayoutParams(paramsDesc); issueDescription.setLayoutParams(paramsDesc);
} }
else if(singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) { else if(singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) {
paramsDesc.setMargins(0, 55, 0, 0); paramsDesc.setMargins(0, 55, 0, 0);
viewBinding.issueDescription.setLayoutParams(paramsDesc); issueDescription.setLayoutParams(paramsDesc);
} }
else if(singleIssue.getAssignees() == null) { else if(singleIssue.getAssignees() == null) {
paramsDesc.setMargins(0, 35, 0, 0); paramsDesc.setMargins(0, 35, 0, 0);
viewBinding.issueDescription.setLayoutParams(paramsDesc); issueDescription.setLayoutParams(paramsDesc);
} }
else { else {
paramsDesc.setMargins(0, 15, 0, 0); paramsDesc.setMargins(0, 15, 0, 0);
viewBinding.issueDescription.setLayoutParams(paramsDesc); issueDescription.setLayoutParams(paramsDesc);
} }
viewBinding.issueCreatedTime.setText(TimeHelper.formatTime(singleIssue.getCreated_at(), new Locale(locale), timeFormat, ctx)); issueCreatedTime.setText(TimeHelper.formatTime(singleIssue.getCreated_at(), new Locale(locale), timeFormat, ctx));
viewBinding.issueCreatedTime.setVisibility(View.VISIBLE); issueCreatedTime.setVisibility(View.VISIBLE);
if(timeFormat.equals("pretty")) { if(timeFormat.equals("pretty")) {
viewBinding.issueCreatedTime issueCreatedTime
.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getCreated_at()), ctx)); .setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getCreated_at()), ctx));
} }
if(singleIssue.getMilestone() != null) { if(singleIssue.getMilestone() != null) {
viewBinding.issueMilestone.setVisibility(View.VISIBLE); issueMilestone.setText(getString(R.string.issueMilestone, singleIssue.getMilestone().getTitle()));
viewBinding.issueMilestone.setText(getString(R.string.issueMilestone, singleIssue.getMilestone().getTitle()));
} }
else { else {
viewBinding.issueMilestone.setVisibility(View.GONE); issueMilestone.setVisibility(View.GONE);
} }
if(!singleIssue.getUser().getFull_name().equals("")) { if(!singleIssue.getUser().getFull_name().equals("")) {
viewBinding.assigneeAvatar.setOnClickListener( assigneeAvatar.setOnClickListener(
new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), ctx)); new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), ctx));
} }
else { else {
viewBinding.assigneeAvatar.setOnClickListener( assigneeAvatar.setOnClickListener(
new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), ctx)); new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), ctx));
} }
viewBinding.progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
} }
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),
@ -799,22 +561,6 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
} }
else if(response.code() == 404) {
if(tinyDb.getString("issueType").equals("Issue")) {
Toasty.warning(ctx, getResources().getString(R.string.noDataIssueTab));
}
else if(tinyDb.getString("issueType").equals("Pull")) {
Toasty.warning(ctx, getResources().getString(R.string.noDataPullRequests));
}
Intent mainIntent = new Intent(ctx, MainActivity.class);
ctx.startActivity(mainIntent);
finish();
}
} }

View File

@ -2,26 +2,31 @@ package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.Gravity;
import android.view.View; import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioGroup; import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
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.database.api.UserAccountsApi; import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.NetworkObserver; import org.mian.gitnex.helpers.NetworkObserver;
import org.mian.gitnex.helpers.PathsHelper; import org.mian.gitnex.helpers.PathsHelper;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.UrlHelper; import org.mian.gitnex.helpers.UrlHelper;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.GiteaVersion;
@ -52,10 +57,11 @@ public class LoginActivity extends BaseActivity {
private Button loginButton; private Button loginButton;
private EditText instanceUrlET, loginUidET, loginPassword, otpCode, loginTokenCode; private EditText instanceUrlET, loginUidET, loginPassword, otpCode, loginTokenCode;
private AutoCompleteTextView protocolSpinner; private Spinner protocolSpinner;
private TextView otpInfo;
private RadioGroup loginMethod; private RadioGroup loginMethod;
private String device_id = "token"; private String device_id = "token";
private String selectedProtocol; private ScrollView layoutView;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId() {
@ -77,47 +83,52 @@ public class LoginActivity extends BaseActivity {
loginUidET = findViewById(R.id.login_uid); loginUidET = findViewById(R.id.login_uid);
loginPassword = findViewById(R.id.login_passwd); loginPassword = findViewById(R.id.login_passwd);
otpCode = findViewById(R.id.otpCode); otpCode = findViewById(R.id.otpCode);
otpInfo = findViewById(R.id.otpInfo);
ImageView info_button = findViewById(R.id.info);
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);
((TextView) findViewById(R.id.appVersion)).setText(AppUtil.getAppVersion(appCtx)); ((TextView) findViewById(R.id.appVersion)).setText(AppUtil.getAppVersion(appCtx));
ArrayAdapter<Protocol> adapterProtocols = new ArrayAdapter<>(LoginActivity.this, R.layout.list_spinner_items, Protocol.values()); ArrayAdapter<Protocol> adapterProtocols = new ArrayAdapter<>(LoginActivity.this, R.layout.spinner_item, Protocol.values());
adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item);
protocolSpinner.setAdapter(adapterProtocols); protocolSpinner.setAdapter(adapterProtocols);
protocolSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
protocolSpinner.setOnItemClickListener((parent, view, position, id) -> { public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
selectedProtocol = String.valueOf(parent.getItemAtPosition(position)); if(protocolSpinner.getSelectedItem() == Protocol.HTTP) {
SnackBar.warning(ctx, layoutView, getResources().getString(R.string.protocolError));
if(selectedProtocol.equals(String.valueOf(Protocol.HTTP))) {
Toasty.warning(ctx, getResources().getString(R.string.protocolError));
} }
}
public void onNothingSelected(AdapterView<?> parent) {
}
}); });
if(R.id.loginToken == loginMethod.getCheckedRadioButtonId()) { info_button.setOnClickListener(
view -> new Tooltip.Builder(view).setText(R.string.urlInfoTooltip).setTextColor(getResources().getColor(R.color.white))
AppUtil.setMultiVisibility(View.GONE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout)); .setBackgroundColor(getResources().getColor(R.color.tooltipBackground)).setCancelable(true).setDismissOnClick(true).setPadding(30)
findViewById(R.id.loginTokenCodeLayout).setVisibility(View.VISIBLE); .setCornerRadius(R.dimen.tooltipCornor).setGravity(Gravity.BOTTOM).show());
}
else {
AppUtil.setMultiVisibility(View.VISIBLE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout));
findViewById(R.id.loginTokenCodeLayout).setVisibility(View.GONE);
}
loginMethod.setOnCheckedChangeListener((group, checkedId) -> { loginMethod.setOnCheckedChangeListener((group, checkedId) -> {
if(checkedId == R.id.loginToken) { if(checkedId == R.id.loginToken) {
AppUtil.setMultiVisibility(View.GONE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout)); AppUtil.setMultiVisibility(View.GONE, loginUidET, loginPassword, otpCode, otpInfo);
findViewById(R.id.loginTokenCodeLayout).setVisibility(View.VISIBLE); loginTokenCode.setVisibility(View.VISIBLE);
} }
else { else {
AppUtil.setMultiVisibility(View.VISIBLE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout)); AppUtil.setMultiVisibility(View.VISIBLE, loginUidET, loginPassword, otpCode, otpInfo);
findViewById(R.id.loginTokenCodeLayout).setVisibility(View.GONE); loginTokenCode.setVisibility(View.GONE);
} }
}); });
@ -126,12 +137,13 @@ public class LoginActivity extends BaseActivity {
if(isAvailable) { if(isAvailable) {
enableProcessButton(); enableProcessButton();
SnackBar.success(ctx, layoutView, getResources().getString(R.string.netConnectionIsBack));
} }
else { else {
disableProcessButton(); disableProcessButton();
loginButton.setText(getResources().getString(R.string.btnLogin)); loginButton.setText(getResources().getString(R.string.btnLogin));
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.checkNetConnection));
} }
}); });
@ -150,62 +162,73 @@ public class LoginActivity extends BaseActivity {
try { try {
if(selectedProtocol == null) {
Toasty.error(ctx, getResources().getString(R.string.protocolEmptyError));
enableProcessButton();
return;
}
String loginUid = loginUidET.getText().toString(); String loginUid = loginUidET.getText().toString();
String loginPass = loginPassword.getText().toString(); String loginPass = loginPassword.getText().toString();
String loginToken = loginTokenCode.getText().toString().trim(); String loginToken = loginTokenCode.getText().toString().trim();
Protocol protocol = (Protocol) protocolSpinner.getSelectedItem();
LoginType loginType = (loginMethod.getCheckedRadioButtonId() == R.id.loginUsernamePassword) ? LoginType.BASIC : LoginType.TOKEN; LoginType loginType = (loginMethod.getCheckedRadioButtonId() == R.id.loginUsernamePassword) ? LoginType.BASIC : LoginType.TOKEN;
URI rawInstanceUrl = UrlBuilder.fromString(UrlHelper.fixScheme(instanceUrlET.getText().toString(), "http")).toUri(); URI rawInstanceUrl = UrlBuilder.fromString(UrlHelper.fixScheme(instanceUrlET.getText().toString(), "http")).toUri();
URI instanceUrl = UrlBuilder.fromUri(rawInstanceUrl).withScheme(selectedProtocol.toLowerCase()).withPath(PathsHelper.join(rawInstanceUrl.getPath(), "/api/v1/")) URI instanceUrlWithProtocol = UrlBuilder.fromUri(rawInstanceUrl).withPath(PathsHelper.join(rawInstanceUrl.getPath()))
.withScheme(protocol.name().toLowerCase()).toUri();
URI instanceUrl = UrlBuilder.fromUri(instanceUrlWithProtocol).withPath(PathsHelper.join(instanceUrlWithProtocol.getPath(), "/api/v1/"))
.toUri(); .toUri();
tinyDB.putString("loginType", loginType.name().toLowerCase()); tinyDB.putString("loginType", loginType.name().toLowerCase());
tinyDB.putString("instanceUrlRaw", instanceUrlET.getText().toString()); tinyDB.putString("instanceUrlRaw", instanceUrlET.getText().toString());
tinyDB.putString("instanceUrl", instanceUrl.toString()); tinyDB.putString("instanceUrl", instanceUrl.toString());
tinyDB.putString("instanceUrlWithProtocol", instanceUrlWithProtocol.toString());
if(instanceUrlET.getText().toString().equals("")) { if(instanceUrlET.getText().toString().equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldURL)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.emptyFieldURL));
enableProcessButton(); enableProcessButton();
return; return;
} }
if(loginType == LoginType.BASIC) { if(loginType == LoginType.BASIC) {
if(otpCode.length() != 0 && otpCode.length() != 6) { if(otpCode.length() != 0 && otpCode.length() != 6) {
Toasty.warning(ctx, getResources().getString(R.string.loginOTPTypeError)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.loginOTPTypeError));
enableProcessButton(); enableProcessButton();
return; return;
} }
if(rawInstanceUrl.getUserInfo() != null) { if(rawInstanceUrl.getUserInfo() != null) {
tinyDB.putString("basicAuthPassword", loginPass); tinyDB.putString("basicAuthPassword", loginPass);
tinyDB.putBoolean("basicAuthFlag", true); tinyDB.putBoolean("basicAuthFlag", true);
} }
if(loginUid.equals("")) { if(loginUid.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldUsername)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.emptyFieldUsername));
enableProcessButton(); enableProcessButton();
return; return;
}
if(loginUid.contains("@")) {
SnackBar.warning(ctx, layoutView, getResources().getString(R.string.userInvalidUserName));
enableProcessButton();
return;
} }
if(loginPass.equals("")) { if(loginPass.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldPassword)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.emptyFieldPassword));
enableProcessButton(); enableProcessButton();
return; return;
} }
int loginOTP = (otpCode.length() > 0) ? Integer.parseInt(otpCode.getText().toString().trim()) : 0; int loginOTP = (otpCode.length() > 0) ? Integer.parseInt(otpCode.getText().toString().trim()) : 0;
@ -218,7 +241,7 @@ public class LoginActivity extends BaseActivity {
if(loginToken.equals("")) { if(loginToken.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.loginTokenError)); SnackBar.warning(ctx, layoutView, getResources().getString(R.string.loginTokenError));
enableProcessButton(); enableProcessButton();
return; return;
@ -232,7 +255,7 @@ public class LoginActivity extends BaseActivity {
catch(Exception e) { catch(Exception e) {
Log.e("onFailure-login", e.toString()); Log.e("onFailure-login", e.toString());
Toasty.error(ctx, getResources().getString(R.string.malformedUrl)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.malformedUrl));
enableProcessButton(); enableProcessButton();
} }
@ -245,7 +268,7 @@ public class LoginActivity extends BaseActivity {
if(!loginToken.equals("")) { if(!loginToken.equals("")) {
callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken("token " + loginToken); callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken(loginToken);
} }
else { else {
@ -265,17 +288,20 @@ public class LoginActivity extends BaseActivity {
if(responseVersion.code() == 200) { if(responseVersion.code() == 200) {
GiteaVersion version = responseVersion.body(); GiteaVersion version = responseVersion.body();
Version gitea_version;
assert version != null; assert version != null;
if(!Version.valid(version.getVersion())) {
Toasty.error(ctx, getResources().getString(R.string.versionUnknown)); try {
gitea_version = new Version(version.getVersion());
}
catch(Exception e) {
SnackBar.error(ctx, layoutView, getResources().getString(R.string.versionUnknown));
enableProcessButton(); enableProcessButton();
return; return;
} }
tinyDB.putString("giteaVersion", version.getVersion());
Version gitea_version = new Version(version.getVersion());
if(gitea_version.less(getString(R.string.versionLow))) { if(gitea_version.less(getString(R.string.versionLow))) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader)) AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader))
@ -303,7 +329,7 @@ public class LoginActivity extends BaseActivity {
} }
else { else {
Toasty.warning(ctx, getResources().getString(R.string.versionUnsupportedNew)); SnackBar.info(ctx, layoutView, getResources().getString(R.string.versionUnsupportedNew));
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken); login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken);
} }
@ -332,7 +358,7 @@ public class LoginActivity extends BaseActivity {
public void onFailure(@NonNull Call<GiteaVersion> callVersion, @NonNull Throwable t) { public void onFailure(@NonNull Call<GiteaVersion> callVersion, @NonNull Throwable t) {
Log.e("onFailure-versionCheck", t.toString()); Log.e("onFailure-versionCheck", t.toString());
Toasty.error(ctx, getResources().getString(R.string.errorOnLogin)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.errorOnLogin));
enableProcessButton(); enableProcessButton();
} }
}); });
@ -362,18 +388,9 @@ public class LoginActivity extends BaseActivity {
String accountName = userDetails.getUsername() + "@" + instanceUrl; String accountName = userDetails.getUsername() + "@" + instanceUrl;
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx); UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
int checkAccount = userAccountsApi.getCount(accountName); int checkAccount = userAccountsApi.getCount(accountName);
long accountId;
if(checkAccount == 0) { if(checkAccount == 0) {
userAccountsApi.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, "");
accountId = userAccountsApi.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, "");
tinyDB.putInt("currentActiveAccountId", (int) accountId);
}
else {
userAccountsApi.updateTokenByAccountName(accountName, loginToken);
UserAccount data = userAccountsApi.getAccountData(accountName);
tinyDB.putInt("currentActiveAccountId", data.getAccountId());
} }
enableProcessButton(); enableProcessButton();
@ -382,12 +399,12 @@ public class LoginActivity extends BaseActivity {
break; break;
case 401: case 401:
Toasty.error(ctx, getResources().getString(R.string.unauthorizedApiError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.unauthorizedApiError));
enableProcessButton(); enableProcessButton();
break; break;
default: default:
Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
} }
@ -398,7 +415,7 @@ public class LoginActivity extends BaseActivity {
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());
Toasty.error(ctx, getResources().getString(R.string.genericError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericError));
enableProcessButton(); enableProcessButton();
} }
@ -458,7 +475,7 @@ public class LoginActivity extends BaseActivity {
} }
else { else {
Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
} }
@ -468,7 +485,7 @@ public class LoginActivity extends BaseActivity {
public void onFailure(@NonNull Call<Void> delcall, @NonNull Throwable t) { public void onFailure(@NonNull Call<Void> delcall, @NonNull Throwable t) {
Log.e("onFailure-login", t.toString()); Log.e("onFailure-login", t.toString());
Toasty.error(ctx, getResources().getString(R.string.malformedJson)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.malformedJson));
enableProcessButton(); enableProcessButton();
} }
@ -481,7 +498,7 @@ public class LoginActivity extends BaseActivity {
} }
else { else {
Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
} }
@ -491,7 +508,7 @@ public class LoginActivity extends BaseActivity {
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());
Toasty.error(ctx, getResources().getString(R.string.malformedJson)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.malformedJson));
enableProcessButton(); enableProcessButton();
} }
@ -552,19 +569,10 @@ public class LoginActivity extends BaseActivity {
String accountName = userDetails.getUsername() + "@" + instanceUrl; String accountName = userDetails.getUsername() + "@" + instanceUrl;
UserAccountsApi userAccountsApi = new UserAccountsApi(ctx); UserAccountsApi userAccountsApi = new UserAccountsApi(ctx);
int checkAccount = userAccountsApi.getCount(accountName); int checkAccount = userAccountsApi.getCount(accountName);
long accountId;
if(checkAccount == 0) { if(checkAccount == 0) {
userAccountsApi
accountId = userAccountsApi
.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), newToken.getSha1(), ""); .insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), newToken.getSha1(), "");
tinyDB.putInt("currentActiveAccountId", (int) accountId);
}
else {
userAccountsApi.updateTokenByAccountName(accountName, newToken.getSha1());
UserAccount data = userAccountsApi.getAccountData(accountName);
tinyDB.putInt("currentActiveAccountId", data.getAccountId());
} }
startActivity(new Intent(LoginActivity.this, MainActivity.class)); startActivity(new Intent(LoginActivity.this, MainActivity.class));
@ -572,12 +580,12 @@ public class LoginActivity extends BaseActivity {
break; break;
case 401: case 401:
Toasty.error(ctx, getResources().getString(R.string.unauthorizedApiError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.unauthorizedApiError));
enableProcessButton(); enableProcessButton();
break; break;
default: default:
Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton(); enableProcessButton();
} }
@ -588,7 +596,7 @@ public class LoginActivity extends BaseActivity {
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());
Toasty.error(ctx, getResources().getString(R.string.genericError)); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericError));
enableProcessButton(); enableProcessButton();
} }
@ -597,7 +605,7 @@ public class LoginActivity extends BaseActivity {
} }
else if(responseCreate.code() == 500) { else if(responseCreate.code() == 500) {
Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + responseCreate.code()); SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + responseCreate.code());
enableProcessButton(); enableProcessButton();
} }
@ -646,14 +654,26 @@ public class LoginActivity extends BaseActivity {
private void disableProcessButton() { private void disableProcessButton() {
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.hintColor));
loginButton.setText(R.string.processingText); loginButton.setText(R.string.processingText);
loginButton.setBackground(shape);
loginButton.setEnabled(false); loginButton.setEnabled(false);
} }
private void enableProcessButton() { private void enableProcessButton() {
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.btnBackground));
loginButton.setText(R.string.btnLogin); loginButton.setText(R.string.btnLogin);
loginButton.setBackground(shape);
loginButton.setEnabled(true); loginButton.setEnabled(true);
} }
} }

View File

@ -1,14 +1,15 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.app.Activity; import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -17,24 +18,22 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat; import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.navigation.NavigationView; import com.google.android.material.navigation.NavigationView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.adapters.UserAccountsNavAdapter;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.UserAccountsApi; import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount; import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.fragments.AboutFragment;
import org.mian.gitnex.fragments.AdministrationFragment; import org.mian.gitnex.fragments.AdministrationFragment;
import org.mian.gitnex.fragments.BottomSheetDraftsFragment; import org.mian.gitnex.fragments.BottomSheetDraftsFragment;
import org.mian.gitnex.fragments.DraftsFragment; import org.mian.gitnex.fragments.DraftsFragment;
import org.mian.gitnex.fragments.ExploreFragment; import org.mian.gitnex.fragments.ExploreRepositoriesFragment;
import org.mian.gitnex.fragments.MyRepositoriesFragment; import org.mian.gitnex.fragments.MyRepositoriesFragment;
import org.mian.gitnex.fragments.NotificationsFragment; import org.mian.gitnex.fragments.NotificationsFragment;
import org.mian.gitnex.fragments.OrganizationsFragment; import org.mian.gitnex.fragments.OrganizationsFragment;
@ -53,10 +52,7 @@ import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.NotificationCount;
import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import eightbitlab.com.blurview.BlurView; import eightbitlab.com.blurview.BlurView;
import eightbitlab.com.blurview.RenderScriptBlur; import eightbitlab.com.blurview.RenderScriptBlur;
@ -79,17 +75,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
private TextView toolbarTitle; private TextView toolbarTitle;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private static TinyDB tinyDb;
private Typeface myTypeface; private Typeface myTypeface;
private String instanceUrl;
private String loginUid;
private String instanceToken;
private View hView;
private MenuItem navNotifications;
private TextView notificationCounter;
@Override @Override
protected int getLayoutResourceId() { protected int getLayoutResourceId() {
@ -102,15 +89,15 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx); final TinyDB tinyDb = new TinyDB(appCtx);
tinyDb.putBoolean("noConnection", false); tinyDb.putBoolean("noConnection", false);
Intent mainIntent = getIntent(); Intent mainIntent = getIntent();
String launchFragment = mainIntent.getStringExtra("launchFragment"); String launchFragment = mainIntent.getStringExtra("launchFragment");
instanceUrl = tinyDb.getString("instanceUrl"); final String instanceUrl = tinyDb.getString("instanceUrl");
loginUid = tinyDb.getString("loginUid"); final String loginUid = tinyDb.getString("loginUid");
instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
if(tinyDb.getString("dateFormat").isEmpty()) { if(tinyDb.getString("dateFormat").isEmpty()) {
tinyDb.putString("dateFormat", "pretty"); tinyDb.putString("dateFormat", "pretty");
@ -136,9 +123,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
return; return;
} }
if(tinyDb.getInt("currentActiveAccountId") <= 0) { String accountName = loginUid + "@" + instanceUrl;
AlertDialogs.forceLogoutDialog(ctx, getResources().getString(R.string.forceLogoutDialogHeader), getResources().getString(R.string.forceLogoutDialogDescription), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); getAccountData(accountName);
}
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);
@ -177,7 +163,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
else if(fragmentById instanceof OrganizationsFragment) { else if(fragmentById instanceof OrganizationsFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations));
} }
else if(fragmentById instanceof ExploreFragment) { else if(fragmentById instanceof ExploreRepositoriesFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
} }
else if(fragmentById instanceof NotificationsFragment) { else if(fragmentById instanceof NotificationsFragment) {
@ -186,6 +172,9 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
else if(fragmentById instanceof ProfileFragment) { else if(fragmentById instanceof ProfileFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
} }
else if(fragmentById instanceof AboutFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout));
}
else if(fragmentById instanceof DraftsFragment) { else if(fragmentById instanceof DraftsFragment) {
toolbarTitle.setText(getResources().getString(R.string.titleDrafts)); toolbarTitle.setText(getResources().getString(R.string.titleDrafts));
} }
@ -196,15 +185,10 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
toolbarTitle.setText(getResources().getString(R.string.pageTitleUserAccounts)); toolbarTitle.setText(getResources().getString(R.string.pageTitleUserAccounts));
} }
getNotificationsCount(instanceUrl, instanceToken);
drawer = findViewById(R.id.drawer_layout); drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view); NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this); navigationView.setNavigationItemSelectedListener(this);
hView = navigationView.getHeaderView(0); final View hView = navigationView.getHeaderView(0);
Menu menu = navigationView.getMenu();
navNotifications = menu.findItem(R.id.nav_notifications);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
@ -214,14 +198,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
@Override @Override
public void onDrawerOpened(@NonNull View drawerView) { public void onDrawerOpened(@NonNull View drawerView) {
getNotificationsCount(instanceUrl, instanceToken);
}
@Override
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
if(tinyDb.getBoolean("noConnection")) { if(tinyDb.getBoolean("noConnection")) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
tinyDb.putBoolean("noConnection", false); tinyDb.putBoolean("noConnection", false);
} }
@ -236,29 +214,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
userAvatarBackground = hView.findViewById(R.id.userAvatarBackground); userAvatarBackground = hView.findViewById(R.id.userAvatarBackground);
navHeaderFrame = hView.findViewById(R.id.navHeaderFrame); navHeaderFrame = hView.findViewById(R.id.navHeaderFrame);
List<UserAccount> userAccountsList;
userAccountsList = new ArrayList<>();
UserAccountsApi userAccountsApi;
userAccountsApi = new UserAccountsApi(ctx);
RecyclerView navRecyclerViewUserAccounts = hView.findViewById(R.id.navRecyclerViewUserAccounts);
UserAccountsNavAdapter adapterUserAccounts;
adapterUserAccounts = new UserAccountsNavAdapter(ctx, userAccountsList, drawer, toolbarTitle);
userAccountsApi.getAllAccounts().observe((AppCompatActivity) ctx, userAccounts -> {
if(userAccounts.size() > 0) {
userAccountsList.addAll(userAccounts);
navRecyclerViewUserAccounts.setAdapter(adapterUserAccounts);
}
});
userEmail.setTypeface(myTypeface); userEmail.setTypeface(myTypeface);
userFullName.setTypeface(myTypeface); userFullName.setTypeface(myTypeface);
String currentVersion = tinyDb.getString("giteaVersion");
navigationView.getMenu().findItem(R.id.nav_administration).setVisible(tinyDb.getBoolean("userIsAdmin"));
navigationView.getMenu().findItem(R.id.nav_notifications).setVisible(new Version(currentVersion).higherOrEqual("1.12.3"));
if(!userEmailNav.equals("")) { if(!userEmailNav.equals("")) {
userEmail.setText(userEmailNav); userEmail.setText(userEmailNav);
} }
@ -306,16 +269,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
drawer.closeDrawers(); drawer.closeDrawers();
}); });
String currentVersion = tinyDb.getString("giteaVersion");
navigationView.getMenu().findItem(R.id.nav_administration).setVisible(tinyDb.getBoolean("userIsAdmin"));
navigationView.getMenu().findItem(R.id.nav_notifications).setVisible(new Version(currentVersion).higherOrEqual("1.12.3"));
} }
@Override
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {}
@Override @Override
public void onDrawerClosed(@NonNull View drawerView) {} public void onDrawerClosed(@NonNull View drawerView) {}
@ -324,6 +285,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
}); });
ImageView userAccounts = hView.findViewById(R.id.userAccounts);
userAccounts.setOnClickListener(v -> {
toolbarTitle.setText(getResources().getString(R.string.pageTitleUserAccounts));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new UserAccountsFragment()).commit();
drawer.closeDrawers();
});
toggle.syncState(); toggle.syncState();
toolbar.setNavigationIcon(R.drawable.ic_menu); toolbar.setNavigationIcon(R.drawable.ic_menu);
@ -348,46 +317,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
} }
String launchFragmentByHandler = mainIntent.getStringExtra("launchFragmentByLinkHandler");
if(launchFragmentByHandler != null) {
mainIntent.removeExtra("launchFragmentByLinkHandler");
switch(launchFragmentByHandler) {
case "repos":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_repositories);
return;
case "org":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_organizations);
return;
case "notification":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_notifications);
return;
case "explore":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit();
navigationView.setCheckedItem(R.id.nav_explore);
return;
}
}
if(savedInstanceState == null) { if(savedInstanceState == null) {
if(!new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.3")) {
if(tinyDb.getInt("homeScreenId") == 7) {
tinyDb.putInt("homeScreenId", 0);
}
}
switch(tinyDb.getInt("homeScreenId")) { switch(tinyDb.getInt("homeScreenId")) {
case 1: case 1:
@ -416,7 +347,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
case 5: case 5:
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreRepositoriesFragment()).commit();
navigationView.setCheckedItem(R.id.nav_explore); navigationView.setCheckedItem(R.id.nav_explore);
break; break;
@ -426,12 +357,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
navigationView.setCheckedItem(R.id.nav_comments_draft); navigationView.setCheckedItem(R.id.nav_comments_draft);
break; break;
case 7:
toolbarTitle.setText(getResources().getString(R.string.pageTitleNotifications));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit();
navigationView.setCheckedItem(R.id.nav_notifications);
break;
default: default:
toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit();
@ -444,7 +369,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
if(!connToInternet) { if(!connToInternet) {
if(!tinyDb.getBoolean("noConnection")) { if(!tinyDb.getBoolean("noConnection")) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
} }
tinyDb.putBoolean("noConnection", true); tinyDb.putBoolean("noConnection", true);
@ -481,11 +406,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
} }
public void setActionBarTitle(String title) {
toolbarTitle.setText(title);
}
@Override @Override
public void onButtonClicked(String text) { public void onButtonClicked(String text) {
@ -501,18 +421,12 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
if(frag != null) { if(frag != null) {
new AlertDialog.Builder(ctx) new AlertDialog.Builder(ctx).setTitle(R.string.deleteAllDrafts).setIcon(R.drawable.ic_delete).setCancelable(false).setMessage(R.string.deleteAllDraftsDialogMessage).setPositiveButton(R.string.menuDeleteText, (dialog, which) -> {
.setTitle(R.string.deleteAllDrafts)
.setIcon(R.drawable.ic_delete)
.setCancelable(false)
.setMessage(R.string.deleteAllDraftsDialogMessage)
.setPositiveButton(R.string.menuDeleteText, (dialog, which) -> {
frag.deleteAllDrafts(currentActiveAccountId); frag.deleteAllDrafts(currentActiveAccountId);
dialog.dismiss(); dialog.dismiss();
}) }).setNegativeButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss()).show();
.setNeutralButton(R.string.cancelButton, null).show();
} }
else { else {
@ -528,6 +442,20 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
public void getAccountData(String accountName) {
UserAccountsApi accountData = new UserAccountsApi(ctx);
UserAccount data = accountData.getAccountData(accountName);
if(data != null) {
TinyDB tinyDb = new TinyDB(ctx.getApplicationContext());
tinyDb.putInt("currentActiveAccountId", data.getAccountId());
}
else {
AlertDialogs.forceLogoutDialog(ctx, getResources().getString(R.string.forceLogoutDialogHeader), getResources().getString(R.string.forceLogoutDialogDescription), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
}
}
@Override @Override
public void onBackPressed() { public void onBackPressed() {
@ -575,6 +503,15 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
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:
toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit();
break;
case R.id.nav_rate_app:
rateThisApp();
break;
case R.id.nav_starred_repos: case R.id.nav_starred_repos:
toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit();
@ -582,7 +519,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
case R.id.nav_explore: case R.id.nav_explore:
toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreRepositoriesFragment()).commit();
break; break;
case R.id.nav_notifications: case R.id.nav_notifications:
@ -606,8 +543,19 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
return true; return true;
} }
public void rateThisApp() {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName())));
}
catch(ActivityNotFoundException e) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())));
}
}
public static void logout(Activity activity, Context ctx) { public static void logout(Activity activity, Context ctx) {
TinyDB tinyDb = new TinyDB(ctx.getApplicationContext());
tinyDb.putBoolean("loggedInMode", false); tinyDb.putBoolean("loggedInMode", false);
tinyDb.remove("basicAuthPassword"); tinyDb.remove("basicAuthPassword");
tinyDb.putBoolean("basicAuthFlag", false); tinyDb.putBoolean("basicAuthFlag", false);
@ -717,7 +665,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
else { else {
String toastError = getResources().getString(R.string.genericApiStatusError) + response.code(); String toastError = getResources().getString(R.string.genericApiStatusError) + response.code();
Toasty.error(ctx, toastError); Toasty.info(ctx, toastError);
} }
@ -732,31 +680,4 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} }
private void getNotificationsCount(String instanceUrl, String token) {
Call<NotificationCount> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkUnreadNotifications(token);
call.enqueue(new Callback<NotificationCount>() {
@Override
public void onResponse(@NonNull Call<NotificationCount> call, @NonNull retrofit2.Response<NotificationCount> response) {
NotificationCount notificationCount = response.body();
if(response.code() == 200) {
assert notificationCount != null;
notificationCounter = navNotifications.getActionView().findViewById(R.id.counterBadgeNotification);
notificationCounter.setText(String.valueOf(notificationCount.getCounter()));
}
}
@Override
public void onFailure(@NonNull Call<NotificationCount> call, @NonNull Throwable t) {
Log.e("onFailure-notification", t.toString());
}
});
}
} }

View File

@ -6,9 +6,12 @@ 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.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityMergePullRequestBinding; import org.mian.gitnex.databinding.ActivityMergePullRequestBinding;
@ -18,13 +21,15 @@ import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
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.models.MergePullRequestSpinner;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.List;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -35,17 +40,9 @@ public class MergePullRequestActivity extends BaseActivity {
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private TinyDB tinyDb;
private String instanceUrl;
private String loginUid;
private String instanceToken;
private String repoOwner;
private String repoName;
private int prIndex;
private ActivityMergePullRequestBinding viewBinding; private ActivityMergePullRequestBinding viewBinding;
private ArrayAdapter<Mention> defaultMentionAdapter;
private String Do; private String Do;
@Override @Override
@ -60,22 +57,13 @@ public class MergePullRequestActivity extends BaseActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
viewBinding = ActivityMergePullRequestBinding.inflate(getLayoutInflater()); viewBinding = ActivityMergePullRequestBinding.inflate(getLayoutInflater());
View view = viewBinding.getRoot(); View view = viewBinding.getRoot();
setContentView(view); setContentView(view);
instanceUrl = tinyDb.getString("instanceUrl");
loginUid = tinyDb.getString("loginUid");
instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
repoOwner = parts[0];
repoName = parts[1];
prIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
TinyDB tinyDb = new TinyDB(appCtx);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -85,8 +73,29 @@ public class MergePullRequestActivity extends BaseActivity {
setMergeAdapter(); setMergeAdapter();
if(!tinyDb.getString("issueTitle").isEmpty()) { viewBinding.mergeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
MergePullRequestSpinner mergeId = (MergePullRequestSpinner) parent.getSelectedItem();
Do = mergeId.getId();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
defaultMentionAdapter = new MentionArrayAdapter<>(this);
loadCollaboratorsList();
viewBinding.mergeDescription.setMentionAdapter(defaultMentionAdapter);
if(!tinyDb.getString("issueTitle").isEmpty()) {
viewBinding.toolbarTitle.setText(tinyDb.getString("issueTitle")); viewBinding.toolbarTitle.setText(tinyDb.getString("issueTitle"));
viewBinding.mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber") + ")"); viewBinding.mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber") + ")");
} }
@ -117,16 +126,20 @@ public class MergePullRequestActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
disableProcessButton(); disableProcessButton();
} }
else { else {
viewBinding.mergeButton.setOnClickListener(mergePullRequest); viewBinding.mergeButton.setOnClickListener(mergePullRequest);
} }
} }
private void setMergeAdapter() { private void setMergeAdapter() {
TinyDB tinyDb = new TinyDB(appCtx);
ArrayList<MergePullRequestSpinner> mergeList = new ArrayList<>(); ArrayList<MergePullRequestSpinner> mergeList = new ArrayList<>();
mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge))); mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge)));
@ -137,14 +150,58 @@ public class MergePullRequestActivity extends BaseActivity {
mergeList.add(new MergePullRequestSpinner("squash", getResources().getString(R.string.mergeOptionSquash))); mergeList.add(new MergePullRequestSpinner("squash", getResources().getString(R.string.mergeOptionSquash)));
} }
ArrayAdapter<MergePullRequestSpinner> adapter = new ArrayAdapter<>(MergePullRequestActivity.this, R.layout.list_spinner_items, mergeList); ArrayAdapter<MergePullRequestSpinner> adapter = new ArrayAdapter<>(MergePullRequestActivity.this, R.layout.spinner_item, mergeList);
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
viewBinding.mergeSpinner.setAdapter(adapter); viewBinding.mergeSpinner.setAdapter(adapter);
viewBinding.mergeSpinner.setOnItemClickListener ((parent, view, position, id) -> { }
public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
if(response.isSuccessful()) {
assert response.body() != null;
String fullName = "";
for(int i = 0; i < response.body().size(); i++) {
if(!response.body().get(i).getFull_name().equals("")) {
fullName = response.body().get(i).getFull_name();
}
defaultMentionAdapter.add(new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
}
}
else {
Log.i("onResponse", String.valueOf(response.code()));
}
}
@Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
Log.i("onFailure", t.toString());
}
Do = mergeList.get(position).getId();
}); });
} }
private void initCloseListener() { private void initCloseListener() {
@ -156,31 +213,37 @@ public class MergePullRequestActivity extends BaseActivity {
private void processMergePullRequest() { private void processMergePullRequest() {
String mergePRDesc = Objects.requireNonNull(viewBinding.mergeDescription.getText()).toString(); String mergePRDesc = viewBinding.mergeDescription.getText().toString();
String mergePRTitle = Objects.requireNonNull(viewBinding.mergeTitle.getText()).toString(); String mergePRTitle = viewBinding.mergeTitle.getText().toString();
boolean deleteBranch = viewBinding.deleteBranch.isChecked(); boolean deleteBranch = viewBinding.deleteBranch.isChecked();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
}
if(Do == null) {
Toasty.error(ctx, getResources().getString(R.string.selectMergeStrategy));
} }
else {
disableProcessButton(); disableProcessButton();
mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch); mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch);
}
} }
private void mergeFunction(String Do, String mergePRDT, String mergeTitle, boolean deleteBranch) { private void mergeFunction(String Do, String mergePRDT, String mergeTitle, boolean deleteBranch) {
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
final int prIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle); MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle);
Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().mergePullRequest(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR); Call<ResponseBody> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().mergePullRequest(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR);
@ -203,10 +266,11 @@ public class MergePullRequestActivity extends BaseActivity {
deleteBranchFunction(repoOwner, repoName); deleteBranchFunction(repoOwner, repoName);
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg)); Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true); tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true); tinyDb.putBoolean("resumePullRequests", true);
finish(); finish();
} }
else { else {
@ -217,19 +281,21 @@ public class MergePullRequestActivity extends BaseActivity {
deleteBranchFunction(repoOwner, repoName); deleteBranchFunction(repoOwner, repoName);
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg)); Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true); tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true); tinyDb.putBoolean("resumePullRequests", true);
finish(); finish();
} }
} }
else { else {
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg)); Toasty.info(ctx, getString(R.string.mergePRSuccessMsg));
tinyDb.putBoolean("prMerged", true); tinyDb.putBoolean("prMerged", true);
tinyDb.putBoolean("resumePullRequests", true); tinyDb.putBoolean("resumePullRequests", true);
finish(); finish();
} }
} }
@ -237,16 +303,19 @@ public class MergePullRequestActivity extends BaseActivity {
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) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, getString(R.string.mergePR404ErrorMsg)); Toasty.info(ctx, getString(R.string.mergePR404ErrorMsg));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, getString(R.string.genericError)); Toasty.info(ctx, getString(R.string.genericError));
} }
} }
@ -264,6 +333,11 @@ public class MergePullRequestActivity extends BaseActivity {
private void deleteBranchFunction(String repoOwner, String repoName) { private void deleteBranchFunction(String repoOwner, String repoName) {
TinyDB tinyDb = new TinyDB(appCtx);
String instanceUrl = tinyDb.getString("instanceUrl");
String loginUid = tinyDb.getString("loginUid");
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String branchName = tinyDb.getString("prHeadBranch"); String branchName = tinyDb.getString("prHeadBranch");
Call<JsonElement> call = RetrofitClient Call<JsonElement> call = RetrofitClient
@ -279,6 +353,7 @@ public class MergePullRequestActivity extends BaseActivity {
if(response.code() == 204) { if(response.code() == 204) {
Log.i("deleteBranch", "Branch deleted successfully"); Log.i("deleteBranch", "Branch deleted successfully");
} }
} }
@ -288,6 +363,7 @@ public class MergePullRequestActivity extends BaseActivity {
Log.e("onFailure", t.toString()); Log.e("onFailure", t.toString());
enableProcessButton(); enableProcessButton();
} }
}); });
@ -297,11 +373,15 @@ public class MergePullRequestActivity extends BaseActivity {
private void disableProcessButton() { private void disableProcessButton() {
viewBinding.mergeButton.setEnabled(false); viewBinding.mergeButton.setEnabled(false);
viewBinding.mergeButton.setBackground(getResources().getDrawable(R.drawable.shape_buttons_disabled));
} }
private void enableProcessButton() { private void enableProcessButton() {
viewBinding.mergeButton.setEnabled(true); viewBinding.mergeButton.setEnabled(true);
viewBinding.mergeButton.setBackground(getResources().getDrawable(R.drawable.shape_buttons));
} }
} }

View File

@ -30,9 +30,7 @@ public class OpenRepoInBrowserActivity extends AppCompatActivity {
try { try {
URI instanceUrl = new URI(UrlBuilder.fromString(tinyDb.getString("instanceUrl")) URI instanceUrl = new URI(tinyDb.getString("instanceUrlWithProtocol"));
.withPath("/")
.toString());
String browserPath = PathsHelper.join(instanceUrl.getPath(), getIntent().getStringExtra("repoFullNameBrowser")); String browserPath = PathsHelper.join(instanceUrl.getPath(), getIntent().getStringExtra("repoFullNameBrowser"));

View File

@ -1,7 +1,5 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -26,9 +24,7 @@ import org.mian.gitnex.fragments.OrganizationInfoFragment;
import org.mian.gitnex.fragments.RepositoriesByOrgFragment; import org.mian.gitnex.fragments.RepositoriesByOrgFragment;
import org.mian.gitnex.fragments.TeamsByOrgFragment; import org.mian.gitnex.fragments.TeamsByOrgFragment;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.Objects; import java.util.Objects;
import io.mikael.urlbuilder.UrlBuilder;
/** /**
* Author M M Arif * Author M M Arif
@ -38,7 +34,6 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
private TinyDB tinyDb;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -50,7 +45,6 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
appCtx = getApplicationContext(); appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
TinyDB tinyDb = new TinyDB(appCtx); TinyDB tinyDb = new TinyDB(appCtx);
String orgName = tinyDb.getString("orgName"); String orgName = tinyDb.getString("orgName");
@ -111,7 +105,6 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@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;
@ -139,28 +132,19 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@Override @Override
public void onButtonClicked(String text) { public void onButtonClicked(String text) {
TinyDB tinyDb = new TinyDB(appCtx);
switch (text) { switch (text) {
case "repository": case "repository":
tinyDb.putBoolean("organizationAction", true); tinyDb.putBoolean("organizationAction", true);
startActivity(new Intent(OrganizationDetailActivity.this, CreateRepoActivity.class)); startActivity(new Intent(OrganizationDetailActivity.this, CreateRepoActivity.class));
break; break;
case "team": case "team":
startActivity(new Intent(OrganizationDetailActivity.this, CreateTeamByOrgActivity.class)); startActivity(new Intent(OrganizationDetailActivity.this, CreateTeamByOrgActivity.class));
break; break;
case "copyOrgUrl":
String url = UrlBuilder.fromString(tinyDb.getString("instanceUrl"))
.withPath("/")
.toString();
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("orgUrl", url + tinyDb.getString("orgName"));
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg));
break;
} }
//Log.i("clicked", text);
} }
public class SectionsPagerAdapter extends FragmentPagerAdapter { public class SectionsPagerAdapter extends FragmentPagerAdapter {
@ -173,6 +157,7 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh
@Override @Override
public Fragment getItem(int position) { public Fragment getItem(int position) {
TinyDB tinyDb = new TinyDB(appCtx);
String orgName; String orgName;
if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) { if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) {
orgName = getIntent().getStringExtra("orgName"); orgName = getIntent().getStringExtra("orgName");

View File

@ -9,7 +9,6 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.GridView; import android.widget.GridView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@ -31,7 +30,6 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private TeamMembersByOrgAdapter adapter; private TeamMembersByOrgAdapter adapter;
private GridView mGridView; private GridView mGridView;
private ProgressBar progressBar;
final Context ctx = this; final Context ctx = this;
private Context appCtx; private Context appCtx;
@ -60,7 +58,6 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot
TextView toolbarTitle = findViewById(R.id.toolbar_title); TextView toolbarTitle = findViewById(R.id.toolbar_title);
noDataMembers = findViewById(R.id.noDataMembers); noDataMembers = findViewById(R.id.noDataMembers);
mGridView = findViewById(R.id.gridView); mGridView = findViewById(R.id.gridView);
progressBar = findViewById(R.id.progressBar);
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
@ -117,7 +114,6 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot
noDataMembers.setVisibility(View.VISIBLE); noDataMembers.setVisibility(View.VISIBLE);
} }
progressBar.setVisibility(View.GONE);
}); });
} }

View File

@ -1,6 +1,7 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.util.Patterns; import android.util.Patterns;
@ -66,9 +67,11 @@ public class ProfileEmailActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
disableProcessButton(); disableProcessButton();
} else { } else {
addEmailButton.setOnClickListener(addEmailListener); addEmailButton.setOnClickListener(addEmailListener);
} }
} }
@ -91,20 +94,20 @@ public class ProfileEmailActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newUserEmail.equals("")) { if(newUserEmail.equals("")) {
Toasty.error(ctx, getString(R.string.emailErrorEmpty)); Toasty.info(ctx, getString(R.string.emailErrorEmpty));
return; return;
} }
else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
Toasty.warning(ctx, getString(R.string.emailErrorInvalid)); Toasty.info(ctx, getString(R.string.emailErrorInvalid));
return; return;
} }
@ -135,7 +138,7 @@ public class ProfileEmailActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.success(ctx, getString(R.string.emailAddedText)); Toasty.info(ctx, getString(R.string.emailAddedText));
tinyDb.putBoolean("emailsRefresh", true); tinyDb.putBoolean("emailsRefresh", true);
enableProcessButton(); enableProcessButton();
finish(); finish();
@ -153,25 +156,25 @@ public class ProfileEmailActivity extends BaseActivity {
else if(response.code() == 403) { else if(response.code() == 403) {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else if(response.code() == 422) { else if(response.code() == 422) {
enableProcessButton(); enableProcessButton();
Toasty.warning(ctx, ctx.getString(R.string.emailErrorInUse)); Toasty.info(ctx, ctx.getString(R.string.emailErrorInUse));
} }
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, getString(R.string.labelGeneralError)); Toasty.info(ctx, getString(R.string.labelGeneralError));
} }
@ -187,18 +190,32 @@ public class ProfileEmailActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
private void disableProcessButton() { private void disableProcessButton() {
addEmailButton.setEnabled(false); addEmailButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.hintColor));
addEmailButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
addEmailButton.setEnabled(true); addEmailButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setColor(getResources().getColor(R.color.btnBackground));
addEmailButton.setBackground(shape);
} }
} }

View File

@ -2,6 +2,7 @@ package org.mian.gitnex.activities;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -11,12 +12,15 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
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.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import com.hendraanggrian.appcompat.socialview.Mention;
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.IssueActions; import org.mian.gitnex.actions.IssueActions;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
@ -27,10 +31,12 @@ import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Issues;
import java.util.Objects; import java.util.List;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response;
/** /**
* Author M M Arif * Author M M Arif
@ -45,10 +51,11 @@ public class ReplyToIssueActivity extends BaseActivity {
private Context appCtx; private Context appCtx;
private TextView draftSaved; private TextView draftSaved;
private EditText addComment; private SocialAutoCompleteTextView addComment;
private ArrayAdapter<Mention> defaultMentionAdapter;
private Button replyButton; private Button replyButton;
private String TAG = StaticGlobalVariables.replyToIssueActivity; private String TAG = StaticGlobalVariables.replyToIssueActivity;
private long draftIdOnCreate; private long draftId;
@Override @Override
protected int getLayoutResourceId(){ protected int getLayoutResourceId(){
@ -72,6 +79,11 @@ public class ReplyToIssueActivity extends BaseActivity {
addComment = findViewById(R.id.addComment); addComment = findViewById(R.id.addComment);
addComment.setShowSoftInputOnFocus(true); addComment.setShowSoftInputOnFocus(true);
defaultMentionAdapter = new MentionArrayAdapter<>(ctx);
loadCollaboratorsList();
addComment.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);
@ -86,20 +98,6 @@ public class ReplyToIssueActivity extends BaseActivity {
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
if(getIntent().getStringExtra("draftId") != null) {
draftIdOnCreate = Long.parseLong(Objects.requireNonNull(getIntent().getStringExtra("draftId")));
}
else {
if(getIntent().getStringExtra("commentBody") != null) {
draftIdOnCreate = returnDraftId(getIntent().getStringExtra("commentBody"));
}
else {
draftIdOnCreate = returnDraftId("");
}
}
replyButton = findViewById(R.id.replyButton); replyButton = findViewById(R.id.replyButton);
if(getIntent().getStringExtra("commentBody") != null) { if(getIntent().getStringExtra("commentBody") != null) {
@ -109,14 +107,16 @@ public class ReplyToIssueActivity extends BaseActivity {
if(getIntent().getBooleanExtra("cursorToEnd", false)) { if(getIntent().getBooleanExtra("cursorToEnd", false)) {
addComment.setSelection(addComment.length()); addComment.setSelection(addComment.length());
} }
} }
if(getIntent().getStringExtra("draftTitle") != null) { if(getIntent().getStringExtra("draftTitle") != null) {
toolbar_title.setText(getIntent().getStringExtra("draftTitle")); toolbar_title.setText(getIntent().getStringExtra("draftTitle"));
} }
if(getIntent().getStringExtra("commentAction") != null && Objects.equals(getIntent().getStringExtra("commentAction"), "edit") && !Objects.equals(getIntent().getStringExtra("commentId"), "new")) { if(getIntent().getStringExtra("commentAction") != null && getIntent().getStringExtra("commentAction").equals("edit")) {
final String commentId = getIntent().getStringExtra("commentId"); final String commentId = getIntent().getStringExtra("commentId");
@ -130,12 +130,14 @@ public class ReplyToIssueActivity extends BaseActivity {
} }
public void beforeTextChanged(CharSequence s, int start, int count, int after) { public void beforeTextChanged(CharSequence s, int start, int count, int after) {
} }
public void onTextChanged(CharSequence s, int start, int before, int count) { public void onTextChanged(CharSequence s, int start, int before, int count) {
saveDraft(addComment.getText().toString(), commentId, draftIdOnCreate); saveDraft(addComment.getText().toString());
draftSaved.setVisibility(View.VISIBLE); draftSaved.setVisibility(View.VISIBLE);
} }
}); });
@ -144,7 +146,8 @@ public class ReplyToIssueActivity extends BaseActivity {
disableProcessButton(); disableProcessButton();
assert commentId != null; assert commentId != null;
IssueActions.editIssueComment(ctx, Integer.parseInt(commentId), addComment.getText().toString(), draftIdOnCreate); IssueActions.editIssueComment(ctx, Integer.parseInt(commentId), addComment.getText().toString());
}); });
return; return;
@ -154,15 +157,18 @@ public class ReplyToIssueActivity extends BaseActivity {
addComment.addTextChangedListener(new TextWatcher() { addComment.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
} }
public void beforeTextChanged(CharSequence s, int start, int count, int after) { public void beforeTextChanged(CharSequence s, int start, int count, int after) {
} }
public void onTextChanged(CharSequence s, int start, int before, int count) { public void onTextChanged(CharSequence s, int start, int before, int count) {
saveDraft(addComment.getText().toString(), "new", draftIdOnCreate); saveDraft(addComment.getText().toString());
draftSaved.setVisibility(View.VISIBLE); draftSaved.setVisibility(View.VISIBLE);
} }
}); });
@ -170,15 +176,17 @@ public class ReplyToIssueActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
disableProcessButton(); disableProcessButton();
} }
else { else {
replyButton.setOnClickListener(replyToIssue); replyButton.setOnClickListener(replyToIssue);
} }
} }
private void saveDraft(String draftText, String commentId, long draftIdOnCreate) { private void saveDraft(String draftText) {
TinyDB tinyDb = new TinyDB(getApplicationContext()); TinyDB tinyDb = new TinyDB(getApplicationContext());
@ -188,28 +196,66 @@ public class ReplyToIssueActivity extends BaseActivity {
DraftsApi draftsApi = new DraftsApi(appCtx); DraftsApi draftsApi = new DraftsApi(appCtx);
if(draftIdOnCreate == 0) { int countDraft = draftsApi.checkDraft(issueNumber, repositoryId);
if(countDraft == 0) {
draftId = draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, draftText, StaticGlobalVariables.draftTypeComment);
}
else {
DraftsApi.updateDraftByIssueIdAsyncTask(draftText, issueNumber, repositoryId);
}
}
public void loadCollaboratorsList() {
final TinyDB tinyDb = new TinyDB(appCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
final String loginUid = tinyDb.getString("loginUid");
final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
Call<List<Collaborators>> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
call.enqueue(new Callback<List<Collaborators>>() {
@Override
public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
if (response.isSuccessful()) {
assert response.body() != null;
String fullName = "";
for(int i = 0; i < response.body().size(); i++) {
if(!response.body().get(i).getFull_name().equals("")) {
fullName = response.body().get(i).getFull_name();
}
defaultMentionAdapter.add(new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
}
draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, draftText, StaticGlobalVariables.draftTypeComment, commentId);
} }
else { else {
DraftsApi.updateDraft(draftText, (int) draftIdOnCreate, commentId); //updateDraftByIssueIdAsyncTask(draftText, issueNumber, repositoryId, commentId); Log.i(TAG, String.valueOf(response.code()));
}
} }
private long returnDraftId(String draftText) { }
TinyDB tinyDb = new TinyDB(getApplicationContext()); @Override
public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
int repositoryId = (int) tinyDb.getLong("repositoryId", 0); Log.e(TAG, t.toString());
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId"); }
int issueNumber = Integer.parseInt(tinyDb.getString("issueNumber"));
DraftsApi draftsApi = new DraftsApi(appCtx);
return draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, draftText, StaticGlobalVariables.draftTypeComment, "");
});
} }
private void initCloseListener() { private void initCloseListener() {
@ -226,18 +272,21 @@ public class ReplyToIssueActivity extends BaseActivity {
if(!connToInternet) { if(!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Toasty.info(ctx, getResources().getString(R.string.checkNetConnection));
return; return;
} }
if(newReplyDT.equals("")) { if(newReplyDT.equals("")) {
Toasty.error(ctx, getString(R.string.commentEmptyError)); Toasty.info(ctx, getString(R.string.commentEmptyError));
} }
else { else {
disableProcessButton(); disableProcessButton();
replyComment(newReplyDT); replyComment(newReplyDT);
} }
} }
@ -269,7 +318,7 @@ public class ReplyToIssueActivity extends BaseActivity {
if(response.code() == 201) { if(response.code() == 201) {
Toasty.success(ctx, getString(R.string.commentSuccess)); Toasty.info(ctx, getString(R.string.commentSuccess));
tinyDb.putBoolean("commentPosted", true); tinyDb.putBoolean("commentPosted", true);
tinyDb.putBoolean("resumeIssues", true); tinyDb.putBoolean("resumeIssues", true);
tinyDb.putBoolean("resumePullRequests", true); tinyDb.putBoolean("resumePullRequests", true);
@ -277,8 +326,12 @@ public class ReplyToIssueActivity extends BaseActivity {
// delete draft comment // delete draft comment
if(tinyDb.getBoolean("draftsCommentsDeletionEnabled")) { if(tinyDb.getBoolean("draftsCommentsDeletionEnabled")) {
int repositoryId = (int) tinyDb.getLong("repositoryId", 0);
int issueNumber = Integer.parseInt(tinyDb.getString("issueNumber"));
DraftsApi draftsApi = new DraftsApi(appCtx); DraftsApi draftsApi = new DraftsApi(appCtx);
draftsApi.deleteSingleDraft((int) draftIdOnCreate); draftId = draftsApi.getDraftIdAsync(issueNumber, repositoryId);
draftsApi.deleteSingleDraft((int) draftId);
} }
finish(); finish();
@ -296,7 +349,7 @@ public class ReplyToIssueActivity extends BaseActivity {
else { else {
enableProcessButton(); enableProcessButton();
Toasty.error(ctx, getString(R.string.commentError)); Toasty.info(ctx, getString(R.string.commentError));
} }
@ -344,11 +397,21 @@ public class ReplyToIssueActivity extends BaseActivity {
private void disableProcessButton() { private void disableProcessButton() {
replyButton.setEnabled(false); replyButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.hintColor));
replyButton.setBackground(shape);
} }
private void enableProcessButton() { private void enableProcessButton() {
replyButton.setEnabled(true); replyButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.btnBackground));
replyButton.setBackground(shape);
} }
} }

View File

@ -1,8 +1,6 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
@ -33,6 +31,7 @@ import org.mian.gitnex.fragments.BottomSheetIssuesFilterFragment;
import org.mian.gitnex.fragments.BottomSheetMilestonesFilterFragment; import org.mian.gitnex.fragments.BottomSheetMilestonesFilterFragment;
import org.mian.gitnex.fragments.BottomSheetPullRequestFilterFragment; import org.mian.gitnex.fragments.BottomSheetPullRequestFilterFragment;
import org.mian.gitnex.fragments.BottomSheetRepoFragment; import org.mian.gitnex.fragments.BottomSheetRepoFragment;
import org.mian.gitnex.fragments.BranchesFragment;
import org.mian.gitnex.fragments.CollaboratorsFragment; import org.mian.gitnex.fragments.CollaboratorsFragment;
import org.mian.gitnex.fragments.FilesFragment; import org.mian.gitnex.fragments.FilesFragment;
import org.mian.gitnex.fragments.IssuesFragment; import org.mian.gitnex.fragments.IssuesFragment;
@ -43,7 +42,6 @@ import org.mian.gitnex.fragments.ReleasesFragment;
import org.mian.gitnex.fragments.RepoInfoFragment; import org.mian.gitnex.fragments.RepoInfoFragment;
import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
@ -83,7 +81,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
private String repositoryOwner; private String repositoryOwner;
private String repositoryName; private String repositoryName;
public static ViewPager mViewPager;
private int tabsCount; private int tabsCount;
@Override @Override
@ -162,7 +159,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
} }
// Only show collaborators tab, if you have permission to // Only show collaborators tab, if you have permission to
View collaboratorTab = viewGroup.getChildAt(7); View collaboratorTab = viewGroup.getChildAt(8);
if(tinyDB.getBoolean("isRepoAdmin") || new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { if(tinyDB.getBoolean("isRepoAdmin") || new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) {
@ -175,7 +172,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
} }
mViewPager = findViewById(R.id.container); ViewPager mViewPager = findViewById(R.id.container);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)); tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
@ -228,8 +225,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
if(textViewBadgeRelease.getText() != "") { // only show if API returned a number if(textViewBadgeRelease.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(4)).setCustomView(tabHeader6); Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(4); TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5);
assert tabOpenRelease != null; // FIXME This should be cleaned up assert tabOpenRelease != null; // FIXME This should be cleaned up
TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText); TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText);
openReleaseTabView.setTextColor(textColor); openReleaseTabView.setTextColor(textColor);
@ -238,25 +235,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
} }
} }
Intent mainIntent = getIntent();
String goToSection = mainIntent.getStringExtra("goToSection");
String goToSectionType = mainIntent.getStringExtra("goToSectionType");
if(goToSection != null) {
mainIntent.removeExtra("goToSection");
mainIntent.removeExtra("goToSectionType");
if(goToSectionType.equals("issue")) {
RepoDetailActivity.mViewPager.setCurrentItem(2);
}
else if(goToSectionType.equals("pull")) {
RepoDetailActivity.mViewPager.setCurrentItem(3);
}
}
checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName); checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName); checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName);
@ -318,12 +296,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
chooseBranch(); chooseBranch();
return true; return true;
case R.id.branchCommits:
Intent intent = new Intent(ctx, CommitsActivity.class);
intent.putExtra("branchName", tinyDB.getString("repoBranch"));
ctx.startActivity(intent);
return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
@ -373,14 +345,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
startActivity(Intent.createChooser(sharingIntent, tinyDB.getString("repoHtmlUrl"))); startActivity(Intent.createChooser(sharingIntent, tinyDB.getString("repoHtmlUrl")));
break; break;
case "copyRepoUrl":
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", tinyDB.getString("repoHtmlUrl"));
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg));
break;
case "newFile": case "newFile":
startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class)); startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class));
break; break;
@ -421,14 +385,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
} }
break; break;
case "repoSettings":
startActivity(new Intent(RepoDetailActivity.this, RepositorySettingsActivity.class));
break;
case "newPullRequest":
startActivity(new Intent(RepoDetailActivity.this, CreatePullRequestActivity.class));
break;
} }
} }
@ -476,7 +432,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
dialogInterface.dismiss(); dialogInterface.dismiss();
} }
}); });
pBuilder.setNeutralButton(R.string.cancelButton, null);
pBuilder.create().show(); pBuilder.create().show();
@ -522,17 +477,20 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
fragment = new PullRequestsFragment(); fragment = new PullRequestsFragment();
break; break;
case 4: // Releases case 4: // Branches
return BranchesFragment.newInstance(repositoryOwner, repositoryName);
case 5: // Releases
return ReleasesFragment.newInstance(repositoryOwner, repositoryName); return ReleasesFragment.newInstance(repositoryOwner, repositoryName);
case 5: // Milestones case 6: // Milestones
fragment = new MilestonesFragment(); fragment = new MilestonesFragment();
break; break;
case 6: // Labels case 7: // Labels
return LabelsFragment.newInstance(repositoryOwner, repositoryName); return LabelsFragment.newInstance(repositoryOwner, repositoryName);
case 7: // Collaborators case 8: // Collaborators
return CollaboratorsFragment.newInstance(repositoryOwner, repositoryName); return CollaboratorsFragment.newInstance(repositoryOwner, repositoryName);
} }

View File

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

View File

@ -93,8 +93,12 @@ public class RepoStargazersActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
} }

View File

@ -93,8 +93,12 @@ public class RepoWatchersActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = new View.OnClickListener() {
onClickListener = view -> finish(); @Override
public void onClick(View view) {
finish();
}
};
} }
} }

View File

@ -1,435 +0,0 @@
package org.mian.gitnex.activities;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import com.google.gson.JsonElement;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.databinding.ActivityRepositorySettingsBinding;
import org.mian.gitnex.databinding.CustomRepositoryDeleteDialogBinding;
import org.mian.gitnex.databinding.CustomRepositoryEditPropertiesDialogBinding;
import org.mian.gitnex.databinding.CustomRepositoryTransferDialogBinding;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.RepositoryTransfer;
import org.mian.gitnex.models.UserRepositories;
import retrofit2.Call;
import retrofit2.Callback;
/**
* Author M M Arif
*/
public class RepositorySettingsActivity extends BaseActivity {
private ActivityRepositorySettingsBinding viewBinding;
private CustomRepositoryEditPropertiesDialogBinding propBinding;
private CustomRepositoryDeleteDialogBinding deleteRepoBinding;
private CustomRepositoryTransferDialogBinding transferRepoBinding;
private Dialog dialogProp;
private Dialog dialogDeleteRepository;
private Dialog dialogTransferRepository;
private View.OnClickListener onClickListener;
private Context ctx = this;
private Context appCtx;
private TinyDB tinyDb;
private String instanceUrl;
private String loginUid;
private String instanceToken;
private String repositoryOwner;
private String repositoryName;
@Override
protected int getLayoutResourceId(){
return R.layout.activity_repository_settings;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
tinyDb = new TinyDB(appCtx);
viewBinding = ActivityRepositorySettingsBinding.inflate(getLayoutInflater());
View view = viewBinding.getRoot();
setContentView(view);
instanceUrl = tinyDb.getString("instanceUrl");
loginUid = tinyDb.getString("loginUid");
String repoFullName = tinyDb.getString("repoFullName");
String[] parts = repoFullName.split("/");
repositoryOwner = parts[0];
repositoryName = parts[1];
instanceToken = "token " + tinyDb.getString(loginUid + "-token");
ImageView closeActivity = findViewById(R.id.close);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
// require gitea 1.12 or higher
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
viewBinding.transferOwnerFrame.setVisibility(View.VISIBLE);
}
viewBinding.editProperties.setOnClickListener(editProperties -> {
showRepositoryProperties();
});
viewBinding.deleteRepository.setOnClickListener(deleteRepository -> {
showDeleteRepository();
});
viewBinding.transferOwnerFrame.setOnClickListener(transferRepositoryOwnership -> {
showTransferRepository();
});
}
private void showTransferRepository() {
dialogTransferRepository = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
if (dialogTransferRepository.getWindow() != null) {
dialogTransferRepository.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
transferRepoBinding = CustomRepositoryTransferDialogBinding.inflate(LayoutInflater.from(ctx));
View view = transferRepoBinding.getRoot();
dialogTransferRepository.setContentView(view);
transferRepoBinding.cancel.setOnClickListener(editProperties -> {
dialogTransferRepository.dismiss();
});
transferRepoBinding.transfer.setOnClickListener(deleteRepo -> {
String newOwner = String.valueOf(transferRepoBinding.ownerNameForTransfer.getText());
String repoName = String.valueOf(transferRepoBinding.repoNameForTransfer.getText());
if(!repositoryName.equals(repoName)) {
Toasty.error(ctx, getString(R.string.repoSettingsDeleteError));
}
else if(newOwner.matches("")) {
Toasty.error(ctx, getString(R.string.repoTransferOwnerError));
}
else {
transferRepository(newOwner);
}
});
dialogTransferRepository.show();
}
private void transferRepository(String newOwner) {
RepositoryTransfer repositoryTransfer = new RepositoryTransfer(newOwner);
Call<JsonElement> transferCall = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.transferRepository(instanceToken, repositoryOwner, repositoryName, repositoryTransfer);
transferCall.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
transferRepoBinding.transfer.setVisibility(View.GONE);
transferRepoBinding.processingRequest.setVisibility(View.VISIBLE);
if (response.code() == 202) {
dialogTransferRepository.dismiss();
Toasty.success(ctx, getString(R.string.repoTransferSuccess));
finish();
RepositoriesApi.deleteRepository((int) tinyDb.getLong("repositoryId", 0));
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
RepositorySettingsActivity.this.startActivity(intent);
}
else if (response.code() == 404) {
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
transferRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.repoTransferError));
}
else {
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
transferRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
transferRepoBinding.transfer.setVisibility(View.VISIBLE);
transferRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
}
private void showDeleteRepository() {
dialogDeleteRepository = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
if (dialogDeleteRepository.getWindow() != null) {
dialogDeleteRepository.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
deleteRepoBinding = CustomRepositoryDeleteDialogBinding.inflate(LayoutInflater.from(ctx));
View view = deleteRepoBinding.getRoot();
dialogDeleteRepository.setContentView(view);
deleteRepoBinding.cancel.setOnClickListener(editProperties -> {
dialogDeleteRepository.dismiss();
});
deleteRepoBinding.delete.setOnClickListener(deleteRepo -> {
if(!repositoryName.equals(String.valueOf(deleteRepoBinding.repoNameForDeletion.getText()))) {
Toasty.error(ctx, getString(R.string.repoSettingsDeleteError));
}
else {
deleteRepository();
}
});
dialogDeleteRepository.show();
}
private void deleteRepository() {
Call<JsonElement> deleteCall = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.deleteRepository(instanceToken, repositoryOwner, repositoryName);
deleteCall.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
deleteRepoBinding.delete.setVisibility(View.GONE);
deleteRepoBinding.processingRequest.setVisibility(View.VISIBLE);
if (response.code() == 204) {
dialogDeleteRepository.dismiss();
Toasty.success(ctx, getString(R.string.repoDeletionSuccess));
finish();
RepositoriesApi.deleteRepository((int) tinyDb.getLong("repositoryId", 0));
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
RepositorySettingsActivity.this.startActivity(intent);
}
else {
deleteRepoBinding.delete.setVisibility(View.VISIBLE);
deleteRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
deleteRepoBinding.delete.setVisibility(View.VISIBLE);
deleteRepoBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
}
private void showRepositoryProperties() {
dialogProp = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
if (dialogProp.getWindow() != null) {
dialogProp.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
propBinding = CustomRepositoryEditPropertiesDialogBinding.inflate(LayoutInflater.from(ctx));
View view = propBinding.getRoot();
dialogProp.setContentView(view);
propBinding.cancel.setOnClickListener(editProperties -> {
dialogProp.dismiss();
});
Call<UserRepositories> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getUserRepository(instanceToken, repositoryOwner, repositoryName);
call.enqueue(new Callback<UserRepositories>() {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
UserRepositories repoInfo = response.body();
propBinding.progressBar.setVisibility(View.GONE);
propBinding.mainView.setVisibility(View.VISIBLE);
if (response.code() == 200) {
assert repoInfo != null;
propBinding.repoName.setText(repoInfo.getName());
propBinding.repoWebsite.setText(repoInfo.getWebsite());
propBinding.repoDescription.setText(repoInfo.getDescription());
propBinding.repoPrivate.setChecked(repoInfo.getPrivateFlag());
propBinding.repoAsTemplate.setChecked(repoInfo.isTemplate());
propBinding.repoEnableIssues.setChecked(repoInfo.getHas_issues());
propBinding.repoEnableIssues.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (isChecked) {
propBinding.repoEnableTimer.setVisibility(View.VISIBLE);
}
else {
propBinding.repoEnableTimer.setVisibility(View.GONE);
}
});
if(repoInfo.getInternal_tracker() != null) {
propBinding.repoEnableTimer.setChecked(repoInfo.getInternal_tracker().isEnable_time_tracker());
}
else {
propBinding.repoEnableTimer.setVisibility(View.GONE);
}
propBinding.repoEnableWiki.setChecked(repoInfo.isHas_wiki());
propBinding.repoEnablePr.setChecked(repoInfo.isHas_pull_requests());
propBinding.repoEnableMerge.setChecked(repoInfo.isAllow_merge_commits());
propBinding.repoEnableRebase.setChecked(repoInfo.isAllow_rebase());
propBinding.repoEnableSquash.setChecked(repoInfo.isAllow_squash_merge());
propBinding.repoEnableForceMerge.setChecked(repoInfo.isAllow_rebase_explicit());
}
else {
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
propBinding.save.setOnClickListener(saveProperties -> saveRepositoryProperties(String.valueOf(propBinding.repoName.getText()),
String.valueOf(propBinding.repoWebsite.getText()),
String.valueOf(propBinding.repoDescription.getText()),
propBinding.repoPrivate.isChecked(), propBinding.repoAsTemplate.isChecked(),
propBinding.repoEnableIssues.isChecked(), propBinding.repoEnableWiki.isChecked(),
propBinding.repoEnablePr.isChecked(), propBinding.repoEnableTimer.isChecked(),
propBinding.repoEnableMerge.isChecked(), propBinding.repoEnableRebase.isChecked(),
propBinding.repoEnableSquash.isChecked(), propBinding.repoEnableForceMerge.isChecked()));
dialogProp.show();
}
private void saveRepositoryProperties(String repoName, String repoWebsite, String repoDescription,
boolean repoPrivate, boolean repoAsTemplate, boolean repoEnableIssues, boolean repoEnableWiki,
boolean repoEnablePr, boolean repoEnableTimer, boolean repoEnableMerge, boolean repoEnableRebase,
boolean repoEnableSquash, boolean repoEnableForceMerge) {
UserRepositories.internalTimeTrackerObject repoPropsTimeTracker = new UserRepositories.internalTimeTrackerObject(repoEnableTimer);
UserRepositories repoProps;
if(!repoEnableIssues) {
repoProps = new UserRepositories(repoName, repoWebsite, repoDescription, repoPrivate, repoAsTemplate, repoEnableIssues, repoEnableWiki, repoEnablePr, repoEnableMerge,
repoEnableRebase, repoEnableSquash, repoEnableForceMerge);
}
else {
repoProps = new UserRepositories(repoName, repoWebsite, repoDescription, repoPrivate, repoAsTemplate, repoEnableIssues, repoEnableWiki, repoEnablePr, repoPropsTimeTracker, repoEnableMerge,
repoEnableRebase, repoEnableSquash, repoEnableForceMerge);
}
Call<UserRepositories> propsCall = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.updateRepositoryProperties(instanceToken, repositoryOwner, repositoryName, repoProps);
propsCall.enqueue(new Callback<UserRepositories>() {
@Override
public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
propBinding.save.setVisibility(View.GONE);
propBinding.processingRequest.setVisibility(View.VISIBLE);
if (response.code() == 200) {
tinyDb.putBoolean("hasIssues", repoEnableIssues);
tinyDb.putBoolean("hasPullRequests", repoEnablePr);
dialogProp.dismiss();
Toasty.success(ctx, getString(R.string.repoPropertiesSaveSuccess));
if(!repositoryName.equals(repoName)) {
finish();
RepositoriesApi.updateRepositoryOwnerAndName(repositoryOwner, repoName, (int) tinyDb.getLong("repositoryId", 0));
Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class);
RepositorySettingsActivity.this.startActivity(intent);
}
}
else {
propBinding.save.setVisibility(View.VISIBLE);
propBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericError));
}
}
@Override
public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
propBinding.save.setVisibility(View.VISIBLE);
propBinding.processingRequest.setVisibility(View.GONE);
Toasty.error(ctx, getString(R.string.genericServerResponseError));
}
});
}
private void initCloseListener() {
onClickListener = view -> finish();
}
}

View File

@ -11,7 +11,6 @@ import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version;
/** /**
* Author M M Arif * Author M M Arif
@ -29,13 +28,12 @@ public class SettingsAppearanceActivity extends BaseActivity {
private static int codeBlockSelectedChoice = 0; private static int codeBlockSelectedChoice = 0;
private static String[] homeScreenList = {"My Repositories", "Starred Repositories", "Organizations", "Repositories", "Profile", "Explore", "Drafts"}; private static String[] homeScreenList = {"My Repositories", "Starred Repositories", "Organizations", "Repositories", "Profile", "Explore", "Drafts"};
private static String[] homeScreenListNew = {"My Repositories", "Starred Repositories", "Organizations", "Repositories", "Profile", "Explore", "Drafts", "Notifications"};
private static int homeScreenSelectedChoice = 0; private static int homeScreenSelectedChoice = 0;
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 (Light / Dark)", "Retro", "Auto (Retro / Dark)"}; private static String[] themeList = {"Dark", "Light", "Auto (Day/Night)"};
private static int themeSelectedChoice = 0; private static int themeSelectedChoice = 0;
@Override @Override
@ -71,11 +69,6 @@ public class SettingsAppearanceActivity extends BaseActivity {
initCloseListener(); initCloseListener();
closeActivity.setOnClickListener(onClickListener); closeActivity.setOnClickListener(onClickListener);
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.3")) {
homeScreenList = homeScreenListNew;
}
if(!tinyDb.getString("timeStr").isEmpty()) { if(!tinyDb.getString("timeStr").isEmpty()) {
tvDateTimeSelected.setText(tinyDb.getString("timeStr")); tvDateTimeSelected.setText(tinyDb.getString("timeStr"));
} }
@ -128,11 +121,11 @@ public class SettingsAppearanceActivity extends BaseActivity {
if (isChecked) { if (isChecked) {
tinyDb.putBoolean("enableCounterBadges", true); tinyDb.putBoolean("enableCounterBadges", true);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
} }
else { else {
tinyDb.putBoolean("enableCounterBadges", false); tinyDb.putBoolean("enableCounterBadges", false);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
} }
}); });
@ -161,7 +154,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterfaceTheme.dismiss(); dialogInterfaceTheme.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
@ -194,7 +187,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterfaceCustomFont.dismiss(); dialogInterfaceCustomFont.dismiss();
Toasty.success(appCtx, appCtx.getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, appCtx.getResources().getString(R.string.settingsSave));
}); });
@ -224,7 +217,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
tinyDb.putInt("homeScreenId", i); tinyDb.putInt("homeScreenId", i);
dialogInterfaceHomeScreen.dismiss(); dialogInterfaceHomeScreen.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
@ -255,7 +248,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
switch(codeBlockList[i]) { switch(codeBlockList[i]) {
case "White - Black": case "White - Black":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorWhite)); tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break; break;
case "Grey - Black": case "Grey - Black":
@ -263,12 +256,12 @@ public class SettingsAppearanceActivity extends BaseActivity {
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
break; break;
case "White - Grey": case "White - Grey":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorWhite)); tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorAccent)); tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorAccent));
break; break;
case "Dark - White": case "Dark - White":
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorPrimary)); tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorPrimary));
tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorWhite)); tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.white));
break; break;
default: default:
tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen)); tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen));
@ -277,7 +270,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
} }
dialogInterfaceCodeBlock.dismiss(); dialogInterfaceCodeBlock.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
@ -314,7 +307,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
} }
dialogInterfaceTime.dismiss(); dialogInterfaceTime.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
@ -327,7 +320,9 @@ public class SettingsAppearanceActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> finish(); onClickListener = view -> {
finish();
};
} }
} }

View File

@ -51,11 +51,11 @@ public class SettingsDraftsActivity extends BaseActivity {
if(isChecked) { if(isChecked) {
tinyDb.putBoolean("draftsCommentsDeletionEnabled", true); tinyDb.putBoolean("draftsCommentsDeletionEnabled", true);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
} }
else { else {
tinyDb.putBoolean("draftsCommentsDeletionEnabled", false); tinyDb.putBoolean("draftsCommentsDeletionEnabled", false);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
} }
}); });

View File

@ -85,7 +85,7 @@ public class SettingsFileViewerActivity extends BaseActivity {
tinyDb.putInt("fileviewerSourceCodeThemeId", i); tinyDb.putInt("fileviewerSourceCodeThemeId", i);
dialogInterfaceTheme.dismiss(); dialogInterfaceTheme.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
@ -100,12 +100,12 @@ public class SettingsFileViewerActivity extends BaseActivity {
if(isChecked) { if(isChecked) {
tinyDb.putBoolean("enablePdfMode", true); tinyDb.putBoolean("enablePdfMode", true);
tinyDb.putString("enablePdfModeInit", "yes"); tinyDb.putString("enablePdfModeInit", "yes");
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
} }
else { else {
tinyDb.putBoolean("enablePdfMode", false); tinyDb.putBoolean("enablePdfMode", false);
tinyDb.putString("enablePdfModeInit", "yes"); tinyDb.putString("enablePdfModeInit", "yes");
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
} }
}); });

View File

@ -1,94 +0,0 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AlertDialog;
import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsGeneralBinding;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Author M M Arif
*/
public class SettingsGeneralActivity extends BaseActivity {
private ActivitySettingsGeneralBinding viewBinding;
private Context appCtx;
private View.OnClickListener onClickListener;
private List<String> defaultScreen;
private static int defaultScreenSelectedChoice = 0;
@Override
protected int getLayoutResourceId() {
return R.layout.activity_settings_general;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCtx = getApplicationContext();
viewBinding = ActivitySettingsGeneralBinding.inflate(getLayoutInflater());
View view = viewBinding.getRoot();
setContentView(view);
TinyDB tinyDb = new TinyDB(appCtx);
initCloseListener();
viewBinding.close.setOnClickListener(onClickListener);
String[] defaultScreen_ = {getResources().getString(R.string.generalDeepLinkSelectedText), getResources().getString(R.string.navRepos), getResources().getString(R.string.navOrgs), getResources().getString(R.string.pageTitleNotifications), getResources().getString(R.string.navExplore)};
defaultScreen = new ArrayList<>(Arrays.asList(defaultScreen_));
String[] linksArray = new String[defaultScreen.size()];
defaultScreen.toArray(linksArray);
if(!tinyDb.getString("defaultScreenStr").isEmpty()) {
viewBinding.generalDeepLinkSelected.setText(tinyDb.getString("defaultScreenStr"));
}
if(defaultScreenSelectedChoice == 0) {
defaultScreenSelectedChoice = tinyDb.getInt("defaultScreenId");
}
viewBinding.setDefaultLinkHandler.setOnClickListener(setDefaultLinkHandler -> {
AlertDialog.Builder dlBuilder = new AlertDialog.Builder(SettingsGeneralActivity.this);
dlBuilder.setTitle(R.string.linkSelectorDialogTitle);
if(defaultScreenSelectedChoice != -1) {
dlBuilder.setCancelable(true);
}
else {
dlBuilder.setCancelable(false);
}
dlBuilder.setSingleChoiceItems(linksArray, defaultScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> {
defaultScreenSelectedChoice = i;
viewBinding.generalDeepLinkSelected.setText(linksArray[i]);
tinyDb.putString("defaultScreenStr", linksArray[i]);
tinyDb.putInt("defaultScreenId", i);
dialogInterfaceHomeScreen.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
});
AlertDialog dlDialog = dlBuilder.create();
dlDialog.show();
});
}
private void initCloseListener() { onClickListener = view -> finish(); }
}

View File

@ -51,11 +51,11 @@ public class SettingsReportsActivity extends BaseActivity {
if(isChecked) { if(isChecked) {
tinyDb.putBoolean("crashReportingEnabled", true); tinyDb.putBoolean("crashReportingEnabled", true);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
} }
else { else {
tinyDb.putBoolean("crashReportingEnabled", false); tinyDb.putBoolean("crashReportingEnabled", false);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
} }
}); });
@ -63,7 +63,9 @@ public class SettingsReportsActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> finish(); onClickListener = view -> {
finish();
};
} }
} }

View File

@ -12,6 +12,8 @@ import android.widget.TextView;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FilesData;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
@ -19,6 +21,7 @@ import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
import org.mian.gitnex.notifications.NotificationsMaster; import org.mian.gitnex.notifications.NotificationsMaster;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
/** /**
* Author M M Arif * Author M M Arif
@ -96,7 +99,10 @@ public class SettingsSecurityActivity extends BaseActivity {
// clear cache setter // clear cache setter
File cacheDir = appCtx.getCacheDir(); File cacheDir = appCtx.getCacheDir();
clearCacheSelected.setText(FileUtils.byteCountToDisplaySize((int) FileUtils.sizeOfDirectory(cacheDir))); long size__ = FilesData.getFileSizeRecursively(new HashSet<>(), cacheDir);
if(size__ > 0) {
clearCacheSelected.setText(String.valueOf(AppUtil.formatFileSizeInDetail(size__)));
}
// clear cache // clear cache
clearCacheFrame.setOnClickListener(v1 -> { clearCacheFrame.setOnClickListener(v1 -> {
@ -149,7 +155,7 @@ public class SettingsSecurityActivity extends BaseActivity {
tinyDb.putInt("cacheSizeImagesId", i); tinyDb.putInt("cacheSizeImagesId", i);
dialogInterfaceTheme.dismiss(); dialogInterfaceTheme.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
@ -179,7 +185,7 @@ public class SettingsSecurityActivity extends BaseActivity {
tinyDb.putInt("cacheSizeId", i); tinyDb.putInt("cacheSizeId", i);
dialogInterfaceTheme.dismiss(); dialogInterfaceTheme.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
@ -236,11 +242,11 @@ public class SettingsSecurityActivity extends BaseActivity {
NotificationsMaster.hireWorker(ctx); NotificationsMaster.hireWorker(ctx);
pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue())); pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue()));
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
builder.setNeutralButton(R.string.cancelButton, null); builder.setNegativeButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
builder.setView(numberPicker); builder.setView(numberPicker);
builder.create().show(); builder.create().show();

View File

@ -22,8 +22,8 @@ public class SettingsTranslationActivity extends BaseActivity {
private Context appCtx; private Context appCtx;
private View.OnClickListener onClickListener; private View.OnClickListener onClickListener;
private static String[] langList = {"English", "Arabic", "Chinese", "Czech", "Finnish", "French", "German", "Italian", "Latvian", "Persian", private static String[] langList = {"English", "Arabic", "Chinese", "Finnish", "French", "German", "Italian", "Latvian", "Persian", "Polish", "Portuguese/Brazilian", "Russian", "Serbian", "Spanish", "Turkish",
"Polish", "Portuguese/Brazilian", "Russian", "Serbian", "Spanish", "Turkish", "Ukrainian"}; "Ukrainian"};
private static int langSelectedChoice = 0; private static int langSelectedChoice = 0;
@Override @Override
@ -95,9 +95,6 @@ public class SettingsTranslationActivity extends BaseActivity {
case "Chinese": case "Chinese":
tinyDb.putString("locale", "zh"); tinyDb.putString("locale", "zh");
break; break;
case "Czech":
tinyDb.putString("locale", "cs");
break;
case "Finnish": case "Finnish":
tinyDb.putString("locale", "fi"); tinyDb.putString("locale", "fi");
break; break;
@ -146,11 +143,11 @@ public class SettingsTranslationActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterface.dismiss(); dialogInterface.dismiss();
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
}); });
lBuilder.setNeutralButton(getString(R.string.cancelButton), null); lBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> dialog.dismiss());
AlertDialog lDialog = lBuilder.create(); AlertDialog lDialog = lBuilder.create();
lDialog.show(); lDialog.show();
@ -160,8 +157,9 @@ public class SettingsTranslationActivity extends BaseActivity {
} }
private void initCloseListener() { private void initCloseListener() {
onClickListener = view -> {
onClickListener = view -> finish(); finish();
};
} }
} }

View File

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

View File

@ -86,7 +86,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdap
holder.userRole.setVisibility(View.VISIBLE); holder.userRole.setVisibility(View.VISIBLE);
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
.textColor(mCtx.getResources().getColor(R.color.colorWhite)) .textColor(mCtx.getResources().getColor(R.color.white))
.fontSize(44) .fontSize(44)
.width(180) .width(180)
.height(60) .height(60)

View File

@ -1,130 +0,0 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.models.Collaborators;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
/**
* Author M M Arif
*/
public class AssigneesListAdapter extends RecyclerView.Adapter<AssigneesListAdapter.AssigneesViewHolder> {
private Context mCtx;
private List<Collaborators> assigneesList;
private List<String> assigneesStrings = new ArrayList<>();
private List<String> currentAssignees;
private AssigneesListAdapterListener assigneesListener;
public interface AssigneesListAdapterListener {
void assigneesInterface(List<String> data);
}
public AssigneesListAdapter(Context mCtx, List<Collaborators> dataMain, AssigneesListAdapterListener assigneesListener, List<String> currentAssignees) {
this.mCtx = mCtx;
this.assigneesList = dataMain;
this.assigneesListener = assigneesListener;
this.currentAssignees = currentAssignees;
}
static class AssigneesViewHolder extends RecyclerView.ViewHolder {
private CheckBox assigneesSelection;
private TextView assigneesName;
private ImageView assigneesAvatar;
private AssigneesViewHolder(View itemView) {
super(itemView);
assigneesSelection = itemView.findViewById(R.id.assigneesSelection);
assigneesName = itemView.findViewById(R.id.assigneesName);
assigneesAvatar = itemView.findViewById(R.id.assigneesAvatar);
}
}
@NonNull
@Override
public AssigneesListAdapter.AssigneesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_assignees_list, parent, false);
return new AssigneesListAdapter.AssigneesViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull AssigneesListAdapter.AssigneesViewHolder holder, int position) {
Collaborators currentItem = assigneesList.get(position);
if(currentItem.getFull_name().equals("")) {
holder.assigneesName.setText(currentItem.getLogin());
}
else {
holder.assigneesName.setText(currentItem.getFull_name());
}
PicassoService
.getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(holder.assigneesAvatar);
for(int i = 0; i < assigneesList.size(); i++) {
if(assigneesStrings.contains(currentItem.getLogin())) {
holder.assigneesSelection.setChecked(true);
}
}
currentAssignees = new ArrayList<>(new LinkedHashSet<>(currentAssignees));
for(int i = 0; i < currentAssignees.size(); i++) {
if(currentAssignees.contains(currentItem.getLogin())) {
holder.assigneesSelection.setChecked(true);
assigneesStrings.add(currentAssignees.get(i));
}
}
assigneesListener.assigneesInterface(assigneesStrings);
holder.assigneesSelection.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked) {
assigneesStrings.add(currentItem.getLogin());
}
else {
assigneesStrings.remove(currentItem.getLogin());
}
assigneesListener.assigneesInterface(assigneesStrings);
});
assigneesStrings = new ArrayList<>(new LinkedHashSet<>(assigneesStrings));
}
@Override
public int getItemCount() {
return assigneesList.size();
}
public void updateList(List<String> list) {
currentAssignees = list;
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,90 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.CommitsActivity;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.Branches;
import java.util.List;
import java.util.Objects;
/**
* Author M M Arif
*/
public class BranchesAdapter extends RecyclerView.Adapter<BranchesAdapter.BranchesViewHolder> {
private List<Branches> branchesList;
private Context mCtx;
static class BranchesViewHolder extends RecyclerView.ViewHolder {
private TextView branchNameTv;
private TextView branchCommitAuthor;
private BranchesViewHolder(View itemView) {
super(itemView);
branchNameTv = itemView.findViewById(R.id.branchName);
branchCommitAuthor = itemView.findViewById(R.id.branchCommitAuthor);
Button branchCommitHash = itemView.findViewById(R.id.branchCommitHash);
branchCommitHash.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), CommitsActivity.class);
intent.putExtra("branchName", String.valueOf(branchNameTv.getText()));
Objects.requireNonNull(v.getContext()).startActivity(intent);
}
});
}
}
public BranchesAdapter(Context mCtx, List<Branches> branchesMain) {
this.mCtx = mCtx;
this.branchesList = branchesMain;
}
@NonNull
@Override
public BranchesAdapter.BranchesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_branches, parent, false);
return new BranchesAdapter.BranchesViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull BranchesAdapter.BranchesViewHolder holder, int position) {
final TinyDB tinyDb = new TinyDB(mCtx);
final String instanceUrl = tinyDb.getString("instanceUrl");
Branches currentItem = branchesList.get(position);
holder.branchNameTv.setText(currentItem.getName());
if(currentItem.getCommit().getAuthor().getName() != null || !currentItem.getCommit().getAuthor().getName().equals("")) {
holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getName()));
}
else {
holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getUsername()));
}
}
@Override
public int getItemCount() {
return branchesList.size();
}
}

View File

@ -2,21 +2,19 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.content.Intent;
import android.text.Html; import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.database.api.DraftsApi; import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.database.models.DraftWithRepository; import org.mian.gitnex.database.models.DraftWithRepository;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import java.util.List; import java.util.List;
@ -28,7 +26,6 @@ import java.util.List;
public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsViewHolder> { public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsViewHolder> {
private List<DraftWithRepository> draftsList; private List<DraftWithRepository> draftsList;
private FragmentManager fragmentManager;
private Context mCtx; private Context mCtx;
class DraftsViewHolder extends RecyclerView.ViewHolder { class DraftsViewHolder extends RecyclerView.ViewHolder {
@ -41,8 +38,6 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
private TextView issueType; private TextView issueType;
private TextView repoOwner; private TextView repoOwner;
private TextView repoName; private TextView repoName;
private TextView commentId;
private ImageView editCommentStatus;
private DraftsViewHolder(View itemView) { private DraftsViewHolder(View itemView) {
@ -56,9 +51,7 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
issueType = itemView.findViewById(R.id.issueType); issueType = itemView.findViewById(R.id.issueType);
repoOwner = itemView.findViewById(R.id.repoOwner); repoOwner = itemView.findViewById(R.id.repoOwner);
repoName = itemView.findViewById(R.id.repoName); repoName = itemView.findViewById(R.id.repoName);
commentId = itemView.findViewById(R.id.commentId);
ImageView deleteDraft = itemView.findViewById(R.id.deleteDraft); ImageView deleteDraft = itemView.findViewById(R.id.deleteDraft);
editCommentStatus = itemView.findViewById(R.id.editCommentStatus);
deleteDraft.setOnClickListener(itemDelete -> { deleteDraft.setOnClickListener(itemDelete -> {
@ -71,25 +64,18 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
itemView.setOnClickListener(itemEdit -> { itemView.setOnClickListener(itemEdit -> {
Bundle bundle = new Bundle(); Intent intent = new Intent(mCtx, ReplyToIssueActivity.class);
intent.putExtra("commentBody", draftText.getText().toString());
bundle.putString("commentBody", draftText.getText().toString()); intent.putExtra("issueNumber", issueNumber.getText().toString());
bundle.putString("issueNumber", issueNumber.getText().toString()); intent.putExtra("repositoryId", repoId.getText().toString());
bundle.putString("repositoryId", repoId.getText().toString()); intent.putExtra("draftTitle", repoInfo.getText().toString());
bundle.putString("draftTitle", repoInfo.getText().toString());
bundle.putString("commentId", commentId.getText().toString());
bundle.putString("draftId", draftId.getText().toString());
if(!commentId.getText().toString().isEmpty()) {
bundle.putString("commentAction", "edit");
}
TinyDB tinyDb = new TinyDB(mCtx); TinyDB tinyDb = new TinyDB(mCtx);
tinyDb.putString("issueNumber", issueNumber.getText().toString()); tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putLong("repositoryId", Long.parseLong(repoId.getText().toString())); tinyDb.putLong("repositoryId", Long.parseLong(repoId.getText().toString()));
//tinyDb.putString("issueType", issueType.getText().toString()); //tinyDb.putString("issueType", issueType.getText().toString());
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet"); mCtx.startActivity(intent);
}); });
@ -97,9 +83,8 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
} }
public DraftsAdapter(Context mCtx, FragmentManager fragmentManager, List<DraftWithRepository> draftsListMain) { public DraftsAdapter(Context mCtx, List<DraftWithRepository> draftsListMain) {
this.mCtx = mCtx; this.mCtx = mCtx;
this.fragmentManager = fragmentManager;
this.draftsList = draftsListMain; this.draftsList = draftsListMain;
} }
@ -108,7 +93,7 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
draftsList.remove(position); draftsList.remove(position);
notifyItemRemoved(position); notifyItemRemoved(position);
notifyItemRangeChanged(position, draftsList.size()); notifyItemRangeChanged(position, draftsList.size());
Toasty.success(mCtx, mCtx.getResources().getString(R.string.draftsSingleDeleteSuccess)); Toasty.info(mCtx, mCtx.getResources().getString(R.string.draftsSingleDeleteSuccess));
} }
@ -132,18 +117,9 @@ public class DraftsAdapter extends RecyclerView.Adapter<DraftsAdapter.DraftsView
holder.repoOwner.setText(currentItem.getRepositoryOwner()); holder.repoOwner.setText(currentItem.getRepositoryOwner());
holder.repoName.setText(currentItem.getRepositoryName()); holder.repoName.setText(currentItem.getRepositoryName());
holder.draftText.setText(currentItem.getDraftText()); holder.draftText.setText(currentItem.getDraftText());
holder.commentId.setText(currentItem.getCommentId());
String issueNumber = "<font color='" + mCtx.getResources().getColor(R.color.lightGray) + "'>" + mCtx.getResources().getString(R.string.hash) + currentItem.getIssueId() + "</font>"; String issueNumber = "<font color='" + mCtx.getResources().getColor(R.color.lightGray) + "'>" + mCtx.getResources().getString(R.string.hash) + currentItem.getIssueId() + "</font>";
Spanned headTitle = Html.fromHtml(issueNumber + " " + currentItem.getRepositoryOwner() + " / " + currentItem.getRepositoryName()); holder.repoInfo.setText(Html.fromHtml(issueNumber + " " + currentItem.getRepositoryOwner() + " / " + currentItem.getRepositoryName()));
holder.repoInfo.setText(headTitle);
if(!currentItem.getCommentId().equalsIgnoreCase("new")) {
holder.editCommentStatus.setVisibility(View.VISIBLE);
}
else {
holder.editCommentStatus.setVisibility(View.GONE);
}
} }

View File

@ -1,8 +1,6 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -21,7 +19,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog;
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.RepoForksActivity;
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.PicassoService;
@ -34,7 +31,6 @@ import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.models.WatchInfo;
import java.util.List; import java.util.List;
import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -44,6 +40,7 @@ import retrofit2.Callback;
public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepositoriesAdapter.ReposSearchViewHolder> { public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepositoriesAdapter.ReposSearchViewHolder> {
private List<UserRepositories> searchedReposList; private List<UserRepositories> searchedReposList;
private Context mCtx; private Context mCtx;
@ -67,7 +64,6 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
private TextView repoType; private TextView repoType;
private LinearLayout archiveRepo; private LinearLayout archiveRepo;
private TextView repoBranch; private TextView repoBranch;
private TextView htmlUrl;
private ReposSearchViewHolder(View itemView) { private ReposSearchViewHolder(View itemView) {
@ -86,7 +82,6 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame); archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch); repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(v -> {
@ -153,7 +148,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
if(response.code() != 404) { if(response.code() != 404) {
Toasty.error(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
@ -165,7 +160,7 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.error(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
}); });
@ -185,8 +180,6 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers); TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers); TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1])); bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
@ -194,17 +187,6 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
dialog.setContentView(view); dialog.setContentView(view);
dialog.show(); dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> { repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
@ -232,15 +214,6 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
}); });
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
}); });
} }
@ -261,7 +234,6 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
UserRepositories currentItem = searchedReposList.get(position); UserRepositories currentItem = searchedReposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch()); holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -286,13 +258,13 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
holder.repoDescription.setVisibility(View.VISIBLE); holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.repoDescription.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullName()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate); holder.repoType.setText(R.string.strPrivate);
} }
else { else {
holder.repoPrivatePublic.setVisibility(View.GONE); holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic); holder.repoType.setText(R.string.strPublic);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
@ -318,9 +290,4 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<ExploreRepo
return searchedReposList.size(); return searchedReposList.size();
} }
public void notifyDataChanged() {
notifyDataSetChanged();
}
} }

View File

@ -10,8 +10,8 @@ import android.widget.ImageView;
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 org.apache.commons.io.FileUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Files; import org.mian.gitnex.models.Files;
import java.util.ArrayList; import java.util.ArrayList;
@ -37,8 +37,6 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
class FilesViewHolder extends RecyclerView.ViewHolder { class FilesViewHolder extends RecyclerView.ViewHolder {
private ImageView fileTypeImage; private ImageView fileTypeImage;
private ImageView dirTypeImage;
private ImageView unknownTypeImage;
private TextView fileName; private TextView fileName;
private TextView fileType; private TextView fileType;
private TextView fileInfo; private TextView fileInfo;
@ -48,8 +46,6 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
super(itemView); super(itemView);
fileName = itemView.findViewById(R.id.fileName); fileName = itemView.findViewById(R.id.fileName);
fileTypeImage = itemView.findViewById(R.id.fileImage); fileTypeImage = itemView.findViewById(R.id.fileImage);
dirTypeImage = itemView.findViewById(R.id.dirImage);
unknownTypeImage = itemView.findViewById(R.id.unknownImage);
fileType = itemView.findViewById(R.id.fileType); fileType = itemView.findViewById(R.id.fileType);
fileInfo = itemView.findViewById(R.id.fileInfo); fileInfo = itemView.findViewById(R.id.fileInfo);
@ -66,7 +62,7 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
filesListener.onClickDir(fileName.getText().toString()); filesListener.onClickDir(fileName.getText().toString());
} }
else { else {
Toasty.warning(context, context.getString(R.string.filesGenericError)); Toasty.info(context, context.getString(R.string.filesGenericError));
} }
}); });
@ -161,22 +157,16 @@ public class FilesAdapter extends RecyclerView.Adapter<FilesAdapter.FilesViewHol
holder.fileName.setText(currentItem.getName()); holder.fileName.setText(currentItem.getName());
if(currentItem.getType().equals("file")) { if(currentItem.getType().equals("file")) {
holder.fileTypeImage.setVisibility(View.VISIBLE); holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_file));
holder.dirTypeImage.setVisibility(View.GONE);
holder.unknownTypeImage.setVisibility(View.GONE);
holder.fileInfo.setVisibility(View.VISIBLE); holder.fileInfo.setVisibility(View.VISIBLE);
holder.fileInfo.setText(FileUtils.byteCountToDisplaySize(currentItem.getSize())); holder.fileInfo.setText(AppUtil.formatFileSizeInDetail(currentItem.getSize()));
} }
else if(currentItem.getType().equals("dir")) { else if(currentItem.getType().equals("dir")) {
holder.dirTypeImage.setVisibility(View.VISIBLE);
holder.unknownTypeImage.setVisibility(View.GONE);
holder.fileTypeImage.setVisibility(View.GONE);
holder.fileInfo.setVisibility(View.GONE); holder.fileInfo.setVisibility(View.GONE);
holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_directory));
} }
else { else {
holder.unknownTypeImage.setVisibility(View.VISIBLE); holder.fileTypeImage.setImageDrawable(mCtx.getResources().getDrawable(R.drawable.ic_question));
holder.dirTypeImage.setVisibility(View.GONE);
holder.fileTypeImage.setVisibility(View.GONE);
} }
} }

View File

@ -2,8 +2,8 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -12,9 +12,8 @@ import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.fragment.app.FragmentManager;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.fragments.BottomSheetReplyFragment; import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.helpers.DiffTextView; import org.mian.gitnex.helpers.DiffTextView;
import org.mian.gitnex.models.FileDiffView; import org.mian.gitnex.models.FileDiffView;
import java.util.List; import java.util.List;
@ -37,13 +36,11 @@ public class FilesDiffAdapter extends BaseAdapter {
private static int COLOR_FONT; private static int COLOR_FONT;
private Context context; private Context context;
private FragmentManager fragmentManager;
private List<FileDiffView> fileDiffViews; private List<FileDiffView> fileDiffViews;
public FilesDiffAdapter(Context context, FragmentManager fragmentManager, List<FileDiffView> fileDiffViews) { public FilesDiffAdapter(Context context, List<FileDiffView> fileDiffViews) {
this.context = context; this.context = context;
this.fragmentManager = fragmentManager;
this.fileDiffViews = fileDiffViews; this.fileDiffViews = fileDiffViews;
selectedViews = new ConcurrentSkipListMap<>(); selectedViews = new ConcurrentSkipListMap<>();
@ -204,11 +201,12 @@ public class FilesDiffAdapter extends BaseAdapter {
selectedViews.clear(); selectedViews.clear();
Bundle bundle = new Bundle(); Intent intent = new Intent(context, ReplyToIssueActivity.class);
bundle.putString("commentBody", stringBuilder.toString()); intent.putExtra("commentBody", stringBuilder.toString());
bundle.putBoolean("cursorToEnd", true); intent.putExtra("cursorToEnd", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet"); context.startActivity(intent);
} }

View File

@ -7,7 +7,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle;
import android.text.Spanned; import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -15,15 +14,14 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
@ -62,13 +60,11 @@ import retrofit2.Callback;
public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> { public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> {
private List<IssueComments> issuesComments; private List<IssueComments> issuesComments;
private FragmentManager fragmentManager;
private Context mCtx; private Context mCtx;
public IssueCommentsAdapter(Context mCtx, FragmentManager fragmentManager, List<IssueComments> issuesCommentsMain) { public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {
this.mCtx = mCtx; this.mCtx = mCtx;
this.fragmentManager = fragmentManager;
this.issuesComments = issuesCommentsMain; this.issuesComments = issuesCommentsMain;
} }
@ -113,7 +109,6 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
TextView commentMenuQuote = view.findViewById(R.id.commentMenuQuote); TextView commentMenuQuote = view.findViewById(R.id.commentMenuQuote);
TextView commentMenuCopy = view.findViewById(R.id.commentMenuCopy); TextView commentMenuCopy = view.findViewById(R.id.commentMenuCopy);
TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete); TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete);
TextView issueCommentCopyUrl = view.findViewById(R.id.issueCommentCopyUrl);
if(!loginUid.contentEquals(commenterUsername.getText())) { if(!loginUid.contentEquals(commenterUsername.getText())) {
commentMenuEdit.setVisibility(View.GONE); commentMenuEdit.setVisibility(View.GONE);
@ -130,12 +125,11 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
commentMenuEdit.setOnClickListener(ediComment -> { commentMenuEdit.setOnClickListener(ediComment -> {
Bundle bundle = new Bundle(); Intent intent = new Intent(ctx, ReplyToIssueActivity.class);
bundle.putString("commentId", commendId.getText().toString()); intent.putExtra("commentId", commendId.getText());
bundle.putString("commentAction", "edit"); intent.putExtra("commentAction", "edit");
bundle.putString("commentBody", commendBodyRaw.getText().toString()); intent.putExtra("commentBody", commendBodyRaw.getText());
ctx.startActivity(intent);
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
dialog.dismiss(); dialog.dismiss();
}); });
@ -157,22 +151,6 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
}); });
issueCommentCopyUrl.setOnClickListener(ediComment -> {
// comment Url
CharSequence commentUrl = htmlUrl.getText();
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
assert clipboard != null;
ClipData clip = ClipData.newPlainText(commentUrl, commentUrl);
clipboard.setPrimaryClip(clip);
dialog.dismiss();
Toasty.success(ctx, ctx.getString(R.string.copyIssueUrlToastMsg));
});
commentMenuQuote.setOnClickListener(v1 -> { commentMenuQuote.setOnClickListener(v1 -> {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
@ -192,12 +170,13 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
stringBuilder.append("\n"); stringBuilder.append("\n");
Bundle bundle = new Bundle(); Intent intent = new Intent(ctx, ReplyToIssueActivity.class);
bundle.putString("commentBody", stringBuilder.toString()); intent.putExtra("commentBody", stringBuilder.toString());
bundle.putBoolean("cursorToEnd", true); intent.putExtra("cursorToEnd", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialog.dismiss(); dialog.dismiss();
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet"); ctx.startActivity(intent);
}); });
@ -210,7 +189,7 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
clipboard.setPrimaryClip(clip); clipboard.setPrimaryClip(clip);
dialog.dismiss(); dialog.dismiss();
Toasty.success(ctx, ctx.getString(R.string.copyIssueCommentToastMsg)); Toasty.info(ctx, ctx.getString(R.string.copyIssueCommentToastMsg));
}); });
@ -263,7 +242,7 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
if(response.code() == 204) { if(response.code() == 204) {
updateAdapter(position); updateAdapter(position);
Toasty.success(ctx, ctx.getResources().getString(R.string.deleteCommentSuccess)); Toasty.info(ctx, ctx.getResources().getString(R.string.deleteCommentSuccess));
} }
else if(response.code() == 401) { else if(response.code() == 401) {
@ -276,17 +255,17 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
} }
else if(response.code() == 403) { else if(response.code() == 403) {
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); Toasty.info(ctx, ctx.getString(R.string.authorizeError));
} }
else if(response.code() == 404) { else if(response.code() == 404) {
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
} }
else { else {
Toasty.error(ctx, ctx.getString(R.string.genericError)); Toasty.info(ctx, ctx.getString(R.string.genericError));
} }

View File

@ -1,128 +0,0 @@
package org.mian.gitnex.adapters;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.models.Labels;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
/**
* Author M M Arif
*/
public class LabelsListAdapter extends RecyclerView.Adapter<LabelsListAdapter.LabelsViewHolder> {
private List<Integer> currentLabelsIds;
private List<Labels> labels;
private List<String> labelsStrings = new ArrayList<>();
private List<Integer> labelsIds = new ArrayList<>();
private LabelsListAdapterListener labelsListener;
public interface LabelsListAdapterListener {
void labelsInterface(List<String> data);
void labelsIdsInterface(List<Integer> data);
}
public LabelsListAdapter(List<Labels> labelsMain, LabelsListAdapterListener labelsListener, List<Integer> currentLabelsIds) {
this.labels = labelsMain;
this.labelsListener = labelsListener;
this.currentLabelsIds = currentLabelsIds;
}
static class LabelsViewHolder extends RecyclerView.ViewHolder {
private CheckBox labelSelection;
private TextView labelText;
private ImageView labelColor;
private LabelsViewHolder(View itemView) {
super(itemView);
labelSelection = itemView.findViewById(R.id.labelSelection);
labelText = itemView.findViewById(R.id.labelText);
labelColor = itemView.findViewById(R.id.labelColor);
}
}
@NonNull
@Override
public LabelsListAdapter.LabelsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_labels_list, parent, false);
return new LabelsListAdapter.LabelsViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull LabelsListAdapter.LabelsViewHolder holder, int position) {
Labels currentItem = labels.get(position);
String labelColor = currentItem.getColor();
int color = Color.parseColor("#" + labelColor);
holder.labelText.setText(currentItem.getName());
holder.labelColor.setBackgroundColor(color);
for(int i = 0; i < labelsIds.size(); i++) {
if(labelsStrings.contains(currentItem.getName())) {
holder.labelSelection.setChecked(true);
}
}
currentLabelsIds = new ArrayList<>(new LinkedHashSet<>(currentLabelsIds));
for(int i = 0; i < currentLabelsIds.size(); i++) {
if(currentLabelsIds.contains(currentItem.getId())) {
holder.labelSelection.setChecked(true);
labelsIds.add(currentLabelsIds.get(i));
}
}
labelsListener.labelsIdsInterface(labelsIds);
holder.labelSelection.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked) {
labelsStrings.add(currentItem.getName());
labelsIds.add(currentItem.getId());
}
else {
labelsStrings.remove(currentItem.getName());
labelsIds.remove(Integer.valueOf(currentItem.getId()));
}
labelsListener.labelsInterface(labelsStrings);
labelsListener.labelsIdsInterface(labelsIds);
});
labelsIds = new ArrayList<>(new LinkedHashSet<>(labelsIds));
}
@Override
public int getItemCount() {
return labels.size();
}
public void updateList(List<Integer> list) {
currentLabelsIds = list;
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,190 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.TextAppearanceSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatCheckBox;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.helpers.MultiSelectDialog;
import org.mian.gitnex.models.MultiSelectModel;
import java.util.List;
/**
* Author com.github.abumoallim, modified by M M Arif
*/
public class MutliSelectAdapter extends RecyclerView.Adapter<MutliSelectAdapter.MultiSelectDialogViewHolder> {
private List<MultiSelectModel> mDataSet;
private String mSearchQuery = "";
private Context mContext;
public MutliSelectAdapter(List<MultiSelectModel> dataSet, Context context) {
this.mDataSet = dataSet;
this.mContext = context;
}
@NonNull
@Override
public MultiSelectDialogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.multi_select_item, parent, false);
return new MultiSelectDialogViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final MultiSelectDialogViewHolder holder, int position) {
if (!mSearchQuery.equals("") && mSearchQuery.length() > 1) {
setHighlightedText(position, holder.dialog_name_item);
} else {
holder.dialog_name_item.setText(mDataSet.get(position).getName());
}
if (mDataSet.get(position).getSelected()) {
if (!MultiSelectDialog.selectedIdsForCallback.contains(mDataSet.get(position).getId())) {
MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(position).getId());
}
}
if (checkForSelection(mDataSet.get(position).getId())) {
holder.dialog_item_checkbox.setChecked(true);
} else {
holder.dialog_item_checkbox.setChecked(false);
}
/*holder.dialog_item_checkbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (holder.dialog_item_checkbox.isChecked()) {
MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(holder.getAdapterPosition()).getId());
holder.dialog_item_checkbox.setChecked(true);
} else {
removeFromSelection(mDataSet.get(holder.getAdapterPosition()).getId());
holder.dialog_item_checkbox.setChecked(false);
}
}
});*/
holder.main_container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!holder.dialog_item_checkbox.isChecked()) {
MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(holder.getAdapterPosition()).getId());
holder.dialog_item_checkbox.setChecked(true);
mDataSet.get(holder.getAdapterPosition()).setSelected(true);
notifyItemChanged(holder.getAdapterPosition());
} else {
removeFromSelection(mDataSet.get(holder.getAdapterPosition()).getId());
holder.dialog_item_checkbox.setChecked(false);
mDataSet.get(holder.getAdapterPosition()).setSelected(false);
notifyItemChanged(holder.getAdapterPosition());
}
}
});
}
private void setHighlightedText(int position, TextView textview) {
String name = mDataSet.get(position).getName();
SpannableString str = new SpannableString(name);
int endLength = name.toLowerCase().indexOf(mSearchQuery) + mSearchQuery.length();
ColorStateList highlightedColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{ContextCompat.getColor(mContext, R.color.colorAccent)});
TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(null, Typeface.NORMAL, -1, highlightedColor, null);
str.setSpan(textAppearanceSpan, name.toLowerCase().indexOf(mSearchQuery), endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textview.setText(str);
}
private void removeFromSelection(Integer id) {
for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) {
if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) {
MultiSelectDialog.selectedIdsForCallback.remove(i);
}
}
}
private boolean checkForSelection(Integer id) {
for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) {
if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) {
return true;
}
}
return false;
}
/*//get selected name string separated by coma
public String getDataString() {
String data = "";
for (int i = 0; i < mDataSet.size(); i++) {
if (checkForSelection(mDataSet.get(i).getId())) {
data = data + ", " + mDataSet.get(i).getName();
}
}
if (data.length() > 0) {
return data.substring(1);
} else {
return "";
}
}
//get selected name ararylist
public ArrayList<String> getSelectedNameList() {
ArrayList<String> names = new ArrayList<>();
for (int i = 0; i < mDataSet.size(); i++) {
if (checkForSelection(mDataSet.get(i).getId())) {
names.add(mDataSet.get(i).getName());
}
}
// return names.toArray(new String[names.size()]);
return names;
}*/
@Override
public int getItemCount() {
return mDataSet.size();
}
public void setData(List<MultiSelectModel> data, String query, MutliSelectAdapter mutliSelectAdapter) {
this.mDataSet = data;
this.mSearchQuery = query;
mutliSelectAdapter.notifyDataSetChanged();
}
class MultiSelectDialogViewHolder extends RecyclerView.ViewHolder {
private TextView dialog_name_item;
private AppCompatCheckBox dialog_item_checkbox;
private LinearLayout main_container;
MultiSelectDialogViewHolder(View view) {
super(view);
dialog_name_item = view.findViewById(R.id.dialog_item_name);
dialog_item_checkbox = view.findViewById(R.id.dialog_item_checkbox);
main_container = view.findViewById(R.id.main_container);
}
}
}

View File

@ -1,8 +1,6 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -23,7 +21,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog;
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.RepoForksActivity;
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.PicassoService;
@ -37,7 +34,6 @@ import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.models.WatchInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -65,7 +61,6 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
private CheckBox isRepoAdmin; private CheckBox isRepoAdmin;
private LinearLayout archiveRepo; private LinearLayout archiveRepo;
private TextView repoBranch; private TextView repoBranch;
private TextView htmlUrl;
private MyReposViewHolder(View itemView) { private MyReposViewHolder(View itemView) {
@ -83,7 +78,6 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin); isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame); archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch); repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(v -> {
@ -151,7 +145,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
if(response.code() != 404) { if(response.code() != 404) {
Toasty.error(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
@ -163,7 +157,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.error(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
}); });
@ -183,8 +177,6 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers); TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers); TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", repoFullName.getText().toString().split("/")[0], repoFullName.getText().toString().split("/")[1])); bottomSheetHeader.setText(String.format("%s / %s", repoFullName.getText().toString().split("/")[0], repoFullName.getText().toString().split("/")[1]));
@ -192,17 +184,6 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
dialog.setContentView(view); dialog.setContentView(view);
dialog.show(); dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> { repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
@ -230,15 +211,6 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
}); });
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", repoFullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
}); });
} }
@ -266,7 +238,6 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch()); holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -291,13 +262,13 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
holder.repoDescription.setVisibility(View.VISIBLE); holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.repoDescription.setText(currentItem.getDescription());
} }
holder.repoFullName.setText(currentItem.getFullName()); holder.repoFullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate); holder.repoType.setText(R.string.strPrivate);
} }
else { else {
holder.repoPrivatePublic.setVisibility(View.GONE); holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic); holder.repoType.setText(R.string.strPublic);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
@ -344,7 +315,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.
String filterPattern = constraint.toString().toLowerCase().trim(); String filterPattern = constraint.toString().toLowerCase().trim();
for(UserRepositories item : reposListFull) { for(UserRepositories item : reposListFull) {
if(item.getFullName().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) { if(item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item); filteredList.add(item);
} }
} }

View File

@ -44,9 +44,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
private LinearLayout frame; private LinearLayout frame;
private TextView subject; private TextView subject;
private TextView repository; private TextView repository;
private ImageView typePr; private ImageView type;
private ImageView typeIssue;
private ImageView typeUnknown;
private ImageView pinned; private ImageView pinned;
private ImageView more; private ImageView more;
@ -57,9 +55,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
frame = itemView.findViewById(R.id.frame); frame = itemView.findViewById(R.id.frame);
subject = itemView.findViewById(R.id.subject); subject = itemView.findViewById(R.id.subject);
repository = itemView.findViewById(R.id.repository); repository = itemView.findViewById(R.id.repository);
typePr = itemView.findViewById(R.id.typePr); type = itemView.findViewById(R.id.type);
typeIssue = itemView.findViewById(R.id.typeIssue);
typeUnknown = itemView.findViewById(R.id.typeUnknown);
pinned = itemView.findViewById(R.id.pinned); pinned = itemView.findViewById(R.id.pinned);
more = itemView.findViewById(R.id.more); more = itemView.findViewById(R.id.more);
@ -85,7 +81,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
.getString(R.string.hash) + url.substring(url.lastIndexOf("/") + 1) + "</font>"; .getString(R.string.hash) + url.substring(url.lastIndexOf("/") + 1) + "</font>";
holder.subject.setText(Html.fromHtml(subjectId + " " + notificationThread.getSubject().getTitle())); holder.subject.setText(Html.fromHtml(subjectId + " " + notificationThread.getSubject().getTitle()));
holder.repository.setText(notificationThread.getRepository().getFullName()); holder.repository.setText(notificationThread.getRepository().getFullname());
if(notificationThread.isPinned()) { if(notificationThread.isPinned()) {
holder.pinned.setVisibility(View.VISIBLE); holder.pinned.setVisibility(View.VISIBLE);
@ -97,21 +93,15 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
switch(notificationThread.getSubject().getType()) { switch(notificationThread.getSubject().getType()) {
case "Pull": case "Pull":
holder.typePr.setVisibility(View.VISIBLE); holder.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_pull_request, null));
holder.typeIssue.setVisibility(View.GONE);
holder.typeUnknown.setVisibility(View.GONE);
break; break;
case "Issue": case "Issue":
holder.typePr.setVisibility(View.GONE); holder.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_issue, null));
holder.typeIssue.setVisibility(View.VISIBLE);
holder.typeUnknown.setVisibility(View.GONE);
break; break;
default: default:
holder.typePr.setVisibility(View.GONE); holder.type.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_question, null));
holder.typeIssue.setVisibility(View.GONE);
holder.typeUnknown.setVisibility(View.VISIBLE);
break; break;
} }
@ -120,7 +110,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
onNotificationClickedListener.onNotificationClicked(notificationThread); onNotificationClickedListener.onNotificationClicked(notificationThread);
String[] parts = notificationThread.getRepository().getFullName().split("/"); String[] parts = notificationThread.getRepository().getFullname().split("/");
final String repoOwner = parts[0]; final String repoOwner = parts[0];
final String repoName = parts[1]; final String repoName = parts[1];

View File

@ -58,7 +58,7 @@ public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdap
if(currentItem.getPrimary()) { if(currentItem.getPrimary()) {
TextDrawable drawable = TextDrawable.builder() TextDrawable drawable = TextDrawable.builder()
.beginConfig() .beginConfig()
.textColor(mCtx.getResources().getColor(R.color.colorWhite)) .textColor(mCtx.getResources().getColor(R.color.white))
.fontSize(36) .fontSize(36)
.width(220) .width(220)
.height(60) .height(60)

View File

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

View File

@ -1,8 +1,6 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -25,7 +23,6 @@ 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.activities.RepoForksActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi; import org.mian.gitnex.database.api.RepositoriesApi;
@ -37,7 +34,6 @@ import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.models.WatchInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -65,7 +61,6 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
private TextView repoType; private TextView repoType;
private LinearLayout archiveRepo; private LinearLayout archiveRepo;
private TextView repoBranch; private TextView repoBranch;
private TextView htmlUrl;
private ReposViewHolder(View itemView) { private ReposViewHolder(View itemView) {
@ -83,7 +78,6 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame); archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch); repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(v -> {
@ -152,7 +146,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
if(response.code() != 404) { if(response.code() != 404) {
Toasty.error(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
@ -164,7 +158,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.error(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
}); });
@ -184,8 +178,6 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers); TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers); TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1])); bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
@ -193,17 +185,6 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
dialog.setContentView(view); dialog.setContentView(view);
dialog.show(); dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> { repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
@ -231,15 +212,6 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
}); });
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
}); });
} }
@ -267,7 +239,6 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch()); holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -292,13 +263,13 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
holder.repoDescription.setVisibility(View.VISIBLE); holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.repoDescription.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullName()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate); holder.repoType.setText(R.string.strPrivate);
} }
else { else {
holder.repoPrivatePublic.setVisibility(View.GONE); holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic); holder.repoType.setText(R.string.strPublic);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
@ -344,7 +315,7 @@ public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.Repo
String filterPattern = constraint.toString().toLowerCase().trim(); String filterPattern = constraint.toString().toLowerCase().trim();
for(UserRepositories item : reposListFull) { for(UserRepositories item : reposListFull) {
if(item.getFullName().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) { if(item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item); filteredList.add(item);
} }
} }

View File

@ -1,8 +1,6 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -25,7 +23,6 @@ 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.activities.RepoForksActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi; import org.mian.gitnex.database.api.RepositoriesApi;
@ -37,7 +34,6 @@ import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.models.WatchInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -65,7 +61,6 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
private TextView repoType; private TextView repoType;
private LinearLayout archiveRepo; private LinearLayout archiveRepo;
private TextView repoBranch; private TextView repoBranch;
private TextView htmlUrl;
private OrgReposViewHolder(View itemView) { private OrgReposViewHolder(View itemView) {
super(itemView); super(itemView);
@ -82,7 +77,6 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame); archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch); repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(v -> {
@ -147,7 +141,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
if(response.code() != 404) { if(response.code() != 404) {
Toasty.error(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
@ -159,7 +153,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
tinyDb.putBoolean("repoWatch", false); tinyDb.putBoolean("repoWatch", false);
Toasty.error(context, context.getString(R.string.genericApiStatusError)); Toasty.info(context, context.getString(R.string.genericApiStatusError));
} }
}); });
@ -179,8 +173,6 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers); TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers); TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1])); bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
@ -188,17 +180,6 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
dialog.setContentView(view); dialog.setContentView(view);
dialog.show(); dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> { repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
@ -208,7 +189,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
}); });
repoStargazers.setOnClickListener(stargazers -> { repoStargazers.setOnClickListener(openInBrowser -> {
Intent intent = new Intent(context, RepoStargazersActivity.class); Intent intent = new Intent(context, RepoStargazersActivity.class);
intent.putExtra("repoFullNameForStars", fullName.getText()); intent.putExtra("repoFullNameForStars", fullName.getText());
@ -217,7 +198,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
}); });
repoWatchers.setOnClickListener(watchers -> { 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());
@ -226,15 +207,6 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
}); });
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
}); });
} }
@ -260,7 +232,6 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch()); holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -292,13 +263,13 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
holder.repoDescription.setVisibility(View.VISIBLE); holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.repoDescription.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullName()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate); holder.repoType.setText(R.string.strPrivate);
} }
else { else {
holder.repoPrivatePublic.setVisibility(View.GONE); holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic); holder.repoType.setText(R.string.strPublic);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
@ -340,7 +311,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesB
String filterPattern = constraint.toString().toLowerCase().trim(); String filterPattern = constraint.toString().toLowerCase().trim();
for (UserRepositories item : reposListFull) { for (UserRepositories item : reposListFull) {
if (item.getFullName().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) { if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item); filteredList.add(item);
} }
} }

View File

@ -1,172 +0,0 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.api.RepositoriesApi;
import org.mian.gitnex.database.models.Repository;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.Issues;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
/**
* Author M M Arif
*/
public class SearchIssuesAdapter extends RecyclerView.Adapter<SearchIssuesAdapter.SearchViewHolder> {
private List<Issues> searchedList;
private Context mCtx;
private TinyDB tinyDb;
public SearchIssuesAdapter(List<Issues> dataList, Context mCtx) {
this.mCtx = mCtx;
this.searchedList = dataList;
this.tinyDb = new TinyDB(mCtx);
}
class SearchViewHolder extends RecyclerView.ViewHolder {
private TextView issueNumber;
private ImageView issueAssigneeAvatar;
private TextView issueTitle;
private TextView issueCreatedTime;
private TextView issueCommentsCount;
private TextView repoFullName;
private SearchViewHolder(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);
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
repoFullName = itemView.findViewById(R.id.repoFullName);
issueTitle.setOnClickListener(v -> {
Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issueNumber.getText());
tinyDb.putString("issueNumber", issueNumber.getText().toString());
tinyDb.putString("issueType", "Issue");
tinyDb.putString("repoFullName", repoFullName.getText().toString());
String[] parts = repoFullName.getText().toString().split("/");
final String repoOwner = parts[0];
final String repoName = parts[1];
int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId");
RepositoriesApi repositoryData = new RepositoriesApi(context);
Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName);
if(count == 0) {
long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", id);
}
else {
Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName);
tinyDb.putLong("repositoryId", data.getRepositoryId());
}
context.startActivity(intent);
});
}
}
@NonNull
@Override
public SearchIssuesAdapter.SearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_issues, parent, false);
return new SearchIssuesAdapter.SearchViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull final SearchIssuesAdapter.SearchViewHolder holder, int position) {
Issues currentItem = searchedList.get(position);
String locale = tinyDb.getString("locale");
String timeFormat = tinyDb.getString("dateFormat");
if(!currentItem.getUser().getFull_name().equals("")) {
holder.issueAssigneeAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCreator) + currentItem.getUser().getFull_name(), mCtx));
}
else {
holder.issueAssigneeAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCreator) + 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.issueAssigneeAvatar);
String issueNumber_ = "<font color='" + mCtx.getResources().getColor(R.color.lightGray) + "'>" + currentItem.getRepository().getFull_name() + mCtx.getResources().getString(R.string.hash) + currentItem.getNumber() + "</font>";
holder.issueTitle.setText(Html.fromHtml(issueNumber_ + " " + currentItem.getTitle()));
holder.issueNumber.setText(String.valueOf(currentItem.getNumber()));
holder.issueCommentsCount.setText(String.valueOf(currentItem.getComments()));
holder.repoFullName.setText(currentItem.getRepository().getFull_name());
switch(timeFormat) {
case "pretty": {
PrettyTime prettyTime = new PrettyTime(new Locale(locale));
String createdTime = prettyTime.format(currentItem.getCreated_at());
holder.issueCreatedTime.setText(createdTime);
holder.issueCreatedTime.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.issueCreatedTime.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.issueCreatedTime.setText(createdTime);
break;
}
}
}
@Override
public int getItemCount() {
return searchedList.size();
}
public void notifyDataChanged() {
notifyDataSetChanged();
}
}

View File

@ -1,8 +1,6 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -25,7 +23,6 @@ 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.activities.RepoForksActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.RepositoriesApi; import org.mian.gitnex.database.api.RepositoriesApi;
@ -37,7 +34,6 @@ import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.models.WatchInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -65,7 +61,6 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
private TextView repoType; private TextView repoType;
private LinearLayout archiveRepo; private LinearLayout archiveRepo;
private TextView repoBranch; private TextView repoBranch;
private TextView htmlUrl;
private StarredReposViewHolder(View itemView) { private StarredReposViewHolder(View itemView) {
super(itemView); super(itemView);
@ -82,7 +77,6 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
repoType = itemView.findViewById(R.id.repoType); repoType = itemView.findViewById(R.id.repoType);
archiveRepo = itemView.findViewById(R.id.archiveRepoFrame); archiveRepo = itemView.findViewById(R.id.archiveRepoFrame);
repoBranch = itemView.findViewById(R.id.repoBranch); repoBranch = itemView.findViewById(R.id.repoBranch);
htmlUrl = itemView.findViewById(R.id.htmlUrl);
itemView.setOnClickListener(v -> { itemView.setOnClickListener(v -> {
@ -182,8 +176,6 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser); TextView repoOpenInBrowser = view.findViewById(R.id.repoOpenInBrowser);
TextView repoStargazers = view.findViewById(R.id.repoStargazers); TextView repoStargazers = view.findViewById(R.id.repoStargazers);
TextView repoWatchers = view.findViewById(R.id.repoWatchers); TextView repoWatchers = view.findViewById(R.id.repoWatchers);
TextView repoForksList = view.findViewById(R.id.repoForksList);
TextView repoCopyUrl = view.findViewById(R.id.repoCopyUrl);
TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader); TextView bottomSheetHeader = view.findViewById(R.id.bottomSheetHeader);
bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1])); bottomSheetHeader.setText(String.format("%s / %s", fullName.getText().toString().split("/")[0], fullName.getText().toString().split("/")[1]));
@ -191,17 +183,6 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
dialog.setContentView(view); dialog.setContentView(view);
dialog.show(); dialog.show();
repoCopyUrl.setOnClickListener(openInBrowser -> {
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("repoUrl", htmlUrl.getText().toString());
assert clipboard != null;
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.copyIssueUrlToastMsg));
dialog.dismiss();
});
repoOpenInBrowser.setOnClickListener(openInBrowser -> { repoOpenInBrowser.setOnClickListener(openInBrowser -> {
Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class); Intent intentOpenInBrowser = new Intent(context, OpenRepoInBrowserActivity.class);
@ -229,15 +210,6 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
}); });
repoForksList.setOnClickListener(forks -> {
Intent intentW = new Intent(context, RepoForksActivity.class);
intentW.putExtra("repoFullNameForForks", fullName.getText());
context.startActivity(intentW);
dialog.dismiss();
});
}); });
} }
@ -263,7 +235,6 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
UserRepositories currentItem = reposList.get(position); UserRepositories currentItem = reposList.get(position);
holder.repoDescription.setVisibility(View.GONE); holder.repoDescription.setVisibility(View.GONE);
holder.repoBranch.setText(currentItem.getDefault_branch()); holder.repoBranch.setText(currentItem.getDefault_branch());
holder.htmlUrl.setText(currentItem.getHtml_url());
ColorGenerator generator = ColorGenerator.MATERIAL; ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(currentItem.getName()); int color = generator.getColor(currentItem.getName());
@ -295,13 +266,13 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
holder.repoDescription.setVisibility(View.VISIBLE); holder.repoDescription.setVisibility(View.VISIBLE);
holder.repoDescription.setText(currentItem.getDescription()); holder.repoDescription.setText(currentItem.getDescription());
} }
holder.fullName.setText(currentItem.getFullName()); holder.fullName.setText(currentItem.getFullname());
if(currentItem.getPrivateFlag()) { if(currentItem.getPrivateFlag()) {
holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock); holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock);
holder.repoType.setText(R.string.strPrivate); holder.repoType.setText(R.string.strPrivate);
} }
else { else {
holder.repoPrivatePublic.setVisibility(View.GONE); holder.repoPrivatePublic.setImageResource(R.drawable.ic_unlock);
holder.repoType.setText(R.string.strPublic); holder.repoType.setText(R.string.strPublic);
} }
holder.repoStars.setText(currentItem.getStars_count()); holder.repoStars.setText(currentItem.getStars_count());
@ -342,7 +313,7 @@ public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposLi
String filterPattern = constraint.toString().toLowerCase().trim(); String filterPattern = constraint.toString().toLowerCase().trim();
for (UserRepositories item : reposListFull) { for (UserRepositories item : reposListFull) {
if (item.getFullName().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) { if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
filteredList.add(item); filteredList.add(item);
} }
} }

View File

@ -1,7 +1,6 @@
package org.mian.gitnex.adapters; package org.mian.gitnex.adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -9,11 +8,9 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount; import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
@ -31,15 +28,13 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
private Context mCtx; private Context mCtx;
private TinyDB tinyDB; private TinyDB tinyDB;
class UserAccountsViewHolder extends RecyclerView.ViewHolder { static class UserAccountsViewHolder extends RecyclerView.ViewHolder {
private TextView accountUrl; private TextView accountUrl;
private TextView userId; private TextView userId;
private ImageView activeAccount; private ImageView activeAccount;
private ImageView deleteAccount; private ImageView deleteAccount;
private ImageView repoAvatar; private ImageView repoAvatar;
private TextView accountId;
private TextView accountName;
private UserAccountsViewHolder(View itemView) { private UserAccountsViewHolder(View itemView) {
@ -50,46 +45,14 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
activeAccount = itemView.findViewById(R.id.activeAccount); activeAccount = itemView.findViewById(R.id.activeAccount);
deleteAccount = itemView.findViewById(R.id.deleteAccount); deleteAccount = itemView.findViewById(R.id.deleteAccount);
repoAvatar = itemView.findViewById(R.id.repoAvatar); repoAvatar = itemView.findViewById(R.id.repoAvatar);
accountId = itemView.findViewById(R.id.accountId);
accountName = itemView.findViewById(R.id.accountName);
deleteAccount.setOnClickListener(itemDelete -> { deleteAccount.setOnClickListener(itemDelete -> {
// use later to delete an account
new AlertDialog.Builder(mCtx)
.setIcon(mCtx.getDrawable(R.drawable.ic_delete))
.setTitle(mCtx.getResources().getString(R.string.removeAccountPopupTitle))
.setMessage(mCtx.getResources().getString(R.string.removeAccountPopupMessage))
.setPositiveButton(mCtx.getResources().getString(R.string.removeButton), (dialog, which) -> {
updateLayoutByPosition(getAdapterPosition());
UserAccountsApi userAccountsApi = new UserAccountsApi(mCtx);
userAccountsApi.deleteAccount(Integer.parseInt(accountId.getText().toString()));
}).setNeutralButton(mCtx.getResources().getString(R.string.cancelButton), null)
.show();
}); });
itemView.setOnClickListener(itemEdit -> { itemView.setOnClickListener(itemEdit -> {
// use later to switch account
String accountNameSwitch = accountName.getText().toString();
UserAccountsApi userAccountsApi = new UserAccountsApi(mCtx);
UserAccount userAccount = userAccountsApi.getAccountData(accountNameSwitch);
if(tinyDB.getInt("currentActiveAccountId") != userAccount.getAccountId()) {
String url = UrlBuilder.fromString(userAccount.getInstanceUrl())
.withPath("/")
.toString();
tinyDB.putString("loginUid", userAccount.getUserName());
tinyDB.putString("userLogin", userAccount.getUserName());
tinyDB.putString(userAccount.getUserName() + "-token", userAccount.getToken());
tinyDB.putString("instanceUrl", userAccount.getInstanceUrl());
tinyDB.putInt("currentActiveAccountId", userAccount.getAccountId());
Toasty.success(mCtx, mCtx.getResources().getString(R.string.switchAccountSuccess, userAccount.getUserName(), url));
((Activity) mCtx).recreate();
}
}); });
@ -103,12 +66,12 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
this.userAccountsList = userAccountsListMain; this.userAccountsList = userAccountsListMain;
} }
private void updateLayoutByPosition(int position) { private void deleteAccount(int position) {
userAccountsList.remove(position); userAccountsList.remove(position);
notifyItemRemoved(position); notifyItemRemoved(position);
notifyItemRangeChanged(position, userAccountsList.size()); notifyItemRangeChanged(position, userAccountsList.size());
Toasty.success(mCtx, mCtx.getResources().getString(R.string.accountDeletedMessage)); Toasty.info(mCtx, mCtx.getResources().getString(R.string.accountDeletedMessage));
} }
@ -131,8 +94,6 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
.withPath("/") .withPath("/")
.toString(); .toString();
holder.accountId.setText(String.valueOf(currentItem.getAccountId()));
holder.accountName.setText(currentItem.getAccountName());
holder.userId.setText(String.format("@%s", currentItem.getUserName())); holder.userId.setText(String.format("@%s", currentItem.getUserName()));
holder.accountUrl.setText(url); holder.accountUrl.setText(url);
@ -142,7 +103,7 @@ public class UserAccountsAdapter extends RecyclerView.Adapter<UserAccountsAdapte
holder.activeAccount.setVisibility(View.VISIBLE); holder.activeAccount.setVisibility(View.VISIBLE);
} }
else { else {
holder.deleteAccount.setVisibility(View.VISIBLE); holder.deleteAccount.setVisibility(View.GONE);
} }
} }

View File

@ -1,76 +0,0 @@
package org.mian.gitnex.adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import java.util.List;
import io.mikael.urlbuilder.UrlBuilder;
/**
* Author M M Arif
*/
public class UserAccountsListDialogAdapter extends ArrayAdapter<UserAccount> {
private final Context mCtx;
private final TinyDB tinyDB;
private final List<UserAccount> userAccounts;
public UserAccountsListDialogAdapter(@NonNull Context mCtx, int resource, @NonNull List<UserAccount> userAccounts) {
super(mCtx, resource, userAccounts);
tinyDB = new TinyDB(mCtx);
this.userAccounts = userAccounts;
this.mCtx = mCtx;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
if(convertView == null) {
convertView = LayoutInflater.from(mCtx).inflate(R.layout.custom_user_accounts_list, parent, false);
}
ImageView profileImage = convertView.findViewById(R.id.profileImage);
TextView userName = convertView.findViewById(R.id.userName);
TextView accountUrl = convertView.findViewById(R.id.accountUrl);
ImageView activeAccount = convertView.findViewById(R.id.activeAccount);
UserAccount currentItem = userAccounts.get(position);
String url = UrlBuilder.fromString(currentItem.getInstanceUrl())
.withPath("/")
.toString();
userName.setText(currentItem.getUserName());
accountUrl.setText(url);
if(tinyDB.getInt("currentActiveAccountId") == currentItem.getAccountId()) {
activeAccount.setVisibility(View.VISIBLE);
}
else {
activeAccount.setVisibility(View.GONE);
}
PicassoService
.getInstance(mCtx).get().load(url + "img/favicon.png").placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(profileImage);
return convertView;
}
}

View File

@ -1,147 +0,0 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.RecyclerView;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.fragments.UserAccountsFragment;
import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.List;
import io.mikael.urlbuilder.UrlBuilder;
/**
* Author M M Arif
*/
public class UserAccountsNavAdapter extends RecyclerView.Adapter<UserAccountsNavAdapter.UserAccountsViewHolder> {
private static DrawerLayout drawer;
private List<UserAccount> userAccountsList;
private Context mCtx;
private TextView toolbarTitle;
public UserAccountsNavAdapter(Context mCtx, List<UserAccount> userAccountsListMain, DrawerLayout drawerLayout, TextView toolbarTitle) {
this.mCtx = mCtx;
this.userAccountsList = userAccountsListMain;
drawer = drawerLayout;
this.toolbarTitle = toolbarTitle;
}
class UserAccountsViewHolder extends RecyclerView.ViewHolder {
private ImageView userAccountAvatar;
private UserAccountsViewHolder(View itemView) {
super(itemView);
userAccountAvatar = itemView.findViewById(R.id.userAccountAvatar);
itemView.setOnClickListener(item -> {
customDialogUserAccountsList(userAccountsList);
drawer.closeDrawers();
});
}
}
@NonNull
@Override
public UserAccountsNavAdapter.UserAccountsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.nav_user_accounts, parent, false);
return new UserAccountsViewHolder(v);
}
@SuppressLint("DefaultLocale")
@Override
public void onBindViewHolder(@NonNull UserAccountsNavAdapter.UserAccountsViewHolder holder, int position) {
UserAccount currentItem = userAccountsList.get(position);
String url = UrlBuilder.fromString(currentItem.getInstanceUrl())
.withPath("/")
.toString();
PicassoService
.getInstance(mCtx).get().load(url + "img/favicon.png").placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(holder.userAccountAvatar);
}
@Override
public int getItemCount() {
return userAccountsList.size();
}
private void customDialogUserAccountsList(List<UserAccount> allAccountsList) {
TinyDB tinyDB = new TinyDB(mCtx);
Dialog dialog = new Dialog(mCtx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
dialog.setContentView(R.layout.custom_user_accounts_dialog);
ListView listView = dialog.findViewById(R.id.accountsList);
TextView manageAccounts = dialog.findViewById(R.id.manageAccounts);
if (dialog.getWindow() != null) {
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
manageAccounts.setOnClickListener(item -> {
toolbarTitle.setText(mCtx.getResources().getString(R.string.pageTitleUserAccounts));
AppCompatActivity activity = (AppCompatActivity) mCtx;
activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new UserAccountsFragment()).commit();
dialog.dismiss();
});
UserAccountsListDialogAdapter arrayAdapter = new UserAccountsListDialogAdapter(mCtx, R.layout.custom_user_accounts_list, allAccountsList);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener((adapterView, view, which, l) -> {
String accountNameSwitch = allAccountsList.get(which).getAccountName();
UserAccountsApi userAccountsApi = new UserAccountsApi(mCtx);
UserAccount userAccount = userAccountsApi.getAccountData(accountNameSwitch);
if(tinyDB.getInt("currentActiveAccountId") != userAccount.getAccountId()) {
String url = UrlBuilder.fromString(userAccount.getInstanceUrl())
.withPath("/")
.toString();
tinyDB.putString("loginUid", userAccount.getUserName());
tinyDB.putString("userLogin", userAccount.getUserName());
tinyDB.putString(userAccount.getUserName() + "-token", userAccount.getToken());
tinyDB.putString("instanceUrl", userAccount.getInstanceUrl());
tinyDB.putInt("currentActiveAccountId", userAccount.getAccountId());
Toasty.success(mCtx, mCtx.getResources().getString(R.string.switchAccountSuccess, userAccount.getUserName(), url));
((Activity) mCtx).recreate();
dialog.dismiss();
}
});
dialog.show();
}
}

View File

@ -27,7 +27,7 @@ public class DraftsApi {
draftsDao = db.draftsDao(); draftsDao = db.draftsDao();
} }
public long insertDraft(int repositoryId, int draftAccountId, int issueId, String draftText, String draftType, String commentId) { public long insertDraft(int repositoryId, int draftAccountId, int issueId, String draftText, String draftType) {
Draft draft = new Draft(); Draft draft = new Draft();
draft.setDraftRepositoryId(repositoryId); draft.setDraftRepositoryId(repositoryId);
@ -35,7 +35,6 @@ public class DraftsApi {
draft.setIssueId(issueId); draft.setIssueId(issueId);
draft.setDraftText(draftText); draft.setDraftText(draftText);
draft.setDraftType(draftType); draft.setDraftType(draftType);
draft.setCommentId(draftType);
return insertDraftAsyncTask(draft); return insertDraftAsyncTask(draft);
} }
@ -50,7 +49,7 @@ public class DraftsApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.draftsApi, e.toString()); Log.e(StaticGlobalVariables.draftsRepository, e.toString());
} }
return draftId; return draftId;
@ -66,23 +65,23 @@ public class DraftsApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.draftsApi, e.toString()); Log.e(StaticGlobalVariables.draftsRepository, e.toString());
} }
return draftId; return draftId;
} }
public Integer checkDraft(int issueId, int draftRepositoryId, String commentId) { public Integer checkDraft(int issueId, int draftRepositoryId) {
try { try {
Thread thread = new Thread(() -> checkDraftFlag = draftsDao.checkDraftDao(issueId, draftRepositoryId, commentId)); Thread thread = new Thread(() -> checkDraftFlag = draftsDao.checkDraftDao(issueId, draftRepositoryId));
thread.start(); thread.start();
thread.join(); thread.join();
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.draftsApi, e.toString()); Log.e(StaticGlobalVariables.draftsRepository, e.toString());
} }
return checkDraftFlag; return checkDraftFlag;
@ -113,14 +112,14 @@ public class DraftsApi {
new Thread(() -> draftsDao.deleteAllDrafts(accountId)).start(); new Thread(() -> draftsDao.deleteAllDrafts(accountId)).start();
} }
public static void updateDraft(final String draftText, final int draftId, final String commentId) { public static void updateDraft(final String draftText, final int draftId) {
new Thread(() -> draftsDao.updateDraft(draftText, draftId, commentId)).start(); new Thread(() -> draftsDao.updateDraft(draftText, draftId)).start();
} }
public static void updateDraftByIssueIdAsyncTask(final String draftText, final int issueId, final int draftRepositoryId, final String commentId) { public static void updateDraftByIssueIdAsyncTask(final String draftText, final int issueId, final int draftRepositoryId) {
new Thread(() -> draftsDao.updateDraftByIssueId(draftText, issueId, draftRepositoryId, commentId)).start(); new Thread(() -> draftsDao.updateDraftByIssueId(draftText, issueId, draftRepositoryId)).start();
} }
} }

View File

@ -47,7 +47,7 @@ public class RepositoriesApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); Log.e(StaticGlobalVariables.repositoriesRepository, e.toString());
} }
return repositoryId; return repositoryId;
@ -63,7 +63,7 @@ public class RepositoriesApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); Log.e(StaticGlobalVariables.repositoriesRepository, e.toString());
} }
return repository; return repository;
@ -89,7 +89,7 @@ public class RepositoriesApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); Log.e(StaticGlobalVariables.repositoriesRepository, e.toString());
} }
return checkRepository; return checkRepository;
@ -105,7 +105,7 @@ public class RepositoriesApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); Log.e(StaticGlobalVariables.repositoriesRepository, e.toString());
} }
return repository; return repository;
@ -121,17 +121,12 @@ public class RepositoriesApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); Log.e(StaticGlobalVariables.repositoriesRepository, e.toString());
} }
return repository; return repository;
} }
public static void updateRepositoryOwnerAndName(String repositoryOwner, String repositoryName, int repositoryId) {
new Thread(() -> repositoriesDao.updateRepositoryOwnerAndName(repositoryOwner, repositoryName, repositoryId)).start();
}
public static void deleteRepositoriesByAccount(final int repoAccountId) { public static void deleteRepositoriesByAccount(final int repoAccountId) {
new Thread(() -> repositoriesDao.deleteRepositoriesByAccount(repoAccountId)).start(); new Thread(() -> repositoriesDao.deleteRepositoriesByAccount(repoAccountId)).start();

View File

@ -17,9 +17,7 @@ public class UserAccountsApi {
private static UserAccountsDao userAccountsDao; private static UserAccountsDao userAccountsDao;
private static UserAccount userAccount; private static UserAccount userAccount;
private static List<UserAccount> userAccounts;
private static Integer checkAccount; private static Integer checkAccount;
private static long accountId;
public UserAccountsApi(Context context) { public UserAccountsApi(Context context) {
@ -28,7 +26,7 @@ public class UserAccountsApi {
userAccountsDao = db.userAccountsDao(); userAccountsDao = db.userAccountsDao();
} }
public long insertNewAccount(String accountName, String instanceUrl, String userName, String token, String serverVersion) { public void insertNewAccount(String accountName, String instanceUrl, String userName, String token, String serverVersion) {
UserAccount userAccount = new UserAccount(); UserAccount userAccount = new UserAccount();
userAccount.setAccountName(accountName); userAccount.setAccountName(accountName);
@ -37,23 +35,12 @@ public class UserAccountsApi {
userAccount.setToken(token); userAccount.setToken(token);
userAccount.setServerVersion(serverVersion); userAccount.setServerVersion(serverVersion);
return insertNewAccountAsync(userAccount); insertNewAccountAsync(userAccount);
} }
private static long insertNewAccountAsync(final UserAccount userAccount) { private static void insertNewAccountAsync(final UserAccount userAccount) {
try { new Thread(() -> userAccountsDao.newAccount(userAccount)).start();
Thread thread = new Thread(() -> accountId = userAccountsDao.newAccount(userAccount));
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(StaticGlobalVariables.userAccountsApi, e.toString());
}
return accountId;
} }
public static void updateServerVersion(final String serverVersion, final int accountId) { public static void updateServerVersion(final String serverVersion, final int accountId) {
@ -61,16 +48,11 @@ public class UserAccountsApi {
new Thread(() -> userAccountsDao.updateServerVersion(serverVersion, accountId)).start(); new Thread(() -> userAccountsDao.updateServerVersion(serverVersion, accountId)).start();
} }
public void updateToken(final int accountId, final String token) { public static void updateToken(final int accountId, final String token) {
new Thread(() -> userAccountsDao.updateAccountToken(accountId, token)).start(); new Thread(() -> userAccountsDao.updateAccountToken(accountId, token)).start();
} }
public void updateTokenByAccountName(final String accountName, final String token) {
new Thread(() -> userAccountsDao.updateAccountTokenByAccountName(accountName, token)).start();
}
public UserAccount getAccountData(String accountName) { public UserAccount getAccountData(String accountName) {
try { try {
@ -81,7 +63,7 @@ public class UserAccountsApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); Log.e(StaticGlobalVariables.userAccountsRepository, e.toString());
} }
return userAccount; return userAccount;
@ -97,7 +79,7 @@ public class UserAccountsApi {
} }
catch(InterruptedException e) { catch(InterruptedException e) {
Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); Log.e(StaticGlobalVariables.userAccountsRepository, e.toString());
} }
return checkAccount; return checkAccount;
@ -108,23 +90,7 @@ public class UserAccountsApi {
return userAccountsDao.fetchAllAccounts(); return userAccountsDao.fetchAllAccounts();
} }
public List<UserAccount> usersAccounts() { public static void deleteAccount(final int accountId) {
try {
Thread thread = new Thread(() -> userAccounts = userAccountsDao.userAccounts());
thread.start();
thread.join();
}
catch(InterruptedException e) {
Log.e(StaticGlobalVariables.userAccountsApi, e.toString());
}
return userAccounts;
}
public void deleteAccount(final int accountId) {
new Thread(() -> userAccountsDao.deleteAccount(accountId)).start(); new Thread(() -> userAccountsDao.deleteAccount(accountId)).start();
} }

View File

@ -35,14 +35,14 @@ public interface DraftsDao {
@Query("SELECT * FROM Drafts WHERE issueId = :issueId") @Query("SELECT * FROM Drafts WHERE issueId = :issueId")
LiveData<Draft> fetchDraftByIssueId(int issueId); LiveData<Draft> fetchDraftByIssueId(int issueId);
@Query("SELECT count(draftId) FROM Drafts WHERE issueId = :issueId AND draftRepositoryId = :draftRepositoryId AND commentId = :commentId") @Query("SELECT count(draftId) FROM Drafts WHERE issueId = :issueId AND draftRepositoryId = :draftRepositoryId")
Integer checkDraftDao(int issueId, int draftRepositoryId, String commentId); Integer checkDraftDao(int issueId, int draftRepositoryId);
@Query("UPDATE Drafts SET draftText = :draftText, commentId = :commentId WHERE draftId = :draftId") @Query("UPDATE Drafts SET draftText= :draftText WHERE draftId = :draftId")
void updateDraft(String draftText, int draftId, String commentId); void updateDraft(String draftText, int draftId);
@Query("UPDATE Drafts SET draftText = :draftText WHERE issueId = :issueId AND draftRepositoryId = :draftRepositoryId AND commentId = :commentId") @Query("UPDATE Drafts SET draftText= :draftText WHERE issueId = :issueId AND draftRepositoryId = :draftRepositoryId")
void updateDraftByIssueId(String draftText, int issueId, int draftRepositoryId, String commentId); void updateDraftByIssueId(String draftText, int issueId, int draftRepositoryId);
@Query("SELECT draftId FROM Drafts WHERE issueId = :issueId AND draftRepositoryId = :draftRepositoryId") @Query("SELECT draftId FROM Drafts WHERE issueId = :issueId AND draftRepositoryId = :draftRepositoryId")
Integer getDraftId(int issueId, int draftRepositoryId); Integer getDraftId(int issueId, int draftRepositoryId);

View File

@ -15,14 +15,11 @@ import java.util.List;
public interface UserAccountsDao { public interface UserAccountsDao {
@Insert @Insert
long newAccount(UserAccount userAccounts); void newAccount(UserAccount userAccounts);
@Query("SELECT * FROM UserAccounts ORDER BY accountId ASC") @Query("SELECT * FROM UserAccounts ORDER BY accountId ASC")
LiveData<List<UserAccount>> fetchAllAccounts(); LiveData<List<UserAccount>> fetchAllAccounts();
@Query("SELECT * FROM UserAccounts ORDER BY accountId ASC")
List<UserAccount> userAccounts();
@Query("SELECT COUNT(accountId) FROM UserAccounts WHERE accountName = :accountName") @Query("SELECT COUNT(accountId) FROM UserAccounts WHERE accountName = :accountName")
Integer getCount(String accountName); Integer getCount(String accountName);
@ -41,9 +38,6 @@ public interface UserAccountsDao {
@Query("UPDATE UserAccounts SET token = :token WHERE accountId = :accountId") @Query("UPDATE UserAccounts SET token = :token WHERE accountId = :accountId")
void updateAccountToken(int accountId, String token); void updateAccountToken(int accountId, String token);
@Query("UPDATE UserAccounts SET token = :token WHERE accountName = :accountName")
void updateAccountTokenByAccountName(String accountName, String token);
@Query("UPDATE UserAccounts SET instanceUrl = :instanceUrl, token = :token WHERE accountId = :accountId") @Query("UPDATE UserAccounts SET instanceUrl = :instanceUrl, token = :token WHERE accountId = :accountId")
void updateHostInfo(String instanceUrl, String token, int accountId); void updateHostInfo(String instanceUrl, String token, int accountId);

View File

@ -19,7 +19,7 @@ import org.mian.gitnex.database.models.UserAccount;
*/ */
@Database(entities = {Draft.class, Repository.class, UserAccount.class}, @Database(entities = {Draft.class, Repository.class, UserAccount.class},
version = 2, exportSchema = false) version = 1, exportSchema = false)
public abstract class GitnexDatabase extends RoomDatabase { public abstract class GitnexDatabase extends RoomDatabase {
private static GitnexDatabase gitnexDatabase; private static GitnexDatabase gitnexDatabase;
@ -30,7 +30,7 @@ public abstract class GitnexDatabase extends RoomDatabase {
String DB_NAME = "gitnex"; String DB_NAME = "gitnex";
gitnexDatabase = Room.databaseBuilder(context, GitnexDatabase.class, DB_NAME) gitnexDatabase = Room.databaseBuilder(context, GitnexDatabase.class, DB_NAME)
//.fallbackToDestructiveMigration() //.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_1_2) //.addMigrations(MIGRATION_1_2)
.build(); .build();
} }
@ -48,7 +48,7 @@ public abstract class GitnexDatabase extends RoomDatabase {
public void migrate(@NonNull SupportSQLiteDatabase database) { public void migrate(@NonNull SupportSQLiteDatabase database) {
//database.execSQL("DROP TABLE Drafts"); //database.execSQL("DROP TABLE Drafts");
database.execSQL("ALTER TABLE 'Drafts' ADD COLUMN 'commentId' TEXT"); //database.execSQL("ALTER TABLE 'Drafts' ADD COLUMN 'draftType' TEXT");
} }
}; };

View File

@ -24,8 +24,6 @@ public class Draft implements Serializable {
private String draftText; private String draftText;
@Nullable @Nullable
private String draftType; private String draftType;
@Nullable
private String commentId;
public int getDraftId() { public int getDraftId() {
@ -88,15 +86,4 @@ public class Draft implements Serializable {
this.draftType = draftType; this.draftType = draftType;
} }
@Nullable
public String getCommentId() {
return commentId;
}
public void setCommentId(@Nullable String commentId) {
this.commentId = commentId;
}
} }

View File

@ -18,7 +18,6 @@ public class DraftWithRepository {
private int issueId; private int issueId;
private String draftText; private String draftText;
private String draftType; private String draftType;
private String commentId;
public int getRepositoryId() { public int getRepositoryId() {
@ -120,14 +119,4 @@ public class DraftWithRepository {
this.draftType = draftType; this.draftType = draftType;
} }
public String getCommentId() {
return commentId;
}
public void setCommentId(String commentId) {
this.commentId = commentId;
}
} }

View File

@ -6,13 +6,16 @@ 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.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.activities.CreditsActivity;
import org.mian.gitnex.databinding.FragmentAboutBinding; import org.mian.gitnex.activities.SponsorsActivity;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import java.util.Objects;
/** /**
* Author M M Arif * Author M M Arif
@ -20,63 +23,99 @@ import org.mian.gitnex.helpers.TinyDB;
public class AboutFragment extends Fragment { public class AboutFragment extends Fragment {
@Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_about, container, false);
FragmentAboutBinding viewBinding = FragmentAboutBinding.inflate(inflater, container, false);
TinyDB tinyDb = new TinyDB(getContext()); TinyDB tinyDb = new TinyDB(getContext());
viewBinding.appVersion.setText(AppUtil.getAppVersion(requireContext())); final TextView appVerBuild;
viewBinding.userServerVersion.setText(tinyDb.getString("giteaVersion")); final TextView donationLink;
viewBinding.appBuild.setText(String.valueOf(AppUtil.getAppBuildNo(requireContext()))); final TextView donationLinkPatreon;
final TextView translateLink;
final TextView creditsButton;
final TextView sponsorsButton;
final TextView appWebsite;
final TextView appRepo;
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.pageTitleAbout)); appVerBuild = v.findViewById(R.id.appVerBuild);
TextView viewTextGiteaVersion = v.findViewById(R.id.giteaVersion);
creditsButton = v.findViewById(R.id.creditsButton);
donationLink = v.findViewById(R.id.donationLink);
donationLinkPatreon = v.findViewById(R.id.donationLinkPatreon);
translateLink = v.findViewById(R.id.translateLink);
sponsorsButton = v.findViewById(R.id.sponsorsButton);
appWebsite = v.findViewById(R.id.appWebsite);
appRepo = v.findViewById(R.id.appRepo);
viewBinding.donationLinkLiberapay.setOnClickListener(v1 -> { appVerBuild.setText(getString(R.string.appVerBuild, AppUtil.getAppVersion(Objects.requireNonNull(getContext())), AppUtil.getAppBuildNo(getContext())));
donationLink.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.supportLink))); intent.setData(Uri.parse(getResources().getString(R.string.supportLink)));
startActivity(intent); startActivity(intent);
}
}); });
viewBinding.donationLinkPatreon.setOnClickListener(v12 -> { donationLinkPatreon.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.supportLinkPatreon))); intent.setData(Uri.parse(getResources().getString(R.string.supportLinkPatreon)));
startActivity(intent); startActivity(intent);
}
}); });
viewBinding.translateLink.setOnClickListener(v13 -> { translateLink.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);
}
}); });
viewBinding.appWebsite.setOnClickListener(v14 -> { appWebsite.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.appWebsiteLink))); intent.setData(Uri.parse(getResources().getString(R.string.appWebsiteLink)));
startActivity(intent); startActivity(intent);
}
}); });
if(AppUtil.isPro(requireContext())) { appRepo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
viewBinding.supportHeader.setVisibility(View.GONE); Intent intent = new Intent();
viewBinding.dividerSupport.setVisibility(View.GONE); intent.setAction(Intent.ACTION_VIEW);
viewBinding.donationLinkLiberapay.setVisibility(View.GONE); intent.addCategory(Intent.CATEGORY_BROWSABLE);
viewBinding.donationLinkPatreon.setVisibility(View.GONE); intent.setData(Uri.parse(getResources().getString(R.string.appRepoLink)));
startActivity(intent);
} }
});
return viewBinding.getRoot(); creditsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(getContext(), CreditsActivity.class));
}
});
sponsorsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(getContext(), SponsorsActivity.class));
}
});
String commit = getResources().getString(R.string.commitPage) + tinyDb.getString("giteaVersion");
viewTextGiteaVersion.setText(commit);
return v;
} }
} }

View File

@ -26,10 +26,12 @@ public class BottomSheetAdminUsersFragment extends BottomSheetDialogFragment {
TextView createNewUser = v.findViewById(R.id.createNewUser); TextView createNewUser = v.findViewById(R.id.createNewUser);
createNewUser.setOnClickListener(v1 -> { createNewUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("newUser"); bmListener.onButtonClicked("newUser");
dismiss(); dismiss();
}
}); });
return v; return v;
@ -45,9 +47,9 @@ public class BottomSheetAdminUsersFragment extends BottomSheetDialogFragment {
try { try {
bmListener = (BottomSheetAdminUsersFragment.BottomSheetListener) context; bmListener = (BottomSheetAdminUsersFragment.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

@ -26,25 +26,13 @@ public class BottomSheetFileViewerFragment extends BottomSheetDialogFragment {
View v = inflater.inflate(R.layout.bottom_sheet_file_viewer, container, false); View v = inflater.inflate(R.layout.bottom_sheet_file_viewer, container, false);
TextView downloadFile = v.findViewById(R.id.downloadFile); TextView downloadFile = v.findViewById(R.id.downloadFile);
TextView deleteFile = v.findViewById(R.id.deleteFile);
TextView editFile = v.findViewById(R.id.editFile);
downloadFile.setOnClickListener(v1 -> {
downloadFile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bmListener.onButtonClicked("downloadFile"); bmListener.onButtonClicked("downloadFile");
dismiss(); dismiss();
}); }
deleteFile.setOnClickListener(v1 -> {
bmListener.onButtonClicked("deleteFile");
dismiss();
});
editFile.setOnClickListener(v1 -> {
bmListener.onButtonClicked("editFile");
dismiss();
}); });
return v; return v;
@ -59,12 +47,10 @@ public class BottomSheetFileViewerFragment extends BottomSheetDialogFragment {
super.onAttach(context); super.onAttach(context);
try { try {
bmListener = (BottomSheetFileViewerFragment.BottomSheetListener) context; bmListener = (BottomSheetFileViewerFragment.BottomSheetListener) context;
} } catch (ClassCastException e) {
catch (ClassCastException e) { throw new ClassCastException(context.toString()
+ " must implement BottomSheetListener");
throw new ClassCastException(context.toString() + " must implement BottomSheetListener");
} }
} }

View File

@ -27,7 +27,6 @@ public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment {
TextView createTeam = v.findViewById(R.id.createTeam); TextView createTeam = v.findViewById(R.id.createTeam);
TextView createRepository = v.findViewById(R.id.createRepository); TextView createRepository = v.findViewById(R.id.createRepository);
TextView copyOrgUrl = v.findViewById(R.id.copyOrgUrl);
createTeam.setOnClickListener(v1 -> { createTeam.setOnClickListener(v1 -> {
@ -41,12 +40,6 @@ public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment {
dismiss(); dismiss();
}); });
copyOrgUrl.setOnClickListener(v1 -> {
bmListener.onButtonClicked("copyOrgUrl");
dismiss();
});
return v; return v;
} }

View File

@ -25,10 +25,12 @@ public class BottomSheetProfileFragment extends BottomSheetDialogFragment {
TextView addNewEmailAddress = v.findViewById(R.id.addNewEmailAddress); TextView addNewEmailAddress = v.findViewById(R.id.addNewEmailAddress);
addNewEmailAddress.setOnClickListener(v1 -> { addNewEmailAddress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getContext(), ProfileEmailActivity.class)); startActivity(new Intent(getContext(), ProfileEmailActivity.class));
dismiss(); dismiss();
}
}); });
return v; return v;

View File

@ -1,214 +0,0 @@
package org.mian.gitnex.fragments;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.ActionResult;
import org.mian.gitnex.actions.IssueActions;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.database.api.DraftsApi;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
import java.util.Objects;
/**
* @author opyale
*/
public class BottomSheetReplyFragment extends BottomSheetDialogFragment {
private TinyDB tinyDB;
private DraftsApi draftsApi;
private int repositoryId;
private int currentActiveAccountId;
private int issueNumber;
private long draftId;
private TextView draftsHint;
@Override
public void onAttach(@NonNull Context context) {
tinyDB = new TinyDB(context);
draftsApi = new DraftsApi(context);
repositoryId = (int) tinyDB.getLong("repositoryId", 0);
currentActiveAccountId = tinyDB.getInt("currentActiveAccountId");
issueNumber = Integer.parseInt(tinyDB.getString("issueNumber"));
super.onAttach(context);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottom_sheet_reply_layout, container, false);
Bundle arguments = requireArguments();
draftsHint = view.findViewById(R.id.drafts_hint);
EditText commentContent = view.findViewById(R.id.comment);
TextView toolbarTitle = view.findViewById(R.id.toolbar_title);
ImageButton close = view.findViewById(R.id.close);
ImageButton drafts = view.findViewById(R.id.drafts);
ImageButton send = view.findViewById(R.id.send);
send.setEnabled(false);
if(Objects.equals(arguments.getString("commentAction"), "edit")) {
send.setVisibility(View.GONE);
}
if(arguments.getString("draftId") != null) {
draftId = Long.parseLong(arguments.getString("draftId"));
}
if(!tinyDB.getString("issueTitle").isEmpty()) {
toolbarTitle.setText(tinyDB.getString("issueTitle"));
}
else if(arguments.getString("draftTitle") != null) {
toolbarTitle.setText(arguments.getString("draftTitle"));
}
if(arguments.getString("commentBody") != null) {
send.setEnabled(true);
send.setAlpha(1f);
commentContent.setText(arguments.getString("commentBody"));
if(arguments.getBoolean("cursorToEnd", false)) {
commentContent.setSelection(commentContent.length());
}
}
commentContent.requestFocus();
commentContent.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
String text = commentContent.getText().toString();
if(text.isEmpty()) {
send.setEnabled(false);
send.setAlpha(0.5f);
saveDraft(null, true);
}
else {
send.setEnabled(true);
send.setAlpha(1f);
saveDraft(text, false);
}
}
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
close.setOnClickListener(v -> dismiss());
drafts.setOnClickListener(v -> {
Intent intent = new Intent(getContext(), MainActivity.class);
intent.putExtra("launchFragment", "drafts");
startActivity(intent);
dismiss();
});
send.setOnClickListener(v -> IssueActions
.reply(getContext(), commentContent.getText().toString(), issueNumber)
.accept((status, result) -> {
if(status == ActionResult.Status.SUCCESS) {
Toasty.success(getContext(), getString(R.string.commentSuccess));
tinyDB.putBoolean("commentPosted", true);
tinyDB.putBoolean("resumeIssues", true);
tinyDB.putBoolean("resumePullRequests", true);
if(draftId != 0 && tinyDB.getBoolean("draftsCommentsDeletionEnabled")) {
draftsApi.deleteSingleDraft((int) draftId);
}
dismiss();
}
else {
Toasty.error(getContext(), getString(R.string.commentError));
dismiss();
}
}));
return view;
}
private void saveDraft(String text, boolean remove) {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.setDuration(500);
valueAnimator.addUpdateListener(animation -> {
float value = (Float) animation.getAnimatedValue();
if(value == 0f) {
draftsHint.setVisibility((remove) ? View.GONE : View.VISIBLE);
}
draftsHint.setAlpha(value);
});
if(remove) {
draftsApi.deleteSingleDraft((int) draftId);
draftId = 0;
valueAnimator.reverse();
}
else {
if(draftId == 0) {
draftId = draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, text, StaticGlobalVariables.draftTypeComment, "TODO");
} else {
DraftsApi.updateDraft(text, (int) draftId, "TODO");
}
draftsHint.setVisibility(View.VISIBLE);
valueAnimator.start();
}
}
public static BottomSheetReplyFragment newInstance(Bundle bundle) {
BottomSheetReplyFragment fragment = new BottomSheetReplyFragment();
fragment.setArguments(bundle);
return fragment;
}
}

View File

@ -40,10 +40,6 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
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); TextView shareRepository = v.findViewById(R.id.shareRepository);
TextView copyRepoUrl = v.findViewById(R.id.copyRepoUrl);
View repoSettingsDivider = v.findViewById(R.id.repoSettingsDivider);
TextView repoSettings = v.findViewById(R.id.repoSettings);
TextView createPullRequest = v.findViewById(R.id.createPullRequest);
createLabel.setOnClickListener(v112 -> { createLabel.setOnClickListener(v112 -> {
@ -52,7 +48,6 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
}); });
if(tinyDb.getBoolean("hasIssues")) { if(tinyDb.getBoolean("hasIssues")) {
createIssue.setVisibility(View.VISIBLE); createIssue.setVisibility(View.VISIBLE);
createIssue.setOnClickListener(v12 -> { createIssue.setOnClickListener(v12 -> {
@ -61,24 +56,9 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
}); });
} }
else { else {
createIssue.setVisibility(View.GONE); createIssue.setVisibility(View.GONE);
} }
if(tinyDb.getBoolean("hasPullRequests")) {
createPullRequest.setVisibility(View.VISIBLE);
createPullRequest.setOnClickListener(vPr -> {
bmListener.onButtonClicked("newPullRequest");
dismiss();
});
}
else {
createPullRequest.setVisibility(View.GONE);
}
createMilestone.setOnClickListener(v13 -> { createMilestone.setOnClickListener(v13 -> {
bmListener.onButtonClicked("newMilestone"); bmListener.onButtonClicked("newMilestone");
@ -86,24 +66,13 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
}); });
if (tinyDb.getBoolean("isRepoAdmin")) { if (tinyDb.getBoolean("isRepoAdmin")) {
repoSettings.setOnClickListener(repoSettingsView -> {
bmListener.onButtonClicked("repoSettings");
dismiss();
});
addCollaborator.setOnClickListener(v1 -> { addCollaborator.setOnClickListener(v1 -> {
bmListener.onButtonClicked("addCollaborator"); bmListener.onButtonClicked("addCollaborator");
dismiss(); dismiss();
}); });
} } else {
else {
addCollaborator.setVisibility(View.GONE); addCollaborator.setVisibility(View.GONE);
repoSettingsDivider.setVisibility(View.GONE);
repoSettings.setVisibility(View.GONE);
} }
createRelease.setOnClickListener(v14 -> { createRelease.setOnClickListener(v14 -> {
@ -124,12 +93,6 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
dismiss(); dismiss();
}); });
copyRepoUrl.setOnClickListener(copyUrl -> {
bmListener.onButtonClicked("copyRepoUrl");
dismiss();
});
newFile.setOnClickListener(v17 -> { newFile.setOnClickListener(v17 -> {
bmListener.onButtonClicked("newFile"); bmListener.onButtonClicked("newFile");
@ -199,9 +162,9 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
try { try {
bmListener = (BottomSheetListener) context; bmListener = (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,13 +14,19 @@ import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.IssueActions; import org.mian.gitnex.actions.IssueActions;
import org.mian.gitnex.activities.AddRemoveAssigneesActivity;
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.helpers.PathsHelper;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Objects; import java.util.Objects;
import io.mikael.urlbuilder.UrlBuilder;
/** /**
* Author M M Arif * Author M M Arif
@ -28,8 +34,6 @@ import java.util.Objects;
public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
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) {
@ -78,60 +82,121 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
else { else {
mergePullRequest.setVisibility(View.GONE); mergePullRequest.setVisibility(View.GONE);
} }
mergePullRequest.setOnClickListener(v13 -> { mergePullRequest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(ctx, MergePullRequestActivity.class)); startActivity(new Intent(ctx, MergePullRequestActivity.class));
dismiss(); dismiss();
}
}); });
openFilesDiff.setOnClickListener(v14 -> { openFilesDiff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(ctx, FileDiffActivity.class)); startActivity(new Intent(ctx, FileDiffActivity.class));
dismiss(); dismiss();
}
}); });
editIssue.setOnClickListener(v15 -> { editIssue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(ctx, EditIssueActivity.class)); startActivity(new Intent(ctx, EditIssueActivity.class));
dismiss(); dismiss();
}
}); });
editLabels.setOnClickListener(v16 -> { editLabels.setOnClickListener(new View.OnClickListener() {
bmListener.onButtonClicked("showLabels"); @Override
public void onClick(View v) {
startActivity(new Intent(ctx, AddRemoveLabelsActivity.class));
dismiss(); dismiss();
}
}); });
addRemoveAssignees.setOnClickListener(v17 -> { addRemoveAssignees.setOnClickListener(new View.OnClickListener() {
bmListener.onButtonClicked("showAssignees"); @Override
public void onClick(View v) {
startActivity(new Intent(ctx, AddRemoveAssigneesActivity.class));
dismiss(); dismiss();
}
}); });
shareIssue.setOnClickListener(v1 -> { shareIssue.setOnClickListener(v1 -> {
try {
URI instanceUrl = new URI(tinyDB.getString("instanceUrlWithProtocol"));
String issuePath = PathsHelper.join(instanceUrl.getPath(), tinyDB.getString("repoFullName"), "/issues/", tinyDB.getString("issueNumber"));
String issueUrl = UrlBuilder.fromUri(instanceUrl)
.withPath(issuePath)
.toString();
// share issue
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain"); 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_SUBJECT, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, tinyDB.getString("singleIssueHtmlUrl")); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, issueUrl);
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"))); startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle")));
}
catch(URISyntaxException e) {
Toasty.error(ctx, getString(R.string.genericError));
}
finally {
dismiss(); dismiss();
}
}); });
copyIssueUrl.setOnClickListener(v12 -> { copyIssueUrl.setOnClickListener(v12 -> {
try {
URI instanceUrl = new URI(tinyDB.getString("instanceUrlWithProtocol"));
String issuePath = PathsHelper.join(instanceUrl.getPath(), tinyDB.getString("repoFullName"), "/issues/", tinyDB.getString("issueNumber"));
String issueUrl = UrlBuilder.fromUri(instanceUrl)
.withPath(issuePath)
.toString();
// copy to clipboard // copy to clipboard
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE); ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("issueUrl", tinyDB.getString("singleIssueHtmlUrl")); ClipData clip = ClipData.newPlainText("issueUrl", issueUrl);
assert clipboard != null; assert clipboard != null;
clipboard.setPrimaryClip(clip); clipboard.setPrimaryClip(clip);
Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg)); Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg));
}
catch(URISyntaxException e) {
Toasty.error(ctx, getString(R.string.genericError));
}
finally {
dismiss(); dismiss();
}
}); });
if(tinyDB.getString("issueType").equalsIgnoreCase("Issue")) { if(tinyDB.getString("issueType").equalsIgnoreCase("Issue")) {
@ -175,12 +240,14 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
IssueActions.subscribe(ctx); IssueActions.subscribe(ctx);
dismiss(); dismiss();
}); });
unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> { unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> {
IssueActions.unsubscribe(ctx); IssueActions.unsubscribe(ctx);
dismiss(); dismiss();
}); });
if(new Version(tinyDB.getString("giteaVersion")).less("1.12.0")) { if(new Version(tinyDB.getString("giteaVersion")).less("1.12.0")) {
@ -199,23 +266,4 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
return v; return v;
} }
public interface BottomSheetListener {
void onButtonClicked(String text);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
bmListener = (BottomSheetListener) context;
}
catch(ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement BottomSheetListener");
}
}
} }

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