From 7aff70e3f36beb4be71a83ea582f518723903a85 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Wed, 12 Jul 2023 23:38:13 +0200 Subject: [PATCH 001/163] dependencies updated; building with AWS Corretto 17. --- .github/workflows/android.yml | 31 ++++++++++++++++--- build.gradle | 16 +++++----- gradle.properties | 5 +-- gradle/wrapper/gradle-wrapper.properties | 2 +- mobile/build.gradle | 19 ++++++------ .../github/adapter/BaseArrayAdapter.java | 3 +- .../github/fragment/BaseFragment.java | 8 ++--- .../github/fragment/RepositoryFragment.java | 21 +++---------- .../github/provider/BaseMenuProvider.java | 1 - .../recyclerview/RepositoriesAdapter.java | 1 - .../github/recyclerview/ScrollListener.java | 6 ++-- .../github/retrofit/GithubService.java | 5 ++- .../syslogic/github/room/RepositoriesDao.java | 2 +- 13 files changed, 66 insertions(+), 54 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 515ace8a..87200d22 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -16,12 +16,35 @@ jobs: - name: 🚚 Get latest code uses: actions/checkout@v3 - - name: ☕ Set up JDK 11 + - name: Get latest Corretto URL + id: get-latest-corretto-url + run: >- + echo "::set-output name=URL::$(curl -LIs -o /dev/null -w + %{url_effective} + https://corretto.aws/downloads/latest/amazon-corretto-17-x64-linux-jdk.tar.gz)" + + - uses: actions/cache@v3 + id: corretto-cache + name: Restore Corretto + with: + path: ./amazon-corretto-17-x64-linux-jdk.tar.gz + key: >- + ${{ runner.os }}-corretto-${{ + steps.get-latest-corretto-url.outputs.URL }} + + - name: Download AWS Corretto + if: steps.corretto-cache.outputs.cache-hit != 'true' + run: >- + wget + https://corretto.aws/downloads/latest/amazon-corretto-17-x64-linux-jdk.tar.gz + + - name: ☕ Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' - distribution: 'temurin' - cache: gradle + distribution: jdkfile + java-version: '17' + architecture: x64 + jdkFile: ./amazon-corretto-17-x64-linux-jdk.tar.gz - name: Build with Gradle run: ./gradlew :mobile:bundleDebug diff --git a/build.gradle b/build.gradle index f0fe1d4b..6e39aae9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,15 @@ // root build.gradle buildscript { ext { - agp_version = '7.4.2' - nav_version = '2.5.3' - fragment_version = '1.5.6' - room_version = '2.5.1' + agp_version = '8.0.2' + navigation_version = '2.6.0' + fragment_version = '1.6.0' + room_version = '2.5.2' annotation_version = '1.6.0' - material_version = '1.8.0' + material_version = '1.9.0' flexbox_version = '3.0.0' appcompat_version = '1.6.1' - splash_version = '1.0.0' + splash_version = '1.0.1' recyclerview_version = '1.3.0' preference_version = '1.2.0' cardview_version = '1.0.0' @@ -18,13 +18,13 @@ buildscript { junit_version = '4.13.2' uiautomator_version = '2.2.0' espresso_version = '3.5.1' - kotlin_version = '1.8.10' + kotlin_version = '1.8.20' } } plugins { id 'com.android.application' version "$agp_version" apply false - id 'androidx.navigation.safeargs' version "$nav_version" apply false + id 'androidx.navigation.safeargs' version "$navigation_version" apply false } /** Version Settings, loaded from file `version.properties` */ diff --git a/gradle.properties b/gradle.properties index e617fb6b..e3051b90 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,5 +6,6 @@ org.gradle.configureondemand = true org.gradle.workers.max = 6 org.gradle.parallel = true -android.enableJetifier = false -android.useAndroidX = true +android.useAndroidX=true +android.suppressUnsupportedCompileSdk=34 +android.enableJetifier=false diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2b08fab3..e062e8b1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip diff --git a/mobile/build.gradle b/mobile/build.gradle index 35da57c8..d76c03bc 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -5,23 +5,23 @@ plugins { } android { - - compileSdk 33 + compileSdk 34 + buildToolsVersion '34.0.0' defaultConfig { - applicationId rootProject.ext.get('applicationId') namespace rootProject.ext.get('applicationId') + applicationId rootProject.ext.get('applicationId') versionName rootProject.ext.get('versionName') versionCode rootProject.ext.get('versionCode') manifestPlaceholders = [ accessToken: "" ] - targetSdk 33 + targetSdk 34 minSdk 22 setProperty("archivesBaseName", "github_client_" + versionName) testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testBuildType "debug" multiDexEnabled true compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } javaCompileOptions { annotationProcessorOptions { @@ -41,7 +41,8 @@ android { } buildFeatures { - dataBinding = true + dataBinding true + buildConfig true } signingConfigs { @@ -113,8 +114,8 @@ dependencies { implementation "androidx.cardview:cardview:$cardview_version" // Navigation - androidTestImplementation "androidx.navigation:navigation-testing:$nav_version" - implementation "androidx.navigation:navigation-fragment:$nav_version" + androidTestImplementation "androidx.navigation:navigation-testing:$navigation_version" + implementation "androidx.navigation:navigation-fragment:$navigation_version" // Fragment androidTestImplementation "androidx.fragment:fragment-testing:$fragment_version" diff --git a/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java index 2d17f1e0..2847f3f7 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java @@ -12,7 +12,6 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatTextView; -import io.syslogic.github.R; import io.syslogic.github.model.SpinnerItem; import java.util.ArrayList; @@ -53,7 +52,7 @@ public long getItemId(int position) { @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { if (convertView == null) { - convertView = this.layoutInflater.inflate(R.layout.support_simple_spinner_dropdown_item, parent, false); + convertView = this.layoutInflater.inflate(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, parent, false); } convertView.setTag(this.mItems.get(position)); AppCompatTextView textView = convertView.findViewById(android.R.id.text1); diff --git a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java index c009949a..c619a934 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java @@ -187,8 +187,7 @@ protected void setUser(@NonNull String accessToken, @Nullable final TokenCallbac @Override public void onResponse(@NonNull Call call, @NonNull Response response) { switch (response.code()) { - - case 200: { + case 200 -> { if (response.body() != null) { User item = response.body(); if (mDebug) { @@ -201,10 +200,8 @@ public void onResponse(@NonNull Call call, @NonNull Response respons } setCurrentUser(item); } - break; } - - case 403: { + case 403 -> { if (response.errorBody() != null) { try { String errors = response.errorBody().string(); @@ -220,7 +217,6 @@ public void onResponse(@NonNull Call call, @NonNull Response respons } } } - break; } } } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java index db7d3e45..6449ef8d 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java @@ -209,17 +209,14 @@ private void setRepository() { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { switch (response.code()) { - - case 200: { + case 200 -> { if (response.body() != null) { Repository item = response.body(); mDataBinding.setRepository(item); setBranches(item); } - break; } - - case 403: { + case 403 -> { if (response.errorBody() != null) { try { String errors = response.errorBody().string(); @@ -235,7 +232,6 @@ public void onResponse(@NonNull Call call, @NonNull Response> call, @NonNull Response> response) { switch (response.code()) { - - case 200: { + case 200 -> { if (response.body() != null && getContext() != null) { /* Updating the branches */ @@ -299,16 +294,11 @@ public void onResponse(@NonNull Call> call, @NonNull Response< if (getActivity() != null && defaultIndex > 0) { final int index = defaultIndex; - getDataBinding().toolbarDownload.spinnerBranch.postDelayed(() -> - getDataBinding().toolbarDownload.spinnerBranch.setSelection(index, false), - 100 - ); + getDataBinding().toolbarDownload.spinnerBranch.postDelayed(() -> getDataBinding().toolbarDownload.spinnerBranch.setSelection(index, false), 100); } } - break; } - - case 403: { + case 403 -> { if (response.errorBody() != null) { try { String errors = response.errorBody().string(); @@ -324,7 +314,6 @@ public void onResponse(@NonNull Call> call, @NonNull Response< } } } - break; } } } diff --git a/mobile/src/main/java/io/syslogic/github/provider/BaseMenuProvider.java b/mobile/src/main/java/io/syslogic/github/provider/BaseMenuProvider.java index 9368094c..96e15b8d 100644 --- a/mobile/src/main/java/io/syslogic/github/provider/BaseMenuProvider.java +++ b/mobile/src/main/java/io/syslogic/github/provider/BaseMenuProvider.java @@ -8,7 +8,6 @@ import androidx.annotation.Nullable; import androidx.core.view.MenuProvider; import androidx.navigation.NavController; -import androidx.navigation.Navigation; import androidx.navigation.fragment.NavHostFragment; import java.lang.ref.WeakReference; diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index 01f13846..a4e7126d 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -27,7 +27,6 @@ import androidx.annotation.Nullable; import androidx.cardview.widget.CardView; import androidx.databinding.DataBindingUtil; -import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; import androidx.navigation.NavController; import androidx.navigation.Navigation; diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/ScrollListener.java b/mobile/src/main/java/io/syslogic/github/recyclerview/ScrollListener.java index 11aa6522..b5cec73c 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/ScrollListener.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/ScrollListener.java @@ -25,12 +25,14 @@ public abstract class ScrollListener extends RecyclerView.OnScrollListener { } /** + *

* Callback method to be invoked when the RecyclerView has been scrolled. * This will be called after the scroll has completed. - * + *

+ *

* This callback will also be called if visible item range changes * after a layout calculation. In that case, dx and dy will be 0. - * + *

* {@link Constants#RECYCLERVIEW_SCROLLING_THRESHOLD} defaults to 12 items. * * @param recyclerView The RecyclerView which scrolled. diff --git a/mobile/src/main/java/io/syslogic/github/retrofit/GithubService.java b/mobile/src/main/java/io/syslogic/github/retrofit/GithubService.java index ae47e8e9..eeaa9288 100644 --- a/mobile/src/main/java/io/syslogic/github/retrofit/GithubService.java +++ b/mobile/src/main/java/io/syslogic/github/retrofit/GithubService.java @@ -74,12 +74,15 @@ Call getBranch( ); /** + *

* Obtain the redirect URL to download an archive for a repository. * The :archive_format can be either "tarball" or "zipball". * The :branch must be a valid Git reference. - * + *

+ *

* If you omit :branch, the repository’s default branch (usually master) will be used. * Note: for private repositories, the links are temporary and expire after five minutes. + *

**/ @NonNull @Streaming diff --git a/mobile/src/main/java/io/syslogic/github/room/RepositoriesDao.java b/mobile/src/main/java/io/syslogic/github/room/RepositoriesDao.java index 9d6498e8..4ce59cd9 100644 --- a/mobile/src/main/java/io/syslogic/github/room/RepositoriesDao.java +++ b/mobile/src/main/java/io/syslogic/github/room/RepositoriesDao.java @@ -15,8 +15,8 @@ /** * {@link Repository} {@link Dao} interface - * * Note: {@link androidx.room.Relation} depends on {@link androidx.room.Transaction}. + * * @author Martin Zeitler */ @Dao From bbdea7529b20e6fdc1b75cfc3834b8eecca32b00 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Wed, 12 Jul 2023 23:53:13 +0200 Subject: [PATCH 002/163] dependencies updated; building with AWS Corretto 17. --- .../recyclerview/RepositoriesAdapter.java | 40 +++++++------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index a4e7126d..ef01a4cf 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -138,10 +138,10 @@ public void fetchPage(final int pageNumber) { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { - switch(response.code()) { + switch (response.code()) { // OK - case 200: { + case 200 -> { if (response.body() != null) { Repositories items = response.body(); if (BuildConfig.DEBUG) { @@ -160,10 +160,8 @@ public void onResponse(@NonNull Call call, @NonNull Response { /* "bad credentials" means that the provided access-token is invalid. */ if (response.errorBody() != null) { logError(response.errorBody()); @@ -171,10 +169,8 @@ public void onResponse(@NonNull Call call, @NonNull Response { if (response.errorBody() != null) { logError(response.errorBody()); @@ -184,7 +180,6 @@ public void onResponse(@NonNull Call call, @NonNull Response call, @NonNull Response response) { if (response.code() == 200 && response.body() != null) { RateLimits items = response.body(); - RateLimit limit = null; - switch (resourceName) { - case "graphql": limit = items.getResources().getGraphql(); break; - case "search": limit = items.getResources().getSearch(); break; - case "core": limit = items.getResources().getCore(); break; - } + RateLimit limit = switch (resourceName) { + case "graphql" -> items.getResources().getGraphql(); + case "search" -> items.getResources().getSearch(); + case "core" -> items.getResources().getCore(); + default -> null; + }; /* For testing purposes only: */ if (limit != null && BuildConfig.DEBUG) { @@ -352,21 +344,17 @@ public void onClick(@NonNull View viewHolder) { NavController controller = Navigation.findNavController(layout); switch (orientation) { //noinspection deprecation - case Configuration.ORIENTATION_SQUARE: - case Configuration.ORIENTATION_UNDEFINED: - case Configuration.ORIENTATION_PORTRAIT: { + case Configuration.ORIENTATION_SQUARE, Configuration.ORIENTATION_UNDEFINED, Configuration.ORIENTATION_PORTRAIT -> { Bundle args = new Bundle(); args.putLong(Constants.ARGUMENT_ITEM_ID, item.getId()); controller.navigate(R.id.action_repositoriesFragment_to_repositoryFragment, args); - break; } - case Configuration.ORIENTATION_LANDSCAPE: { + case Configuration.ORIENTATION_LANDSCAPE -> { int layoutId = databinding.layoutRepository.layoutRepository.getId(); RepositoryFragment fragment = RepositoryFragment.newInstance(item.getId()); FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); ft.replace(layoutId, fragment); ft.commit(); - break; } } } From af1f6aefe5f4a8f8f8c6d1134c6e96376bd49fdc Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sat, 5 Aug 2023 12:04:16 +0200 Subject: [PATCH 003/163] ignore updated. --- .idea/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.idea/.gitignore b/.idea/.gitignore index 4d9b6a17..cff883c6 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -6,3 +6,7 @@ /deploymentTargetDropDown.xml /assetWizardSettings.xml /.name +/markdown-navigator.xml +/markdown-navigator-enh.xml +/androidTestResultsUserPreferences.xml +/dynamic.xml From b14b4f3fd1fe41dc236f88e057423cddcc715726 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sat, 5 Aug 2023 22:39:15 +0200 Subject: [PATCH 004/163] header comments updated. --- .../java/io/syslogic/github/fragment/RepositoriesFragment.java | 2 +- .../io/syslogic/github/fragment/RepositorySearchFragment.java | 2 +- .../io/syslogic/github/recyclerview/RepositoriesAdapter.java | 2 +- .../io/syslogic/github/recyclerview/RepositoriesLinearView.java | 2 +- .../syslogic/github/recyclerview/RepositorySearchAdapter.java | 2 +- .../github/recyclerview/RepositorySearchLinearView.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java index b61dbcd3..9549328e 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java @@ -16,7 +16,7 @@ import io.syslogic.github.recyclerview.RepositoriesAdapter; /** - * Workflows {@link BaseFragment} + * Repositories {@link BaseFragment} * * @author Martin Zeitler */ diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index 76abbee7..7331825f 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -32,7 +32,7 @@ import io.syslogic.github.room.QueryStringsDao; /** - * Repositories {@link BaseFragment} + * Repository Search {@link BaseFragment} * * @author Martin Zeitler */ diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index f4c1b812..4d1b5dac 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -46,7 +46,7 @@ import retrofit2.Response; /** - * Workflows {@link RecyclerView.Adapter} + * Repositories {@link RecyclerView.Adapter} * * @author Martin Zeitler */ diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java index 94adb13a..b2daacad 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java @@ -10,7 +10,7 @@ import androidx.recyclerview.widget.RecyclerView; /** - * Workflows {@link RecyclerView} + * Repositories {@link RecyclerView} * * @author Martin Zeitler */ diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java index 31dc74de..dfdc0191 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java @@ -56,7 +56,7 @@ import io.syslogic.github.network.TokenHelper; /** - * Repositories {@link RecyclerView.Adapter} + * Repository Search {@link RecyclerView.Adapter} * * @author Martin Zeitler */ diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchLinearView.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchLinearView.java index 9fe49425..eda4affc 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchLinearView.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchLinearView.java @@ -9,7 +9,7 @@ import androidx.recyclerview.widget.RecyclerView; /** - * Repositories {@link RecyclerView} + * Repository Search {@link RecyclerView} * * @author Martin Zeitler */ From 5d5e1d08706e492950f01883ca322ad81a96c38b Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 00:28:22 +0200 Subject: [PATCH 005/163] retrofit & room code moved into a reusable library module. --- build.gradle | 3 + library/.gitignore | 1 + library/build.gradle | 172 ++++++++++++++++++ library/consumer-rules.pro | 0 .../github/api/ExampleInstrumentedTest.java | 26 +++ library/src/main/AndroidManifest.xml | 4 + .../io/syslogic/github/api/Constants.java | 19 ++ .../io/syslogic/github/api}/GithubClient.java | 23 +-- .../syslogic/github/api}/GithubService.java | 20 +- .../github/api}/adapter/BaseArrayAdapter.java | 10 +- .../github/api}/content/IContentProvider.java | 4 +- .../syslogic/github/api}/model/BaseModel.java | 6 +- .../io/syslogic/github/api}/model/Branch.java | 6 +- .../io/syslogic/github/api}/model/Commit.java | 6 +- .../syslogic/github/api}/model/License.java | 8 +- .../io/syslogic/github/api}/model/Owner.java | 8 +- .../github/api}/model/QueryString.java | 6 +- .../syslogic/github/api}/model/RateLimit.java | 2 +- .../github/api}/model/RateLimits.java | 6 +- .../github/api}/model/Repositories.java | 2 +- .../github/api}/model/Repository.java | 12 +- .../github/api}/model/RepositorySearch.java | 8 +- .../syslogic/github/api}/model/Resources.java | 6 +- .../github/api}/model/SpinnerItem.java | 2 +- .../io/syslogic/github/api}/model/User.java | 6 +- .../syslogic/github/api}/model/Workflow.java | 2 +- .../github/api}/model/WorkflowJob.java | 2 +- .../github/api}/model/WorkflowJobs.java | 2 +- .../github/api}/model/WorkflowStep.java | 2 +- .../github/api}/model/WorkflowsResponse.java | 3 +- .../github/api}/room/Abstraction.java | 10 +- .../github/api}/room/LicensesDao.java | 7 +- .../syslogic/github/api}/room/OwnersDao.java | 6 +- .../github/api}/room/QueryStringsDao.java | 6 +- .../github/api}/room/RepositoriesDao.java | 6 +- .../api/utils}/StringArrayConverter.java | 4 +- .../syslogic/github/api/ExampleUnitTest.java | 17 ++ mobile/build.gradle | 4 +- .../java/io/syslogic/github/Constants.java | 1 + .../activity/AuthenticatorActivity.java | 4 +- .../github/adapter/QueryStringAdapter.java | 11 +- .../github/adapter/SearchOperatorAdapter.java | 1 + .../github/adapter/SortFieldAdapter.java | 1 + .../github/adapter/SortOrderAdapter.java | 1 + .../github/adapter/StringArrayAdapter.java | 5 +- .../github/content/QueryStringProvider.java | 6 +- .../github/content/RepositoryProvider.java | 6 +- .../github/content/RepositorySyncAdapter.java | 16 +- .../github/fragment/BaseFragment.java | 4 +- .../github/fragment/HomeScreenFragment.java | 2 +- .../github/fragment/ProfileFragment.java | 2 +- .../github/fragment/QueryStringFragment.java | 6 +- .../github/fragment/RepositoryFragment.java | 8 +- .../fragment/RepositorySearchFragment.java | 10 +- .../github/fragment/WorkflowFragment.java | 2 +- .../io/syslogic/github/model/PagerState.java | 2 + .../github/network/TokenCallback.java | 2 +- .../syslogic/github/network/TokenHelper.java | 4 +- .../recyclerview/QueryStringsAdapter.java | 4 +- .../recyclerview/RepositoriesAdapter.java | 8 +- .../recyclerview/RepositorySearchAdapter.java | 13 +- .../fragment_repository_search.xml | 4 +- .../main/res/layout/cardview_query_string.xml | 2 +- .../res/layout/cardview_repository_search.xml | 2 +- .../src/main/res/layout/cardview_workflow.xml | 2 +- .../main/res/layout/fragment_home_screen.xml | 2 +- .../src/main/res/layout/fragment_profile.xml | 4 +- .../main/res/layout/fragment_query_string.xml | 2 +- .../main/res/layout/fragment_repository.xml | 4 +- .../res/layout/fragment_repository_search.xml | 4 +- .../src/main/res/layout/fragment_workflow.xml | 2 +- .../src/main/res/layout/toolbar_download.xml | 2 +- .../src/main/res/layout/toolbar_profile.xml | 2 +- .../main/res/layout/toolbar_repository.xml | 2 +- .../src/main/res/layout/toolbar_workflow.xml | 2 +- settings.gradle | 7 +- 76 files changed, 425 insertions(+), 174 deletions(-) create mode 100644 library/.gitignore create mode 100644 library/build.gradle create mode 100644 library/consumer-rules.pro create mode 100644 library/src/androidTest/java/io/syslogic/github/api/ExampleInstrumentedTest.java create mode 100644 library/src/main/AndroidManifest.xml create mode 100644 library/src/main/java/io/syslogic/github/api/Constants.java rename {mobile/src/main/java/io/syslogic/github/retrofit => library/src/main/java/io/syslogic/github/api}/GithubClient.java (91%) rename {mobile/src/main/java/io/syslogic/github/retrofit => library/src/main/java/io/syslogic/github/api}/GithubService.java (94%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/adapter/BaseArrayAdapter.java (87%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/content/IContentProvider.java (80%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/BaseModel.java (87%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/Branch.java (94%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/Commit.java (93%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/License.java (95%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/Owner.java (97%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/QueryString.java (97%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/RateLimit.java (95%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/RateLimits.java (94%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/Repositories.java (96%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/Repository.java (97%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/RepositorySearch.java (96%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/Resources.java (95%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/SpinnerItem.java (96%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/User.java (99%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/Workflow.java (98%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/WorkflowJob.java (98%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/WorkflowJobs.java (96%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/WorkflowStep.java (97%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/model/WorkflowsResponse.java (91%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/room/Abstraction.java (89%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/room/LicensesDao.java (85%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/room/OwnersDao.java (87%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/room/QueryStringsDao.java (88%) rename {mobile/src/main/java/io/syslogic/github => library/src/main/java/io/syslogic/github/api}/room/RepositoriesDao.java (87%) rename {mobile/src/main/java/io/syslogic/github/room => library/src/main/java/io/syslogic/github/api/utils}/StringArrayConverter.java (82%) create mode 100644 library/src/test/java/io/syslogic/github/api/ExampleUnitTest.java diff --git a/build.gradle b/build.gradle index e7c54e70..0aa1369d 100644 --- a/build.gradle +++ b/build.gradle @@ -27,11 +27,14 @@ buildscript { test_rules_version = '1.5.0' uiautomator_version = '2.2.0' espresso_version = '3.5.1' + + version_name = '1.1.5' } } plugins { id 'com.android.application' version "$agp_version" apply false + id 'com.android.library' version "$agp_version" apply false id 'androidx.navigation.safeargs' version "$nav_version" apply false } diff --git a/library/.gitignore b/library/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/library/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle new file mode 100644 index 00000000..b7783923 --- /dev/null +++ b/library/build.gradle @@ -0,0 +1,172 @@ +plugins { + id 'com.android.library' + id 'maven-publish' +} + +android { + namespace 'io.syslogic.github.api' + compileSdk 34 + + defaultConfig { + minSdk 22 + targetSdk 34 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + buildFeatures { + buildConfig true + dataBinding true + } + + buildTypes { + debug { + // it breaks the data-binding, eg. when running ./gradlew :library:publishToMavenLocal + testCoverageEnabled false + minifyEnabled false + } + release { + minifyEnabled false + } + } + + lint { + lintConfig rootProject.file('lint.xml') + checkAllWarnings true + warningsAsErrors true + abortOnError false + showAll false + } + + publishing { + singleVariant('release') { + withSourcesJar() + withJavadocJar() + } + } +} + +dependencies { + + // Annotations + implementation "androidx.annotation:annotation:$annotation_version" + + // Material Design Components + implementation "com.google.android.material:material:$material_version" + + // App Compat + implementation "androidx.appcompat:appcompat:$appcompat_version" + + // Data-Binding Runtime + implementation "androidx.databinding:databinding-runtime:$agp_version" + + // Room Runtime + annotationProcessor "androidx.room:room-compiler:$room_version" + testImplementation "androidx.room:room-testing:$room_version" + implementation "androidx.room:room-runtime:$room_version" + + // Retrofit2 + implementation "com.google.code.gson:gson:$gson_version" + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation ("com.squareup.retrofit2:converter-gson:$retrofit_version") { + exclude group: "com.google.code.gson", module: "gson" + } + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' +} + +tasks.register('javadoc', Javadoc) { + + title = "GitHub API Client ${android.defaultConfig.versionName}" + source = android.sourceSets.main.java.srcDirs + destinationDir = file("${project.buildDir}/outputs/javadoc/") + configurations.implementation.setCanBeResolved(true) + classpath = files(new File("${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")) + classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + classpath += fileTree(dir: "$buildDir/tmp/aarsToJars/") + classpath += configurations.implementation + exclude "**/BuildConfig.java", "**/R.java" + failOnError false + + // options.verbose() + // javadoc: warning - The code being documented uses modules but the packages + // defined in https://developer.android.com/reference/ are in the unnamed module. + options.links "https://docs.oracle.com/en/java/javase/17/docs/api/" + options.linksOffline "https://developer.android.com/reference", "${android.sdkDirectory}/docs/reference" + options.linkSource true + options.author true + + doFirst { + + // extract AAR files + configurations.implementation.filter { it.name.endsWith('.aar') }.each { aar -> + copy { + from zipTree(aar) + include "**/classes.jar" + into "$buildDir/tmp/aarsToJars/${aar.name.replace('.aar', '')}/" + } + } + + // provide JAR, which contains the generated data-binding classes + def aar_main = new File("$buildDir/intermediates/aar_main_jar") + if (aar_main.exists()) { + copy { + from aar_main + include "**/classes.jar" + into "$buildDir/tmp/aarsToJars/aar_main_jar/" + } + } + } +} + +javadoc.onlyIf { + new File("$buildDir/intermediates/aar_main_jar").exists() +} + +tasks.register('javadocJar', Jar) { + dependsOn javadoc + archiveClassifier.set('javadoc') + from javadoc.destinationDir +} + +tasks.register('sourcesJar', Jar) { + from android.sourceSets.main.java.srcDirs + archiveClassifier.set('sources') +} + +artifacts { + archives javadocJar + archives sourcesJar +} + +group = 'io.syslogic' +version = version_name + +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + groupId = group + artifactId = 'github-retrofit2-client' + from components.getByName('release') + version = version_name + pom { + name = 'GitHub API Client' + description = 'A simple client library for Android' + url = "https://github.com/syslogic/${artifactId}" + scm { + connection = "scm:git:git://github.com/syslogic/${artifactId}.git" + developerConnection = "scm:git:ssh://github.com/syslogic/${artifactId}.git" + url = "https://github.com/syslogic/${artifactId}/" + } + } + } + } + } +} diff --git a/library/consumer-rules.pro b/library/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/library/src/androidTest/java/io/syslogic/github/api/ExampleInstrumentedTest.java b/library/src/androidTest/java/io/syslogic/github/api/ExampleInstrumentedTest.java new file mode 100644 index 00000000..26738af0 --- /dev/null +++ b/library/src/androidTest/java/io/syslogic/github/api/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package io.syslogic.github.api; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("io.syslogic.github.api.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a5918e68 --- /dev/null +++ b/library/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/library/src/main/java/io/syslogic/github/api/Constants.java b/library/src/main/java/io/syslogic/github/api/Constants.java new file mode 100644 index 00000000..bf567083 --- /dev/null +++ b/library/src/main/java/io/syslogic/github/api/Constants.java @@ -0,0 +1,19 @@ +package io.syslogic.github.api; + +import androidx.annotation.NonNull; + +/** + * Common Constants + * + * @author Martin Zeitler + */ +public final class Constants { + @NonNull public static final String GITHUB_API_BASE_URL = "https://api.github.com/"; + @NonNull public static final String GITHUB_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + + /** Table Names */ + @NonNull public static final String TABLE_QUERY_STRINGS = "query_strings"; + @NonNull public static final String TABLE_REPOSITORIES = "repositories"; + @NonNull public static final String TABLE_LICENSES = "licenses"; + @NonNull public static final String TABLE_OWNERS = "owners"; +} diff --git a/mobile/src/main/java/io/syslogic/github/retrofit/GithubClient.java b/library/src/main/java/io/syslogic/github/api/GithubClient.java similarity index 91% rename from mobile/src/main/java/io/syslogic/github/retrofit/GithubClient.java rename to library/src/main/java/io/syslogic/github/api/GithubClient.java index 8b8a543f..b68b333d 100644 --- a/mobile/src/main/java/io/syslogic/github/retrofit/GithubClient.java +++ b/library/src/main/java/io/syslogic/github/api/GithubClient.java @@ -1,24 +1,21 @@ -package io.syslogic.github.retrofit; +package io.syslogic.github.api; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.util.ArrayList; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import io.syslogic.github.Constants; -import io.syslogic.github.model.Branch; -import io.syslogic.github.model.RateLimits; -import io.syslogic.github.model.RepositorySearch; -import io.syslogic.github.model.Repository; -import io.syslogic.github.model.User; -import io.syslogic.github.model.WorkflowsResponse; - +import io.syslogic.github.api.model.Branch; +import io.syslogic.github.api.model.RateLimits; +import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.model.RepositorySearch; +import io.syslogic.github.api.model.User; +import io.syslogic.github.api.model.WorkflowsResponse; import okhttp3.OkHttpClient; import okhttp3.ResponseBody; - import retrofit2.Call; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; diff --git a/mobile/src/main/java/io/syslogic/github/retrofit/GithubService.java b/library/src/main/java/io/syslogic/github/api/GithubService.java similarity index 94% rename from mobile/src/main/java/io/syslogic/github/retrofit/GithubService.java rename to library/src/main/java/io/syslogic/github/api/GithubService.java index b895a7f3..c3485b3f 100644 --- a/mobile/src/main/java/io/syslogic/github/retrofit/GithubService.java +++ b/library/src/main/java/io/syslogic/github/api/GithubService.java @@ -1,20 +1,18 @@ -package io.syslogic.github.retrofit; - -import java.util.ArrayList; +package io.syslogic.github.api; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import io.syslogic.github.model.Branch; -import io.syslogic.github.model.RateLimits; -import io.syslogic.github.model.RepositorySearch; -import io.syslogic.github.model.Repository; -import io.syslogic.github.model.User; -import io.syslogic.github.model.WorkflowJobs; -import io.syslogic.github.model.WorkflowsResponse; +import java.util.ArrayList; +import io.syslogic.github.api.model.Branch; +import io.syslogic.github.api.model.RateLimits; +import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.model.RepositorySearch; +import io.syslogic.github.api.model.User; +import io.syslogic.github.api.model.WorkflowJobs; +import io.syslogic.github.api.model.WorkflowsResponse; import okhttp3.ResponseBody; - import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.HEAD; diff --git a/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java b/library/src/main/java/io/syslogic/github/api/adapter/BaseArrayAdapter.java similarity index 87% rename from mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java rename to library/src/main/java/io/syslogic/github/api/adapter/BaseArrayAdapter.java index fcbf9ef9..1f4e5118 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java +++ b/library/src/main/java/io/syslogic/github/api/adapter/BaseArrayAdapter.java @@ -1,4 +1,4 @@ -package io.syslogic.github.adapter; +package io.syslogic.github.api.adapter; import android.content.Context; import android.content.res.Resources; @@ -12,7 +12,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatTextView; -import io.syslogic.github.model.SpinnerItem; +import io.syslogic.github.api.model.SpinnerItem; import java.util.ArrayList; import java.util.List; @@ -28,7 +28,7 @@ abstract public class BaseArrayAdapter extends BaseAdapter { @NonNull protected ArrayList mItems = new ArrayList<>(); - BaseArrayAdapter(@NonNull Context context) { + protected BaseArrayAdapter(@NonNull Context context) { this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @@ -61,7 +61,7 @@ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup return convertView; } - void setItems(@NonNull Context context, @NonNull @ArrayRes Integer arrayKeys, @NonNull @ArrayRes Integer arrayValues) { + protected void setItems(@NonNull Context context, @NonNull @ArrayRes Integer arrayKeys, @NonNull @ArrayRes Integer arrayValues) { this.clearItems(); Resources res = context.getResources(); String[] keys = res.getStringArray(arrayKeys); @@ -77,7 +77,7 @@ void setItems(List items) { this.mItems.addAll(items); } - void clearItems() { + protected void clearItems() { this.mItems.clear(); } } diff --git a/mobile/src/main/java/io/syslogic/github/content/IContentProvider.java b/library/src/main/java/io/syslogic/github/api/content/IContentProvider.java similarity index 80% rename from mobile/src/main/java/io/syslogic/github/content/IContentProvider.java rename to library/src/main/java/io/syslogic/github/api/content/IContentProvider.java index 7e1a018b..98ef53a6 100644 --- a/mobile/src/main/java/io/syslogic/github/content/IContentProvider.java +++ b/library/src/main/java/io/syslogic/github/api/content/IContentProvider.java @@ -1,11 +1,11 @@ -package io.syslogic.github.content; +package io.syslogic.github.api.content; import android.content.ContentProvider; import android.content.ContentValues; import androidx.annotation.NonNull; -import io.syslogic.github.model.BaseModel; +import io.syslogic.github.api.model.BaseModel; /** * Model Interface for {@link ContentProvider} items. diff --git a/mobile/src/main/java/io/syslogic/github/model/BaseModel.java b/library/src/main/java/io/syslogic/github/api/model/BaseModel.java similarity index 87% rename from mobile/src/main/java/io/syslogic/github/model/BaseModel.java rename to library/src/main/java/io/syslogic/github/api/model/BaseModel.java index 88e0890d..7343a631 100644 --- a/mobile/src/main/java/io/syslogic/github/model/BaseModel.java +++ b/library/src/main/java/io/syslogic/github/api/model/BaseModel.java @@ -1,9 +1,9 @@ -package io.syslogic.github.model; - -import java.io.Serializable; +package io.syslogic.github.api.model; import androidx.databinding.BaseObservable; +import java.io.Serializable; + /** * Base Model * diff --git a/mobile/src/main/java/io/syslogic/github/model/Branch.java b/library/src/main/java/io/syslogic/github/api/model/Branch.java similarity index 94% rename from mobile/src/main/java/io/syslogic/github/model/Branch.java rename to library/src/main/java/io/syslogic/github/api/model/Branch.java index aad82c32..5710d370 100644 --- a/mobile/src/main/java/io/syslogic/github/model/Branch.java +++ b/library/src/main/java/io/syslogic/github/api/model/Branch.java @@ -1,9 +1,9 @@ -package io.syslogic.github.model; - -import com.google.gson.annotations.SerializedName; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; +import com.google.gson.annotations.SerializedName; + /** * Model: Branch * diff --git a/mobile/src/main/java/io/syslogic/github/model/Commit.java b/library/src/main/java/io/syslogic/github/api/model/Commit.java similarity index 93% rename from mobile/src/main/java/io/syslogic/github/model/Commit.java rename to library/src/main/java/io/syslogic/github/api/model/Commit.java index 87660c64..cf46735a 100644 --- a/mobile/src/main/java/io/syslogic/github/model/Commit.java +++ b/library/src/main/java/io/syslogic/github/api/model/Commit.java @@ -1,9 +1,9 @@ -package io.syslogic.github.model; - -import com.google.gson.annotations.SerializedName; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; +import com.google.gson.annotations.SerializedName; + /** * Model: Commit * diff --git a/mobile/src/main/java/io/syslogic/github/model/License.java b/library/src/main/java/io/syslogic/github/api/model/License.java similarity index 95% rename from mobile/src/main/java/io/syslogic/github/model/License.java rename to library/src/main/java/io/syslogic/github/api/model/License.java index 98df5fb2..3870c15d 100644 --- a/mobile/src/main/java/io/syslogic/github/model/License.java +++ b/library/src/main/java/io/syslogic/github/api/model/License.java @@ -1,13 +1,13 @@ -package io.syslogic.github.model; - -import com.google.gson.annotations.SerializedName; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.PrimaryKey; -import io.syslogic.github.Constants; +import com.google.gson.annotations.SerializedName; + +import io.syslogic.github.api.Constants; /** * Model: License diff --git a/mobile/src/main/java/io/syslogic/github/model/Owner.java b/library/src/main/java/io/syslogic/github/api/model/Owner.java similarity index 97% rename from mobile/src/main/java/io/syslogic/github/model/Owner.java rename to library/src/main/java/io/syslogic/github/api/model/Owner.java index e8ec62a9..c34a1a47 100644 --- a/mobile/src/main/java/io/syslogic/github/model/Owner.java +++ b/library/src/main/java/io/syslogic/github/api/model/Owner.java @@ -1,12 +1,12 @@ -package io.syslogic.github.model; - -import com.google.gson.annotations.SerializedName; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; import androidx.room.Entity; import androidx.room.PrimaryKey; -import io.syslogic.github.Constants; +import com.google.gson.annotations.SerializedName; + +import io.syslogic.github.api.Constants; /** * Model: Owner diff --git a/mobile/src/main/java/io/syslogic/github/model/QueryString.java b/library/src/main/java/io/syslogic/github/api/model/QueryString.java similarity index 97% rename from mobile/src/main/java/io/syslogic/github/model/QueryString.java rename to library/src/main/java/io/syslogic/github/api/model/QueryString.java index 0b32ac16..1f64b56a 100644 --- a/mobile/src/main/java/io/syslogic/github/model/QueryString.java +++ b/library/src/main/java/io/syslogic/github/api/model/QueryString.java @@ -1,4 +1,4 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import android.content.ContentValues; @@ -15,8 +15,8 @@ import java.util.Date; import java.util.Locale; -import io.syslogic.github.Constants; -import io.syslogic.github.content.IContentProvider; +import io.syslogic.github.api.Constants; +import io.syslogic.github.api.content.IContentProvider; /** * Model: Query-String diff --git a/mobile/src/main/java/io/syslogic/github/model/RateLimit.java b/library/src/main/java/io/syslogic/github/api/model/RateLimit.java similarity index 95% rename from mobile/src/main/java/io/syslogic/github/model/RateLimit.java rename to library/src/main/java/io/syslogic/github/api/model/RateLimit.java index 6447d9b7..fcc2e903 100644 --- a/mobile/src/main/java/io/syslogic/github/model/RateLimit.java +++ b/library/src/main/java/io/syslogic/github/api/model/RateLimit.java @@ -1,4 +1,4 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import com.google.gson.annotations.SerializedName; diff --git a/mobile/src/main/java/io/syslogic/github/model/RateLimits.java b/library/src/main/java/io/syslogic/github/api/model/RateLimits.java similarity index 94% rename from mobile/src/main/java/io/syslogic/github/model/RateLimits.java rename to library/src/main/java/io/syslogic/github/api/model/RateLimits.java index be224878..83fd58e9 100644 --- a/mobile/src/main/java/io/syslogic/github/model/RateLimits.java +++ b/library/src/main/java/io/syslogic/github/api/model/RateLimits.java @@ -1,9 +1,9 @@ -package io.syslogic.github.model; - -import com.google.gson.annotations.SerializedName; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; +import com.google.gson.annotations.SerializedName; + /** * Model: Rate Limits * diff --git a/mobile/src/main/java/io/syslogic/github/model/Repositories.java b/library/src/main/java/io/syslogic/github/api/model/Repositories.java similarity index 96% rename from mobile/src/main/java/io/syslogic/github/model/Repositories.java rename to library/src/main/java/io/syslogic/github/api/model/Repositories.java index a813575a..c66cbd74 100644 --- a/mobile/src/main/java/io/syslogic/github/model/Repositories.java +++ b/library/src/main/java/io/syslogic/github/api/model/Repositories.java @@ -1,4 +1,4 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; import androidx.databinding.Bindable; diff --git a/mobile/src/main/java/io/syslogic/github/model/Repository.java b/library/src/main/java/io/syslogic/github/api/model/Repository.java similarity index 97% rename from mobile/src/main/java/io/syslogic/github/model/Repository.java rename to library/src/main/java/io/syslogic/github/api/model/Repository.java index a1e99b92..8128c0db 100644 --- a/mobile/src/main/java/io/syslogic/github/model/Repository.java +++ b/library/src/main/java/io/syslogic/github/api/model/Repository.java @@ -1,9 +1,7 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import android.content.ContentValues; -import com.google.gson.annotations.SerializedName; - import androidx.annotation.NonNull; import androidx.databinding.Bindable; import androidx.room.ColumnInfo; @@ -13,9 +11,11 @@ import androidx.room.RoomWarnings; import androidx.room.TypeConverters; -import io.syslogic.github.Constants; -import io.syslogic.github.content.IContentProvider; -import io.syslogic.github.room.StringArrayConverter; +import com.google.gson.annotations.SerializedName; + +import io.syslogic.github.api.Constants; +import io.syslogic.github.api.content.IContentProvider; +import io.syslogic.github.api.utils.StringArrayConverter; /** * Model: Repository diff --git a/mobile/src/main/java/io/syslogic/github/model/RepositorySearch.java b/library/src/main/java/io/syslogic/github/api/model/RepositorySearch.java similarity index 96% rename from mobile/src/main/java/io/syslogic/github/model/RepositorySearch.java rename to library/src/main/java/io/syslogic/github/api/model/RepositorySearch.java index eb9ebd3a..cbe1e2bc 100644 --- a/mobile/src/main/java/io/syslogic/github/model/RepositorySearch.java +++ b/library/src/main/java/io/syslogic/github/api/model/RepositorySearch.java @@ -1,12 +1,12 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; + +import androidx.annotation.NonNull; +import androidx.databinding.Bindable; import com.google.gson.annotations.SerializedName; import java.util.ArrayList; -import androidx.annotation.NonNull; -import androidx.databinding.Bindable; - /** * Model: Repository Search * diff --git a/mobile/src/main/java/io/syslogic/github/model/Resources.java b/library/src/main/java/io/syslogic/github/api/model/Resources.java similarity index 95% rename from mobile/src/main/java/io/syslogic/github/model/Resources.java rename to library/src/main/java/io/syslogic/github/api/model/Resources.java index acda8df8..c0752af1 100644 --- a/mobile/src/main/java/io/syslogic/github/model/Resources.java +++ b/library/src/main/java/io/syslogic/github/api/model/Resources.java @@ -1,9 +1,9 @@ -package io.syslogic.github.model; - -import com.google.gson.annotations.SerializedName; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; +import com.google.gson.annotations.SerializedName; + /** * Model: Resources * diff --git a/mobile/src/main/java/io/syslogic/github/model/SpinnerItem.java b/library/src/main/java/io/syslogic/github/api/model/SpinnerItem.java similarity index 96% rename from mobile/src/main/java/io/syslogic/github/model/SpinnerItem.java rename to library/src/main/java/io/syslogic/github/api/model/SpinnerItem.java index f3106dbf..b93e4392 100644 --- a/mobile/src/main/java/io/syslogic/github/model/SpinnerItem.java +++ b/library/src/main/java/io/syslogic/github/api/model/SpinnerItem.java @@ -1,4 +1,4 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; import androidx.room.Ignore; diff --git a/mobile/src/main/java/io/syslogic/github/model/User.java b/library/src/main/java/io/syslogic/github/api/model/User.java similarity index 99% rename from mobile/src/main/java/io/syslogic/github/model/User.java rename to library/src/main/java/io/syslogic/github/api/model/User.java index 1071ebf5..f5eecbde 100644 --- a/mobile/src/main/java/io/syslogic/github/model/User.java +++ b/library/src/main/java/io/syslogic/github/api/model/User.java @@ -1,11 +1,11 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; + +import androidx.annotation.NonNull; import com.google.gson.annotations.SerializedName; import java.util.Date; -import androidx.annotation.NonNull; - /** * Model: User * diff --git a/mobile/src/main/java/io/syslogic/github/model/Workflow.java b/library/src/main/java/io/syslogic/github/api/model/Workflow.java similarity index 98% rename from mobile/src/main/java/io/syslogic/github/model/Workflow.java rename to library/src/main/java/io/syslogic/github/api/model/Workflow.java index 7f7a4757..108c2937 100644 --- a/mobile/src/main/java/io/syslogic/github/model/Workflow.java +++ b/library/src/main/java/io/syslogic/github/api/model/Workflow.java @@ -1,4 +1,4 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; diff --git a/mobile/src/main/java/io/syslogic/github/model/WorkflowJob.java b/library/src/main/java/io/syslogic/github/api/model/WorkflowJob.java similarity index 98% rename from mobile/src/main/java/io/syslogic/github/model/WorkflowJob.java rename to library/src/main/java/io/syslogic/github/api/model/WorkflowJob.java index 484b46f5..b2671737 100644 --- a/mobile/src/main/java/io/syslogic/github/model/WorkflowJob.java +++ b/library/src/main/java/io/syslogic/github/api/model/WorkflowJob.java @@ -1,4 +1,4 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; diff --git a/mobile/src/main/java/io/syslogic/github/model/WorkflowJobs.java b/library/src/main/java/io/syslogic/github/api/model/WorkflowJobs.java similarity index 96% rename from mobile/src/main/java/io/syslogic/github/model/WorkflowJobs.java rename to library/src/main/java/io/syslogic/github/api/model/WorkflowJobs.java index 1691ae24..a4e50527 100644 --- a/mobile/src/main/java/io/syslogic/github/model/WorkflowJobs.java +++ b/library/src/main/java/io/syslogic/github/api/model/WorkflowJobs.java @@ -1,4 +1,4 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; diff --git a/mobile/src/main/java/io/syslogic/github/model/WorkflowStep.java b/library/src/main/java/io/syslogic/github/api/model/WorkflowStep.java similarity index 97% rename from mobile/src/main/java/io/syslogic/github/model/WorkflowStep.java rename to library/src/main/java/io/syslogic/github/api/model/WorkflowStep.java index b78643fa..f933e833 100644 --- a/mobile/src/main/java/io/syslogic/github/model/WorkflowStep.java +++ b/library/src/main/java/io/syslogic/github/api/model/WorkflowStep.java @@ -1,4 +1,4 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; diff --git a/mobile/src/main/java/io/syslogic/github/model/WorkflowsResponse.java b/library/src/main/java/io/syslogic/github/api/model/WorkflowsResponse.java similarity index 91% rename from mobile/src/main/java/io/syslogic/github/model/WorkflowsResponse.java rename to library/src/main/java/io/syslogic/github/api/model/WorkflowsResponse.java index 76ae9a8a..dae628cf 100644 --- a/mobile/src/main/java/io/syslogic/github/model/WorkflowsResponse.java +++ b/library/src/main/java/io/syslogic/github/api/model/WorkflowsResponse.java @@ -1,8 +1,7 @@ -package io.syslogic.github.model; +package io.syslogic.github.api.model; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.databinding.Bindable; import com.google.gson.annotations.SerializedName; diff --git a/mobile/src/main/java/io/syslogic/github/room/Abstraction.java b/library/src/main/java/io/syslogic/github/api/room/Abstraction.java similarity index 89% rename from mobile/src/main/java/io/syslogic/github/room/Abstraction.java rename to library/src/main/java/io/syslogic/github/api/room/Abstraction.java index a79b9603..394ed0f5 100644 --- a/mobile/src/main/java/io/syslogic/github/room/Abstraction.java +++ b/library/src/main/java/io/syslogic/github/api/room/Abstraction.java @@ -1,4 +1,4 @@ -package io.syslogic.github.room; +package io.syslogic.github.api.room; import android.content.Context; @@ -12,10 +12,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import io.syslogic.github.model.License; -import io.syslogic.github.model.Owner; -import io.syslogic.github.model.QueryString; -import io.syslogic.github.model.Repository; +import io.syslogic.github.api.model.License; +import io.syslogic.github.api.model.Owner; +import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.model.Repository; /** * {@link RoomDatabase} Abstraction diff --git a/mobile/src/main/java/io/syslogic/github/room/LicensesDao.java b/library/src/main/java/io/syslogic/github/api/room/LicensesDao.java similarity index 85% rename from mobile/src/main/java/io/syslogic/github/room/LicensesDao.java rename to library/src/main/java/io/syslogic/github/api/room/LicensesDao.java index 8ce7833e..d0cba116 100644 --- a/mobile/src/main/java/io/syslogic/github/room/LicensesDao.java +++ b/library/src/main/java/io/syslogic/github/api/room/LicensesDao.java @@ -1,8 +1,7 @@ -package io.syslogic.github.room; +package io.syslogic.github.api.room; import android.database.Cursor; -import androidx.annotation.NonNull; import androidx.room.Dao; import androidx.room.Delete; import androidx.room.Insert; @@ -11,8 +10,8 @@ import java.util.List; -import io.syslogic.github.Constants; -import io.syslogic.github.model.License; +import io.syslogic.github.api.Constants; +import io.syslogic.github.api.model.License; /** * {@link License} {@link Dao} interface diff --git a/mobile/src/main/java/io/syslogic/github/room/OwnersDao.java b/library/src/main/java/io/syslogic/github/api/room/OwnersDao.java similarity index 87% rename from mobile/src/main/java/io/syslogic/github/room/OwnersDao.java rename to library/src/main/java/io/syslogic/github/api/room/OwnersDao.java index d70cbcd0..2371b81b 100644 --- a/mobile/src/main/java/io/syslogic/github/room/OwnersDao.java +++ b/library/src/main/java/io/syslogic/github/api/room/OwnersDao.java @@ -1,4 +1,4 @@ -package io.syslogic.github.room; +package io.syslogic.github.api.room; import android.database.Cursor; @@ -10,8 +10,8 @@ import java.util.List; -import io.syslogic.github.Constants; -import io.syslogic.github.model.Owner; +import io.syslogic.github.api.Constants; +import io.syslogic.github.api.model.Owner; /** * {@link Owner} {@link Dao} interface diff --git a/mobile/src/main/java/io/syslogic/github/room/QueryStringsDao.java b/library/src/main/java/io/syslogic/github/api/room/QueryStringsDao.java similarity index 88% rename from mobile/src/main/java/io/syslogic/github/room/QueryStringsDao.java rename to library/src/main/java/io/syslogic/github/api/room/QueryStringsDao.java index 3b7d6193..d4ff1b7b 100644 --- a/mobile/src/main/java/io/syslogic/github/room/QueryStringsDao.java +++ b/library/src/main/java/io/syslogic/github/api/room/QueryStringsDao.java @@ -1,4 +1,4 @@ -package io.syslogic.github.room; +package io.syslogic.github.api.room; import android.database.Cursor; @@ -10,8 +10,8 @@ import java.util.List; -import io.syslogic.github.Constants; -import io.syslogic.github.model.QueryString; +import io.syslogic.github.api.Constants; +import io.syslogic.github.api.model.QueryString; /** * {@link QueryString} {@link Dao} interface diff --git a/mobile/src/main/java/io/syslogic/github/room/RepositoriesDao.java b/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java similarity index 87% rename from mobile/src/main/java/io/syslogic/github/room/RepositoriesDao.java rename to library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java index 2721e83f..2c047af1 100644 --- a/mobile/src/main/java/io/syslogic/github/room/RepositoriesDao.java +++ b/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java @@ -1,4 +1,4 @@ -package io.syslogic.github.room; +package io.syslogic.github.api.room; import android.database.Cursor; @@ -10,8 +10,8 @@ import java.util.List; -import io.syslogic.github.Constants; -import io.syslogic.github.model.Repository; +import io.syslogic.github.api.Constants; +import io.syslogic.github.api.model.Repository; /** * {@link Repository} {@link Dao} interface diff --git a/mobile/src/main/java/io/syslogic/github/room/StringArrayConverter.java b/library/src/main/java/io/syslogic/github/api/utils/StringArrayConverter.java similarity index 82% rename from mobile/src/main/java/io/syslogic/github/room/StringArrayConverter.java rename to library/src/main/java/io/syslogic/github/api/utils/StringArrayConverter.java index b2de30b3..29330044 100644 --- a/mobile/src/main/java/io/syslogic/github/room/StringArrayConverter.java +++ b/library/src/main/java/io/syslogic/github/api/utils/StringArrayConverter.java @@ -1,11 +1,11 @@ -package io.syslogic.github.room; +package io.syslogic.github.api.utils; import androidx.room.TypeConverter; import com.google.gson.Gson; /** - * String[] {@link TypeConverter} + * String[] {@link TypeConverter} for Room. * * @author Martin Zeitler */ diff --git a/library/src/test/java/io/syslogic/github/api/ExampleUnitTest.java b/library/src/test/java/io/syslogic/github/api/ExampleUnitTest.java new file mode 100644 index 00000000..a47c19b1 --- /dev/null +++ b/library/src/test/java/io/syslogic/github/api/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package io.syslogic.github.api; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/mobile/build.gradle b/mobile/build.gradle index 560975bb..d89abbcd 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -97,10 +97,12 @@ android { dependencies { + api project(path: ':library') + // Annotations implementation "androidx.annotation:annotation:$annotation_version" - // Material Design + // Material Design Components implementation "com.google.android.material:material:$material_version" // Flexbox Layout diff --git a/mobile/src/main/java/io/syslogic/github/Constants.java b/mobile/src/main/java/io/syslogic/github/Constants.java index 023a5cde..02e3595e 100644 --- a/mobile/src/main/java/io/syslogic/github/Constants.java +++ b/mobile/src/main/java/io/syslogic/github/Constants.java @@ -41,5 +41,6 @@ public final class Constants { @NonNull public static final String TABLE_REPOSITORIES = "repositories"; @NonNull public static final String TABLE_LICENSES = "licenses"; @NonNull public static final String TABLE_OWNERS = "owners"; + // TODO @NonNull public static final String TABLE_TOPICS = "topics"; } diff --git a/mobile/src/main/java/io/syslogic/github/activity/AuthenticatorActivity.java b/mobile/src/main/java/io/syslogic/github/activity/AuthenticatorActivity.java index b328b441..720df3b0 100644 --- a/mobile/src/main/java/io/syslogic/github/activity/AuthenticatorActivity.java +++ b/mobile/src/main/java/io/syslogic/github/activity/AuthenticatorActivity.java @@ -21,9 +21,9 @@ import io.syslogic.github.BuildConfig; import io.syslogic.github.R; import io.syslogic.github.databinding.FragmentAccessTokenBinding; -import io.syslogic.github.model.User; +import io.syslogic.github.api.GithubClient; +import io.syslogic.github.api.model.User; import io.syslogic.github.network.TokenHelper; -import io.syslogic.github.retrofit.GithubClient; import okhttp3.ResponseBody; diff --git a/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java index 0bc8ac62..2959545b 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java @@ -6,10 +6,11 @@ import androidx.annotation.NonNull; -import io.syslogic.github.model.SpinnerItem; -import io.syslogic.github.model.QueryString; -import io.syslogic.github.room.Abstraction; -import io.syslogic.github.room.QueryStringsDao; +import io.syslogic.github.api.adapter.BaseArrayAdapter; +import io.syslogic.github.api.model.SpinnerItem; +import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.room.Abstraction; +import io.syslogic.github.api.room.QueryStringsDao; import java.util.List; @@ -38,7 +39,7 @@ public QueryStringAdapter(@NonNull Context context) { } activity.runOnUiThread(this::notifyDataSetChanged); } catch (IllegalStateException e) { - Log.e(LOG_TAG, e.getMessage()); + Log.e(LOG_TAG, "" + e.getMessage()); } }); } diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SearchOperatorAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SearchOperatorAdapter.java index 67acc5ed..753f7da0 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/SearchOperatorAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/SearchOperatorAdapter.java @@ -5,6 +5,7 @@ import androidx.annotation.NonNull; import io.syslogic.github.R; +import io.syslogic.github.api.adapter.BaseArrayAdapter; /** * Search-Operator {@link BaseArrayAdapter} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java index 74fb723e..68ecb898 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java @@ -5,6 +5,7 @@ import androidx.annotation.NonNull; import io.syslogic.github.R; +import io.syslogic.github.api.adapter.BaseArrayAdapter; /** * Sort-Field {@link BaseArrayAdapter} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java index 83da2009..e57e6897 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java @@ -5,6 +5,7 @@ import androidx.annotation.NonNull; import io.syslogic.github.R; +import io.syslogic.github.api.adapter.BaseArrayAdapter; /** * Sort-Order {@link BaseArrayAdapter} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java index 936b2e47..42c50bb7 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java @@ -4,7 +4,8 @@ import androidx.annotation.NonNull; -import io.syslogic.github.model.SpinnerItem; +import io.syslogic.github.api.adapter.BaseArrayAdapter; +import io.syslogic.github.api.model.SpinnerItem; import java.util.ArrayList; @@ -21,7 +22,7 @@ public StringArrayAdapter(@NonNull Context context) { super(context); } - void setItems(@NonNull Context context, String[] array) { + void setItems(@NonNull Context context, @NonNull String[] array) { this.clearItems(); for(int i = 0; i < array.length; i++) { this.mItems.add(i, new SpinnerItem(i + 1, array[i], array[i])); diff --git a/mobile/src/main/java/io/syslogic/github/content/QueryStringProvider.java b/mobile/src/main/java/io/syslogic/github/content/QueryStringProvider.java index 785f44ee..7d550e0e 100644 --- a/mobile/src/main/java/io/syslogic/github/content/QueryStringProvider.java +++ b/mobile/src/main/java/io/syslogic/github/content/QueryStringProvider.java @@ -8,9 +8,9 @@ import androidx.annotation.NonNull; -import io.syslogic.github.model.QueryString; -import io.syslogic.github.room.Abstraction; -import io.syslogic.github.room.QueryStringsDao; +import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.room.Abstraction; +import io.syslogic.github.api.room.QueryStringsDao; /** * Query-String {@link ContentProvider} diff --git a/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java b/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java index bd563674..90beaf5b 100644 --- a/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java +++ b/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java @@ -8,9 +8,9 @@ import androidx.annotation.NonNull; -import io.syslogic.github.model.Repository; -import io.syslogic.github.room.Abstraction; -import io.syslogic.github.room.RepositoriesDao; +import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.room.Abstraction; +import io.syslogic.github.api.room.RepositoriesDao; /** * Repository {@link ContentProvider} diff --git a/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java b/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java index cb62762b..e05cfa8c 100644 --- a/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java @@ -17,15 +17,15 @@ import io.syslogic.github.BuildConfig; import io.syslogic.github.Constants; -import io.syslogic.github.model.QueryString; -import io.syslogic.github.model.RepositorySearch; -import io.syslogic.github.model.Repository; -import io.syslogic.github.model.User; +import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.model.RepositorySearch; +import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.model.User; import io.syslogic.github.network.TokenHelper; -import io.syslogic.github.retrofit.GithubClient; -import io.syslogic.github.room.Abstraction; -import io.syslogic.github.room.QueryStringsDao; -import io.syslogic.github.room.RepositoriesDao; +import io.syslogic.github.api.GithubClient; +import io.syslogic.github.api.room.Abstraction; +import io.syslogic.github.api.room.QueryStringsDao; +import io.syslogic.github.api.room.RepositoriesDao; import retrofit2.Call; import retrofit2.Callback; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java index f2d44cf7..14fca560 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java @@ -28,12 +28,12 @@ import io.syslogic.github.BuildConfig; import io.syslogic.github.R; import io.syslogic.github.Constants; -import io.syslogic.github.model.User; +import io.syslogic.github.api.model.User; import io.syslogic.github.network.ConnectivityReceiver; import io.syslogic.github.network.ConnectivityListener; import io.syslogic.github.network.TokenCallback; import io.syslogic.github.network.TokenHelper; -import io.syslogic.github.retrofit.GithubClient; +import io.syslogic.github.api.GithubClient; import retrofit2.Call; import retrofit2.Callback; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java index c2ebc00b..e319eb46 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java @@ -14,7 +14,7 @@ import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; import io.syslogic.github.databinding.FragmentHomeScreenBinding; -import io.syslogic.github.model.User; +import io.syslogic.github.api.model.User; import io.syslogic.github.network.TokenCallback; import io.syslogic.github.provider.HomeScreenMenuProvider; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java index 85004e90..ef7766d7 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java @@ -17,7 +17,7 @@ import io.syslogic.github.R; import io.syslogic.github.Constants; import io.syslogic.github.databinding.FragmentProfileBinding; -import io.syslogic.github.model.User; +import io.syslogic.github.api.model.User; import io.syslogic.github.network.TokenCallback; /** diff --git a/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java index 91043c90..8afe2a3b 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java @@ -19,10 +19,10 @@ import io.syslogic.github.R; import io.syslogic.github.activity.BaseActivity; import io.syslogic.github.Constants; +import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.room.Abstraction; +import io.syslogic.github.api.room.QueryStringsDao; import io.syslogic.github.databinding.FragmentQueryStringBinding; -import io.syslogic.github.model.QueryString; -import io.syslogic.github.room.Abstraction; -import io.syslogic.github.room.QueryStringsDao; /** * Query-String {@link BaseFragment} diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java index d21beb20..9555f309 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java @@ -45,11 +45,11 @@ import io.syslogic.github.Constants; import io.syslogic.github.databinding.FragmentRepositoryBinding; import io.syslogic.github.dialog.ProgressDialogFragment; -import io.syslogic.github.model.User; +import io.syslogic.github.api.model.User; import io.syslogic.github.network.TokenCallback; -import io.syslogic.github.retrofit.GithubClient; -import io.syslogic.github.model.Branch; -import io.syslogic.github.model.Repository; +import io.syslogic.github.api.GithubClient; +import io.syslogic.github.api.model.Branch; +import io.syslogic.github.api.model.Repository; import okhttp3.Headers; import okhttp3.ResponseBody; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index 7331825f..79835964 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -18,18 +18,18 @@ import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; import io.syslogic.github.model.PagerState; -import io.syslogic.github.model.QueryString; -import io.syslogic.github.model.SpinnerItem; +import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.model.SpinnerItem; import io.syslogic.github.adapter.QueryStringAdapter; import io.syslogic.github.databinding.FragmentRepositorySearchBinding; -import io.syslogic.github.model.User; +import io.syslogic.github.api.model.User; import io.syslogic.github.network.TokenCallback; import io.syslogic.github.provider.RepositorySearchMenuProvider; import io.syslogic.github.recyclerview.RepositorySearchAdapter; import io.syslogic.github.recyclerview.RepositorySearchLinearView; import io.syslogic.github.recyclerview.ScrollListener; -import io.syslogic.github.room.Abstraction; -import io.syslogic.github.room.QueryStringsDao; +import io.syslogic.github.api.room.Abstraction; +import io.syslogic.github.api.room.QueryStringsDao; /** * Repository Search {@link BaseFragment} diff --git a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java index 87cba3ce..7088ee4b 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java @@ -15,7 +15,7 @@ import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; import io.syslogic.github.databinding.FragmentWorkflowBinding; -import io.syslogic.github.model.Workflow; +import io.syslogic.github.api.model.Workflow; import io.syslogic.github.provider.WorkflowMenuProvider; /** diff --git a/mobile/src/main/java/io/syslogic/github/model/PagerState.java b/mobile/src/main/java/io/syslogic/github/model/PagerState.java index 8ed71b2f..a8e629c7 100644 --- a/mobile/src/main/java/io/syslogic/github/model/PagerState.java +++ b/mobile/src/main/java/io/syslogic/github/model/PagerState.java @@ -2,6 +2,8 @@ import androidx.databinding.Bindable; +import io.syslogic.github.api.model.BaseModel; + /** * Model: Pager State * diff --git a/mobile/src/main/java/io/syslogic/github/network/TokenCallback.java b/mobile/src/main/java/io/syslogic/github/network/TokenCallback.java index cd8f93e3..0579c0fa 100644 --- a/mobile/src/main/java/io/syslogic/github/network/TokenCallback.java +++ b/mobile/src/main/java/io/syslogic/github/network/TokenCallback.java @@ -2,7 +2,7 @@ import androidx.annotation.NonNull; -import io.syslogic.github.model.User; +import io.syslogic.github.api.model.User; /** * Token Callback diff --git a/mobile/src/main/java/io/syslogic/github/network/TokenHelper.java b/mobile/src/main/java/io/syslogic/github/network/TokenHelper.java index 007deef7..cb8df7ae 100644 --- a/mobile/src/main/java/io/syslogic/github/network/TokenHelper.java +++ b/mobile/src/main/java/io/syslogic/github/network/TokenHelper.java @@ -18,8 +18,8 @@ import io.syslogic.github.BuildConfig; import io.syslogic.github.Constants; -import io.syslogic.github.model.User; -import io.syslogic.github.retrofit.GithubClient; +import io.syslogic.github.api.model.User; +import io.syslogic.github.api.GithubClient; import okhttp3.ResponseBody; diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsAdapter.java index 65d365e9..c143576c 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsAdapter.java @@ -21,9 +21,9 @@ import io.syslogic.github.R; import io.syslogic.github.activity.BaseActivity; import io.syslogic.github.Constants; +import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.room.Abstraction; import io.syslogic.github.databinding.CardviewQueryStringBinding; -import io.syslogic.github.model.QueryString; -import io.syslogic.github.room.Abstraction; /** * Query-Strings {@link RecyclerView.Adapter} diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index 4d1b5dac..77fc694c 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -33,11 +33,11 @@ import io.syslogic.github.activity.BaseActivity; import io.syslogic.github.databinding.CardviewWorkflowBinding; import io.syslogic.github.databinding.FragmentRepositoriesBinding; -import io.syslogic.github.model.Repository; -import io.syslogic.github.model.Workflow; -import io.syslogic.github.model.WorkflowsResponse; +import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.model.Workflow; +import io.syslogic.github.api.model.WorkflowsResponse; import io.syslogic.github.network.TokenHelper; -import io.syslogic.github.retrofit.GithubClient; +import io.syslogic.github.api.GithubClient; import okhttp3.ResponseBody; diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java index dfdc0191..51cc9ad8 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java @@ -40,13 +40,14 @@ import io.syslogic.github.databinding.CardviewRepositorySearchBinding; import io.syslogic.github.databinding.FragmentRepositorySearchBinding; import io.syslogic.github.fragment.RepositoryFragment; -import io.syslogic.github.model.PagerState; -import io.syslogic.github.model.RateLimit; -import io.syslogic.github.model.RateLimits; -import io.syslogic.github.model.RepositorySearch; -import io.syslogic.github.model.Repository; -import io.syslogic.github.retrofit.GithubClient; +import io.syslogic.github.api.model.RateLimit; +import io.syslogic.github.api.model.RateLimits; +import io.syslogic.github.api.model.RepositorySearch; +import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.GithubClient; + +import io.syslogic.github.model.PagerState; import okhttp3.ResponseBody; import retrofit2.Call; diff --git a/mobile/src/main/res/layout-land/fragment_repository_search.xml b/mobile/src/main/res/layout-land/fragment_repository_search.xml index ad041bab..a778f656 100644 --- a/mobile/src/main/res/layout-land/fragment_repository_search.xml +++ b/mobile/src/main/res/layout-land/fragment_repository_search.xml @@ -7,8 +7,8 @@ tools:context=".activity.NavHostActivity"> - - + + diff --git a/mobile/src/main/res/layout/cardview_query_string.xml b/mobile/src/main/res/layout/cardview_query_string.xml index 46f16063..7e29e942 100644 --- a/mobile/src/main/res/layout/cardview_query_string.xml +++ b/mobile/src/main/res/layout/cardview_query_string.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools"> - + - + diff --git a/mobile/src/main/res/layout/cardview_workflow.xml b/mobile/src/main/res/layout/cardview_workflow.xml index 3657a11d..9142f84a 100644 --- a/mobile/src/main/res/layout/cardview_workflow.xml +++ b/mobile/src/main/res/layout/cardview_workflow.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools"> - + - + - + - + - + + + - - - - + + diff --git a/mobile/src/main/res/layout/fragment_workflow.xml b/mobile/src/main/res/layout/fragment_workflow.xml index 1532ef1f..c7e644d4 100644 --- a/mobile/src/main/res/layout/fragment_workflow.xml +++ b/mobile/src/main/res/layout/fragment_workflow.xml @@ -6,7 +6,7 @@ tools:context=".activity.NavHostActivity"> - + - + - + - + diff --git a/mobile/src/main/res/layout/toolbar_workflow.xml b/mobile/src/main/res/layout/toolbar_workflow.xml index 6d6cf20c..58697dbc 100644 --- a/mobile/src/main/res/layout/toolbar_workflow.xml +++ b/mobile/src/main/res/layout/toolbar_workflow.xml @@ -5,7 +5,7 @@ xmlns:tools="http://schemas.android.com/tools"> - + Date: Sun, 6 Aug 2023 00:33:32 +0200 Subject: [PATCH 006/163] deprecation warning. --- .github/workflows/android.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 87200d22..31f705d6 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -18,25 +18,20 @@ jobs: - name: Get latest Corretto URL id: get-latest-corretto-url - run: >- - echo "::set-output name=URL::$(curl -LIs -o /dev/null -w - %{url_effective} - https://corretto.aws/downloads/latest/amazon-corretto-17-x64-linux-jdk.tar.gz)" + run: | + URL=$(curl -LIs -o /dev/null -w %{url_effective} https://corretto.aws/downloads/latest/amazon-corretto-17-x64-linux-jdk.tar.gz) + echo "URL=${URL}" >> $GITHUB_OUTPUT - uses: actions/cache@v3 id: corretto-cache name: Restore Corretto with: path: ./amazon-corretto-17-x64-linux-jdk.tar.gz - key: >- - ${{ runner.os }}-corretto-${{ - steps.get-latest-corretto-url.outputs.URL }} + key: ${{ runner.os }}-corretto-${{ steps.get-latest-corretto-url.outputs.URL }} - name: Download AWS Corretto if: steps.corretto-cache.outputs.cache-hit != 'true' - run: >- - wget - https://corretto.aws/downloads/latest/amazon-corretto-17-x64-linux-jdk.tar.gz + run: wget ${{ steps.get-latest-corretto-url.outputs.URL }} - name: ☕ Set up JDK 17 uses: actions/setup-java@v3 From 4c9384d8055ceb6ddd55cd51ef827618cb79389c Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 00:36:28 +0200 Subject: [PATCH 007/163] room.schemaLocation --- library/build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/build.gradle b/library/build.gradle index b7783923..3baca6fa 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -12,6 +12,12 @@ android { targetSdk 34 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" + + javaCompileOptions { + annotationProcessorOptions { + arguments = ["room.schemaLocation": "$rootDir/schema".toString()] + } + } } compileOptions { From a477e15760a8a0567041086df48c2ecefae14991 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 00:41:59 +0200 Subject: [PATCH 008/163] readme updated. --- README.md | 13 +++++++++++++ jitpack.yml | 5 +++++ library/build.gradle | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 jitpack.yml diff --git a/README.md b/README.md index 1e2875de..9b3ed976 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,16 @@ When file `token.properties` is absent, the personal access token still can be a ### Screenshots ![Repositories](screenshots/repositories_30.png?raw=true&sanitize=true "Repositories") + + +[![](https://jitci.com/gh/syslogic/androidx-github/svg)](https://jitci.com/gh/syslogic/androidx-github) [![Release](https://jitpack.io/v/syslogic/androidx-github.svg)](https://jitpack.io/#io.syslogic/androidx-github) +[![MIT License](https://img.shields.io/github/license/syslogic/androidx-github)](https://github.com/syslogic/androidx-github/blob/master/LICENSE) + + --- + +The library is also available on JitPack; either by version tag or `master-SNAPSHOT`.
+The JitPack repository URL would be: `maven { url 'https://jitpack.io' }` + + dependencies { + implementation "io.syslogic:androidx-github:1.1.5" + } diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 00000000..07b893a8 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,5 @@ +# https://jitpack.io/docs/BUILDING/#custom-commands +before_install: +# - sdk install java 17.0.7-oracle +# - sdk use java 17.0.7-oracle + - sdk update diff --git a/library/build.gradle b/library/build.gradle index 3baca6fa..891c4839 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -159,7 +159,7 @@ afterEvaluate { publications { release(MavenPublication) { groupId = group - artifactId = 'github-retrofit2-client' + artifactId = 'androidx-github' from components.getByName('release') version = version_name pom { From d2ee8dd461a1eca71a0e9746e6928605d3e4157c Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 00:47:53 +0200 Subject: [PATCH 009/163] reset to version 1.0.0 --- README.md | 2 +- version.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9b3ed976..b5a7086c 100644 --- a/README.md +++ b/README.md @@ -23,5 +23,5 @@ The library is also available on JitPack; either by version tag or `master-SNAPS The JitPack repository URL would be: `maven { url 'https://jitpack.io' }` dependencies { - implementation "io.syslogic:androidx-github:1.1.5" + implementation "io.syslogic:androidx-github:1.0.0" } diff --git a/version.properties b/version.properties index 94dfe265..6b270217 100644 --- a/version.properties +++ b/version.properties @@ -1,3 +1,3 @@ applicationId = io.syslogic.github -versionName = 1.1.5 -versionCode = 15 +versionName = 1.0.0 +versionCode = 1 From f70743ce43ce5e8f1c2f2a885b79912e4c43ddf2 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 00:54:09 +0200 Subject: [PATCH 010/163] version name. --- build.gradle | 2 -- library/build.gradle | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 0aa1369d..2af2e7b8 100644 --- a/build.gradle +++ b/build.gradle @@ -27,8 +27,6 @@ buildscript { test_rules_version = '1.5.0' uiautomator_version = '2.2.0' espresso_version = '3.5.1' - - version_name = '1.1.5' } } diff --git a/library/build.gradle b/library/build.gradle index 891c4839..b88b2f35 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -152,7 +152,7 @@ artifacts { } group = 'io.syslogic' -version = version_name +version = rootProject.ext.get('versionName') afterEvaluate { publishing { @@ -160,8 +160,8 @@ afterEvaluate { release(MavenPublication) { groupId = group artifactId = 'androidx-github' + version = rootProject.ext.get('versionName') from components.getByName('release') - version = version_name pom { name = 'GitHub API Client' description = 'A simple client library for Android' From 418cdf74ca653e5b9d7787dd48bd9865eec2e136 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 01:03:00 +0200 Subject: [PATCH 011/163] todo comment added. --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 2af2e7b8..90b6b996 100644 --- a/build.gradle +++ b/build.gradle @@ -43,6 +43,8 @@ project.ext.set('applicationId', version['applicationId']) project.ext.set('versionName', version['versionName']) project.ext.set('versionCode', new Integer(version['versionCode'])) +/** TODO: better should load the versionName from git tag */ + /** Build Configurations */ project.ext.set('archiveBuildTypes', ['debug', 'release']) From 5ffeb3b072e3f5c920a9526f5dcd00e575070c9c Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 01:09:09 +0200 Subject: [PATCH 012/163] todo comment added. --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index 90b6b996..d13c2e8f 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,11 @@ project.ext.set('versionCode', new Integer(version['versionCode'])) /** TODO: better should load the versionName from git tag */ +/* JitPack: use tag as versionName. */ +if (System.env.JITPACK) { + project.ext.set('versionName', System.env.VERSION) +} + /** Build Configurations */ project.ext.set('archiveBuildTypes', ['debug', 'release']) From 33cde404421acfe454cf46f365086a08d9c989cf Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 02:35:38 +0200 Subject: [PATCH 013/163] build.gradle updated. --- build.gradle | 3 --- library/build.gradle | 11 +++++++---- mobile/build.gradle | 16 ++++------------ version.properties | 1 - 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index d13c2e8f..89cac1a6 100644 --- a/build.gradle +++ b/build.gradle @@ -39,12 +39,9 @@ plugins { /** Version Settings, loaded from file `version.properties` */ def version = new Properties() version.load(new FileInputStream(rootProject.file('version.properties'))) -project.ext.set('applicationId', version['applicationId']) project.ext.set('versionName', version['versionName']) project.ext.set('versionCode', new Integer(version['versionCode'])) -/** TODO: better should load the versionName from git tag */ - /* JitPack: use tag as versionName. */ if (System.env.JITPACK) { project.ext.set('versionName', System.env.VERSION) diff --git a/library/build.gradle b/library/build.gradle index b88b2f35..29909ffe 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -5,21 +5,24 @@ plugins { android { namespace 'io.syslogic.github.api' + buildToolsVersion = '34.0.0' compileSdk 34 - defaultConfig { minSdk 22 targetSdk 34 + setProperty("archivesBaseName", "androidx_github_" + versionName) testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" javaCompileOptions { annotationProcessorOptions { - arguments = ["room.schemaLocation": "$rootDir/schema".toString()] + arguments = [ "room.schemaLocation": "$rootDir/schema".toString() ] } } } + sourceSets.main.java.srcDirs = [ "src/main/java" ] + compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 @@ -104,14 +107,14 @@ tasks.register('javadoc', Javadoc) { // javadoc: warning - The code being documented uses modules but the packages // defined in https://developer.android.com/reference/ are in the unnamed module. options.links "https://docs.oracle.com/en/java/javase/17/docs/api/" - options.linksOffline "https://developer.android.com/reference", "${android.sdkDirectory}/docs/reference" + // options.linksOffline "https://developer.android.com/reference", "${android.sdkDirectory}/docs/reference" options.linkSource true options.author true doFirst { // extract AAR files - configurations.implementation.filter { it.name.endsWith('.aar') }.each { aar -> + configurations.named("implementation").filter { it.name.endsWith('.aar') }.each { aar -> copy { from zipTree(aar) include "**/classes.jar" diff --git a/mobile/build.gradle b/mobile/build.gradle index d89abbcd..65d4deae 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -5,11 +5,11 @@ plugins { } android { - + namespace 'io.syslogic.github' + buildToolsVersion = '34.0.0' compileSdk 34 defaultConfig { - applicationId rootProject.ext.get('applicationId') - namespace rootProject.ext.get('applicationId') + applicationId 'io.syslogic.github' versionName rootProject.ext.get('versionName') versionCode rootProject.ext.get('versionCode') manifestPlaceholders = [ accessToken: "" ] @@ -19,12 +19,6 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testBuildType "debug" multiDexEnabled true - - javaCompileOptions { - annotationProcessorOptions { - arguments = ["room.schemaLocation": "$rootDir/schema".toString()] - } - } } compileOptions { @@ -123,9 +117,7 @@ dependencies { androidTestImplementation "androidx.fragment:fragment-testing:$fragment_version" implementation "androidx.fragment:fragment:$fragment_version" - // Room - annotationProcessor "androidx.room:room-compiler:$room_version" - testImplementation "androidx.room:room-testing:$room_version" + // Room Runtime implementation "androidx.room:room-runtime:$room_version" // Retrofit2 diff --git a/version.properties b/version.properties index 6b270217..a97ec87f 100644 --- a/version.properties +++ b/version.properties @@ -1,3 +1,2 @@ -applicationId = io.syslogic.github versionName = 1.0.0 versionCode = 1 From 2e3771e2087a537523422700f3e2929ab1e21c5d Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 03:35:01 +0200 Subject: [PATCH 014/163] javadoc task fixed. --- .../androidx_github_library__javadoc_.xml | 23 +++++++++++++++++++ library/build.gradle | 23 +++++++++++-------- .../io/syslogic/github/api/GithubClient.java | 2 +- .../io/syslogic/github/api/GithubService.java | 14 +++++------ .../io/syslogic/github/api/model/Owner.java | 2 +- .../syslogic/github/api/room/Abstraction.java | 1 + mobile/build.gradle | 2 ++ 7 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 .idea/runConfigurations/androidx_github_library__javadoc_.xml diff --git a/.idea/runConfigurations/androidx_github_library__javadoc_.xml b/.idea/runConfigurations/androidx_github_library__javadoc_.xml new file mode 100644 index 00000000..54bfca52 --- /dev/null +++ b/.idea/runConfigurations/androidx_github_library__javadoc_.xml @@ -0,0 +1,23 @@ + + + + + + + true + true + false + + + \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle index 29909ffe..edffe108 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -8,6 +8,8 @@ android { buildToolsVersion = '34.0.0' compileSdk 34 defaultConfig { + versionName rootProject.ext.get('versionName') + versionCode rootProject.ext.get('versionCode') minSdk 22 targetSdk 34 setProperty("archivesBaseName", "androidx_github_" + versionName) @@ -96,30 +98,33 @@ tasks.register('javadoc', Javadoc) { source = android.sourceSets.main.java.srcDirs destinationDir = file("${project.buildDir}/outputs/javadoc/") configurations.implementation.setCanBeResolved(true) + classpath = files(new File("${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")) - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + android.getBootClasspath().forEach{classpath += fileTree(it) } classpath += fileTree(dir: "$buildDir/tmp/aarsToJars/") classpath += configurations.implementation exclude "**/BuildConfig.java", "**/R.java" failOnError false - // options.verbose() + options.verbose() // javadoc: warning - The code being documented uses modules but the packages // defined in https://developer.android.com/reference/ are in the unnamed module. options.links "https://docs.oracle.com/en/java/javase/17/docs/api/" - // options.linksOffline "https://developer.android.com/reference", "${android.sdkDirectory}/docs/reference" + options.linksOffline "https://developer.android.com/reference", "${android.sdkDirectory}/docs/reference" options.linkSource true options.author true doFirst { // extract AAR files - configurations.named("implementation").filter { it.name.endsWith('.aar') }.each { aar -> - copy { - from zipTree(aar) - include "**/classes.jar" - into "$buildDir/tmp/aarsToJars/${aar.name.replace('.aar', '')}/" - } + configurations.implementation + .filter { it.name.endsWith('.aar') } + .each { aar -> + copy { + from zipTree(aar) + include "**/classes.jar" + into "$buildDir/tmp/aarsToJars/${aar.name.replace('.aar', '')}/" + } } // provide JAR, which contains the generated data-binding classes diff --git a/library/src/main/java/io/syslogic/github/api/GithubClient.java b/library/src/main/java/io/syslogic/github/api/GithubClient.java index b68b333d..b99321f7 100644 --- a/library/src/main/java/io/syslogic/github/api/GithubClient.java +++ b/library/src/main/java/io/syslogic/github/api/GithubClient.java @@ -68,7 +68,7 @@ private static GithubService getService() { return getService().searchRepositories("token " + token, queryString, sortField, sortOrder, pageNumber); } - /** @noinspection unused*/ + @SuppressWarnings("unused") public static @NonNull Call> getOrgRepositories(@Nullable String token, @NonNull String org, @NonNull String type, @NonNull String sortField, @NonNull String sortOrder, @NonNull Integer pageSize, @NonNull Integer pageNumber) { return getService().getOrgRepositories("token " + token, org, type, sortField, sortOrder, pageSize, pageNumber); } diff --git a/library/src/main/java/io/syslogic/github/api/GithubService.java b/library/src/main/java/io/syslogic/github/api/GithubService.java index c3485b3f..bff9face 100644 --- a/library/src/main/java/io/syslogic/github/api/GithubService.java +++ b/library/src/main/java/io/syslogic/github/api/GithubService.java @@ -25,10 +25,10 @@ /** * GitHub API Service * - * @see api v3 - * @see rate limit - * @see search - * @see branches + * @see api v3 + * @see rate limit + * @see search + * @see branches * @author Martin Zeitler */ public interface GithubService { @@ -48,11 +48,9 @@ Call searchRepositories( @NonNull @Query(value = "page") Integer pageNumber ); - /** - * Organization repositories - * @noinspection unused - */ + /** Organization repositories */ @NonNull + @SuppressWarnings("unused") @GET("orgs/{org}/repos") Call> getOrgRepositories( @NonNull @Header("Authorization") String token, diff --git a/library/src/main/java/io/syslogic/github/api/model/Owner.java b/library/src/main/java/io/syslogic/github/api/model/Owner.java index c34a1a47..9b62f7a6 100644 --- a/library/src/main/java/io/syslogic/github/api/model/Owner.java +++ b/library/src/main/java/io/syslogic/github/api/model/Owner.java @@ -11,7 +11,7 @@ /** * Model: Owner * - * @see repos/#get + * @see repos/#get * @author Martin Zeitler */ @Entity(tableName = Constants.TABLE_OWNERS) diff --git a/library/src/main/java/io/syslogic/github/api/room/Abstraction.java b/library/src/main/java/io/syslogic/github/api/room/Abstraction.java index 394ed0f5..8c3febbb 100644 --- a/library/src/main/java/io/syslogic/github/api/room/Abstraction.java +++ b/library/src/main/java/io/syslogic/github/api/room/Abstraction.java @@ -44,6 +44,7 @@ public abstract class Abstraction extends RoomDatabase { /** * Asset `src/main/assets/room.db` must match the current schema version, * else this will also result in: "Room cannot verify the data integrity". + * @param context any Content class. */ @NonNull public static Abstraction getInstance(@NonNull Context context) { diff --git a/mobile/build.gradle b/mobile/build.gradle index 65d4deae..2263bdeb 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -118,6 +118,8 @@ dependencies { implementation "androidx.fragment:fragment:$fragment_version" // Room Runtime + annotationProcessor "androidx.room:room-compiler:$room_version" + testImplementation "androidx.room:room-testing:$room_version" implementation "androidx.room:room-runtime:$room_version" // Retrofit2 From c9aa2b781a69a5de7a87e86511c2f79375411ba7 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 03:39:35 +0200 Subject: [PATCH 015/163] javadoc task fixed. --- library/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/build.gradle b/library/build.gradle index edffe108..c55e769e 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -103,7 +103,7 @@ tasks.register('javadoc', Javadoc) { android.getBootClasspath().forEach{classpath += fileTree(it) } classpath += fileTree(dir: "$buildDir/tmp/aarsToJars/") classpath += configurations.implementation - exclude "**/BuildConfig.java", "**/R.java" + exclude "**/BuildConfig.java", "**/R.java", "**/*.kt" failOnError false options.verbose() From ca14b585b7cb91210d65b8d9adc1f3b04faff7fc Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 03:46:11 +0200 Subject: [PATCH 016/163] javadoc task fixed. --- library/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/build.gradle b/library/build.gradle index c55e769e..e1c19be9 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -106,7 +106,7 @@ tasks.register('javadoc', Javadoc) { exclude "**/BuildConfig.java", "**/R.java", "**/*.kt" failOnError false - options.verbose() + // options.verbose() // javadoc: warning - The code being documented uses modules but the packages // defined in https://developer.android.com/reference/ are in the unnamed module. options.links "https://docs.oracle.com/en/java/javase/17/docs/api/" From 1f12d51db7a763e6ca89e3d61e428142b225c3b9 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 03:48:00 +0200 Subject: [PATCH 017/163] clutter removed. --- library/src/main/AndroidManifest.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml index a5918e68..1d26c87a 100644 --- a/library/src/main/AndroidManifest.xml +++ b/library/src/main/AndroidManifest.xml @@ -1,4 +1,2 @@ - - - \ No newline at end of file + \ No newline at end of file From 593d43cb227bc54c49bd3e8118192becaaca2087 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 04:19:25 +0200 Subject: [PATCH 018/163] javadocs improved. --- .../io/syslogic/github/api/GithubClient.java | 13 ++++++++++ .../io/syslogic/github/api/GithubService.java | 9 ++++--- .../syslogic/github/api/room/Abstraction.java | 24 +++++++++++++++++++ .../github}/adapter/BaseArrayAdapter.java | 2 +- .../github/adapter/QueryStringAdapter.java | 1 - .../github/adapter/SearchOperatorAdapter.java | 1 - .../github/adapter/SortFieldAdapter.java | 1 - .../github/adapter/SortOrderAdapter.java | 1 - .../github/adapter/StringArrayAdapter.java | 1 - 9 files changed, 42 insertions(+), 11 deletions(-) rename {library/src/main/java/io/syslogic/github/api => mobile/src/main/java/io/syslogic/github}/adapter/BaseArrayAdapter.java (98%) diff --git a/library/src/main/java/io/syslogic/github/api/GithubClient.java b/library/src/main/java/io/syslogic/github/api/GithubClient.java index b99321f7..ec21e773 100644 --- a/library/src/main/java/io/syslogic/github/api/GithubClient.java +++ b/library/src/main/java/io/syslogic/github/api/GithubClient.java @@ -29,6 +29,7 @@ public class GithubClient { private static Retrofit retrofit; + /** */ @NonNull private static GithubService getService() { if (retrofit == null) { @@ -51,53 +52,65 @@ private static GithubService getService() { return retrofit.create(GithubService.class); } + /** */ public static @NonNull Call getRateLimits() { return getService().getRateLimits(); } + /** */ public static @NonNull Call getUser(@NonNull String token) { return getService().getUser("token " + token); } + /** */ @SuppressWarnings("unused") public static @NonNull Call getUser(@NonNull String username, @NonNull String token) { return getService().getUser("token " + token, username); } + /** */ public static @NonNull Call searchRepositories(@Nullable String token, @NonNull String queryString, @NonNull String sortField, @NonNull String sortOrder, @NonNull Integer pageNumber) { return getService().searchRepositories("token " + token, queryString, sortField, sortOrder, pageNumber); } + /** */ @SuppressWarnings("unused") public static @NonNull Call> getOrgRepositories(@Nullable String token, @NonNull String org, @NonNull String type, @NonNull String sortField, @NonNull String sortOrder, @NonNull Integer pageSize, @NonNull Integer pageNumber) { return getService().getOrgRepositories("token " + token, org, type, sortField, sortOrder, pageSize, pageNumber); } + /** */ public static @NonNull Call> getUserRepositories(@Nullable String token, @NonNull String username, @NonNull String type, @NonNull String sortField, @NonNull String sortOrder, @NonNull Integer pageSize, @NonNull Integer pageNumber) { return getService().getUserRepositories("token " + token, username, type, sortField, sortOrder, pageSize, pageNumber); } + /** */ public static @NonNull Call getRepository(@NonNull Long itemId) { return getService().getRepository(itemId); } + /** */ public static @NonNull Call> getBranches(@NonNull String owner, @NonNull String repo) { return getService().getBranches(owner, repo); } + /** */ @SuppressWarnings("unused") public static @NonNull Call getBranch(@NonNull String owner, @NonNull String repo, @NonNull String branch) { return getService().getBranch(owner, repo, branch); } + /** */ public static @NonNull Call getWorkflows(@Nullable String token, @NonNull String owner, @NonNull String repo) { return getService().getWorkflows("token " + token, owner, repo); } + /** */ public static @NonNull Call getArchiveLink(@NonNull String token, @NonNull String owner, @NonNull String repo, @NonNull String format, @NonNull String ref) { return getService().getArchiveLink("token " + token, owner, repo, format, ref); } + /** */ public static @NonNull Call getHead(@NonNull String url) { return getService().getHead(url); } diff --git a/library/src/main/java/io/syslogic/github/api/GithubService.java b/library/src/main/java/io/syslogic/github/api/GithubService.java index bff9face..e5e85760 100644 --- a/library/src/main/java/io/syslogic/github/api/GithubService.java +++ b/library/src/main/java/io/syslogic/github/api/GithubService.java @@ -33,6 +33,7 @@ */ public interface GithubService { + /** Get rate limits. */ @NonNull @GET("rate_limit") Call getRateLimits(); @@ -147,9 +148,7 @@ Call getRepositories( @NonNull @Header("Authorization") String token ); - /** - * GitHub Actions: Workflows - */ + /** GitHub Actions: Workflows */ @NonNull @GET("/repos/{owner}/{repo}/actions/workflows") Call getWorkflows( @@ -158,10 +157,10 @@ Call getWorkflows( @NonNull @Path(value = "repo") String repo ); - /** GitHub Actions: Workflow Run */ + /** GitHub Actions: Workflow Runs */ @NonNull @GET("/repos/{owner}/{repo}/actions/jobs/{jobId}") - Call getWorkflowRun( + Call getWorkflowRuns( @NonNull @Header("Authorization") String token, @NonNull @Path(value = "owner") String owner, @NonNull @Path(value = "repo") String repo, diff --git a/library/src/main/java/io/syslogic/github/api/room/Abstraction.java b/library/src/main/java/io/syslogic/github/api/room/Abstraction.java index 8c3febbb..9767fca4 100644 --- a/library/src/main/java/io/syslogic/github/api/room/Abstraction.java +++ b/library/src/main/java/io/syslogic/github/api/room/Abstraction.java @@ -25,26 +25,50 @@ @Database(version = 1, entities = {QueryString.class, Repository.class, License.class, Owner.class}) public abstract class Abstraction extends RoomDatabase { + /** The log tag. */ @NonNull protected static final String LOG_TAG = Abstraction.class.getSimpleName(); private static final int NUMBER_OF_THREADS = 4; + /** The {@link ExecutorService} being used for all database operations. */ public static final ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS); + /** The file-name of the database in local storage. */ private static final String fileName = "room.db"; + /** {@link Room} database instance handle. */ private static Abstraction sInstance; + /** + * Abstract {@link androidx.room.Dao} for {@link QueryString}. + * @return in instance of {@link QueryStringsDao}. + */ @Nullable public abstract QueryStringsDao queryStringsDao(); + + /** + * Abstract {@link androidx.room.Dao} for {@link Repository}. + * @return in instance of {@link RepositoriesDao}. + */ @Nullable public abstract RepositoriesDao repositoriesDao(); + + /** + * Abstract {@link androidx.room.Dao} for {@link License}. + * @return in instance of {@link LicensesDao}. + */ @Nullable public abstract LicensesDao licensesDao(); + + /** + * Abstract {@link androidx.room.Dao} for {@link Owner}. + * @return in instance of {@link OwnersDao}. + */ @Nullable public abstract OwnersDao ownersDao(); /** * Asset `src/main/assets/room.db` must match the current schema version, * else this will also result in: "Room cannot verify the data integrity". * @param context any Content class. + * @return an instance of {@link Room} database. */ @NonNull public static Abstraction getInstance(@NonNull Context context) { diff --git a/library/src/main/java/io/syslogic/github/api/adapter/BaseArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java similarity index 98% rename from library/src/main/java/io/syslogic/github/api/adapter/BaseArrayAdapter.java rename to mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java index 1f4e5118..6738ae39 100644 --- a/library/src/main/java/io/syslogic/github/api/adapter/BaseArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java @@ -1,4 +1,4 @@ -package io.syslogic.github.api.adapter; +package io.syslogic.github.adapter; import android.content.Context; import android.content.res.Resources; diff --git a/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java index 2959545b..c518f8b5 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java @@ -6,7 +6,6 @@ import androidx.annotation.NonNull; -import io.syslogic.github.api.adapter.BaseArrayAdapter; import io.syslogic.github.api.model.SpinnerItem; import io.syslogic.github.api.model.QueryString; import io.syslogic.github.api.room.Abstraction; diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SearchOperatorAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SearchOperatorAdapter.java index 753f7da0..67acc5ed 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/SearchOperatorAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/SearchOperatorAdapter.java @@ -5,7 +5,6 @@ import androidx.annotation.NonNull; import io.syslogic.github.R; -import io.syslogic.github.api.adapter.BaseArrayAdapter; /** * Search-Operator {@link BaseArrayAdapter} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java index 68ecb898..74fb723e 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java @@ -5,7 +5,6 @@ import androidx.annotation.NonNull; import io.syslogic.github.R; -import io.syslogic.github.api.adapter.BaseArrayAdapter; /** * Sort-Field {@link BaseArrayAdapter} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java index e57e6897..83da2009 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java @@ -5,7 +5,6 @@ import androidx.annotation.NonNull; import io.syslogic.github.R; -import io.syslogic.github.api.adapter.BaseArrayAdapter; /** * Sort-Order {@link BaseArrayAdapter} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java index 42c50bb7..3f1419d6 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java @@ -4,7 +4,6 @@ import androidx.annotation.NonNull; -import io.syslogic.github.api.adapter.BaseArrayAdapter; import io.syslogic.github.api.model.SpinnerItem; import java.util.ArrayList; From b950a01fd3e2f7a7f617abf71fc284eaf90a6b99 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 05:00:21 +0200 Subject: [PATCH 019/163] javadocs improved. --- .../io/syslogic/github/api/GithubClient.java | 114 ++++++++++++++--- .../io/syslogic/github/api/GithubService.java | 118 +++++++++++++++--- .../github/api/content/IContentProvider.java | 13 +- 3 files changed, 205 insertions(+), 40 deletions(-) diff --git a/library/src/main/java/io/syslogic/github/api/GithubClient.java b/library/src/main/java/io/syslogic/github/api/GithubClient.java index ec21e773..6dfe91f2 100644 --- a/library/src/main/java/io/syslogic/github/api/GithubClient.java +++ b/library/src/main/java/io/syslogic/github/api/GithubClient.java @@ -29,7 +29,7 @@ public class GithubClient { private static Retrofit retrofit; - /** */ + /** @return an instance of {@link GithubService}. */ @NonNull private static GithubService getService() { if (retrofit == null) { @@ -52,66 +52,140 @@ private static GithubService getService() { return retrofit.create(GithubService.class); } - /** */ + /** @return Retrofit2 call. */ public static @NonNull Call getRateLimits() { return getService().getRateLimits(); } - /** */ + /** + * @param token the personal access token. + * @return Retrofit2 call. + */ public static @NonNull Call getUser(@NonNull String token) { return getService().getUser("token " + token); } - /** */ + /** + * @param token the personal access token. + * @param username the name of the user to get. + * @return Retrofit2 call. + */ @SuppressWarnings("unused") - public static @NonNull Call getUser(@NonNull String username, @NonNull String token) { + public static @NonNull Call getUser(@NonNull String token, @NonNull String username) { return getService().getUser("token " + token, username); } - /** */ + /** + * Search Repositories. + * @param token the personal access token. + * @param queryString the query-string of the repository search. + * @param sortField Default: created. Can be one of: created, updated, pushed, full_name. + * @param sortOrder Default: asc when using full_name, otherwise desc. Can be one of: asc, desc. + * @param pageNumber Page number of the results to fetch. Default: 1. + * @return Retrofit2 call. + */ public static @NonNull Call searchRepositories(@Nullable String token, @NonNull String queryString, @NonNull String sortField, @NonNull String sortOrder, @NonNull Integer pageNumber) { return getService().searchRepositories("token " + token, queryString, sortField, sortOrder, pageNumber); } - /** */ + /** + * Organization repositories + * @param token the personal access token. + * @param org the corresponding organization name. + * @param type Default: all. Can be one of: all, public, private, forks, sources, member. + * @param sortField Default: created. Can be one of: created, updated, pushed, full_name. + * @param sortOrder Default: asc when using full_name, otherwise desc. Can be one of: asc, desc. + * @param pageSize The number of results per page (max 100). Default: 30. + * @param pageNumber Page number of the results to fetch. Default: 1. + * @return Retrofit2 call. + */ @SuppressWarnings("unused") public static @NonNull Call> getOrgRepositories(@Nullable String token, @NonNull String org, @NonNull String type, @NonNull String sortField, @NonNull String sortOrder, @NonNull Integer pageSize, @NonNull Integer pageNumber) { return getService().getOrgRepositories("token " + token, org, type, sortField, sortOrder, pageSize, pageNumber); } - /** */ + /** + * User repositories + * @param token the personal access token. + * @param username the corresponding username. + * @param type Default: all. Can be one of: all, public, private, forks, sources, member. + * @param sortField Default: created. Can be one of: created, updated, pushed, full_name. + * @param sortOrder Default: asc when using full_name, otherwise desc. Can be one of: asc, desc. + * @param pageSize The number of results per page (max 100). Default: 30. + * @param pageNumber Page number of the results to fetch. Default: 1. + * @return Retrofit2 call. + */ public static @NonNull Call> getUserRepositories(@Nullable String token, @NonNull String username, @NonNull String type, @NonNull String sortField, @NonNull String sortOrder, @NonNull Integer pageSize, @NonNull Integer pageNumber) { return getService().getUserRepositories("token " + token, username, type, sortField, sortOrder, pageSize, pageNumber); } - /** */ + /** + * One repository. + * @param itemId the ID of the repository to get. + * @return Retrofit2 call. + */ public static @NonNull Call getRepository(@NonNull Long itemId) { return getService().getRepository(itemId); } - /** */ + /** + * All branches of a repository. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @return Retrofit2 call. + */ public static @NonNull Call> getBranches(@NonNull String owner, @NonNull String repo) { return getService().getBranches(owner, repo); } - /** */ + /** + * One branch of a repository. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @param branch the name of the branch. + * @return Retrofit2 call. + */ @SuppressWarnings("unused") public static @NonNull Call getBranch(@NonNull String owner, @NonNull String repo, @NonNull String branch) { return getService().getBranch(owner, repo, branch); } - /** */ - public static @NonNull Call getWorkflows(@Nullable String token, @NonNull String owner, @NonNull String repo) { - return getService().getWorkflows("token " + token, owner, repo); - } - - /** */ - public static @NonNull Call getArchiveLink(@NonNull String token, @NonNull String owner, @NonNull String repo, @NonNull String format, @NonNull String ref) { - return getService().getArchiveLink("token " + token, owner, repo, format, ref); + /** + * Obtain the redirect URL to download an archive for a repository. + * The :archive_format can be either "tarball" or "zipball". + * The :branch must be a valid Git reference. + * + *

If you omit :branch, the repository’s default branch (usually master) will be used. + * Note: for private repositories, the links are temporary and expire after five minutes.

+ * + * @param token the personal access token. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @param format either zip or tar. + * @param branch the ref, which to download. + * @return Retrofit2 call. + */ + public static @NonNull Call getArchiveLink(@NonNull String token, @NonNull String owner, @NonNull String repo, @NonNull String format, @NonNull String branch) { + return getService().getArchiveLink("token " + token, owner, repo, format, branch); } - /** */ + /** + * It determines the filename to use with the DownloadManager. + * @param url the url, which to download. + * @return Retrofit2 call. + */ public static @NonNull Call getHead(@NonNull String url) { return getService().getHead(url); } + + /** + * GitHub Actions: Workflows per repository. + * @param token the personal access token. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @return Retrofit2 call. + */ + public static @NonNull Call getWorkflows(@Nullable String token, @NonNull String owner, @NonNull String repo) { + return getService().getWorkflows("token " + token, owner, repo); + } } diff --git a/library/src/main/java/io/syslogic/github/api/GithubService.java b/library/src/main/java/io/syslogic/github/api/GithubService.java index e5e85760..aba4102d 100644 --- a/library/src/main/java/io/syslogic/github/api/GithubService.java +++ b/library/src/main/java/io/syslogic/github/api/GithubService.java @@ -33,12 +33,23 @@ */ public interface GithubService { - /** Get rate limits. */ + /** + * Get rate limits. + * @return Retrofit2 call. + */ @NonNull @GET("rate_limit") Call getRateLimits(); - /** Search all repositories */ + /** + * Search all Repositories. + * @param token the personal access token. + * @param queryString the query-string of the repository search. + * @param sortField Default: created. Can be one of: created, updated, pushed, full_name. + * @param sortOrder Default: asc when using full_name, otherwise desc. Can be one of: asc, desc. + * @param pageNumber Page number of the results to fetch. Default: 1. + * @return Retrofit2 call. + */ @NonNull @GET("search/repositories") Call searchRepositories( @@ -49,7 +60,17 @@ Call searchRepositories( @NonNull @Query(value = "page") Integer pageNumber ); - /** Organization repositories */ + /** + * Organization repositories. + * @param token the personal access token. + * @param org the corresponding organization name. + * @param type Default: all. Can be one of: all, public, private, forks, sources, member. + * @param sortField Default: created. Can be one of: created, updated, pushed, full_name. + * @param sortOrder Default: asc when using full_name, otherwise desc. Can be one of: asc, desc. + * @param pageSize The number of results per page (max 100). Default: 30. + * @param pageNumber Page number of the results to fetch. Default: 1. + * @return Retrofit2 call. + */ @NonNull @SuppressWarnings("unused") @GET("orgs/{org}/repos") @@ -63,27 +84,46 @@ Call> getOrgRepositories( @NonNull @Query(value = "page") Integer pageNumber // Page number of the results to fetch. Default: 1 ); - /** User repositories */ + /** + * User repositories. + * @param token the personal access token. + * @param username the corresponding username. + * @param type Default: all. Can be one of: all, public, private, forks, sources, member. + * @param sortField Default: created. Can be one of: created, updated, pushed, full_name. + * @param sortOrder Default: asc when using full_name, otherwise desc. Can be one of: asc, desc. + * @param pageSize The number of results per page (max 100). Default: 30. + * @param pageNumber Page number of the results to fetch. Default: 1. + * @return Retrofit2 call. + */ @NonNull @GET("users/{username}/repos") Call> getUserRepositories( @NonNull @Header("Authorization") String token, @NonNull @Path(value = "username") String username, - @NonNull @Query(value = "type") String type, // Default: all. Can be one of: all, public, private, forks, sources, member - @NonNull @Query(value = "sort") String sortField, // Default: created. Can be one of: created, updated, pushed, full_name - @NonNull @Query(value = "direction") String sortOrder, // Default: asc when using full_name, otherwise desc. Can be one of: asc, desc - @NonNull @Query(value = "per_page") Integer pageSize, // The number of results per page (max 100). Default: 30 - @NonNull @Query(value = "page") Integer pageNumber // Page number of the results to fetch. Default: 1 + @NonNull @Query(value = "type") String type, + @NonNull @Query(value = "sort") String sortField, + @NonNull @Query(value = "direction") String sortOrder, + @NonNull @Query(value = "per_page") Integer pageSize, + @NonNull @Query(value = "page") Integer pageNumber ); - /** One repository */ + /** + * One repository. + * @param id the ID of the repository to get. + * @return Retrofit2 call. + */ @NonNull @GET("repositories/{id}") Call getRepository( @NonNull @Path(value = "id") Long id ); - /** All branches of a repository */ + /** + * All branches of a repository. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @return Retrofit2 call. + */ @NonNull @GET("/repos/{owner}/{repo}/branches") Call> getBranches( @@ -91,7 +131,13 @@ Call> getBranches( @NonNull @Path(value = "repo") String repo ); - /** One branch of a repository */ + /** + * One branch of a repository. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @param branch the name of the branch. + * @return Retrofit2 call. + */ @NonNull @GET("/repos/{owner}/{repo}/branches/{branch}") Call getBranch( @@ -108,6 +154,12 @@ Call getBranch( * If you omit :branch, the repository’s default branch (usually master) will be used. * Note: for private repositories, the links are temporary and expire after five minutes. *

+ * @param token the personal access token. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @param format either zip or tar. + * @param branch the ref, which to download. + * @return Retrofit2 call. */ @NonNull @Streaming @@ -120,19 +172,32 @@ Call getArchiveLink( @Nullable @Path(value = "branch") String branch ); - /** It determines the filename to use with the DownloadManager. */ + /** + * It determines the filename to use with the DownloadManager. + * @param url the url, which to download. + * @return Retrofit2 call. + */ @NonNull @HEAD Call getHead(@NonNull @Url String url); - /** One user */ + /** + * One user. + * @param token the personal access token. + * @return Retrofit2 call. + */ @NonNull @GET("user") Call getUser( @NonNull @Header("Authorization") String token ); - /** One user */ + /** + * One user. + * @param token the personal access token. + * @param username the name of the user. + * @return Retrofit2 call. + */ @NonNull @GET("user/{username}") Call getUser( @@ -140,7 +205,11 @@ Call getUser( @NonNull @Path(value = "name") String username ); - /** One user */ + /** + * One user. + * @param token the personal access token. + * @return Retrofit2 call. + */ @NonNull @SuppressWarnings("unused") @GET("/user/repos") @@ -148,7 +217,13 @@ Call getRepositories( @NonNull @Header("Authorization") String token ); - /** GitHub Actions: Workflows */ + /** + * GitHub Actions: Workflows per repository. + * @param token the personal access token. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @return Retrofit2 call. + */ @NonNull @GET("/repos/{owner}/{repo}/actions/workflows") Call getWorkflows( @@ -157,7 +232,14 @@ Call getWorkflows( @NonNull @Path(value = "repo") String repo ); - /** GitHub Actions: Workflow Runs */ + /** + * GitHub Actions: Workflow Runs. + * @param token the personal access token. + * @param owner the owner of the repository. + * @param repo the name of the repository. + * @param jobId the ID of the job. + * @return Retrofit2 call. + */ @NonNull @GET("/repos/{owner}/{repo}/actions/jobs/{jobId}") Call getWorkflowRuns( diff --git a/library/src/main/java/io/syslogic/github/api/content/IContentProvider.java b/library/src/main/java/io/syslogic/github/api/content/IContentProvider.java index 98ef53a6..0a547f35 100644 --- a/library/src/main/java/io/syslogic/github/api/content/IContentProvider.java +++ b/library/src/main/java/io/syslogic/github/api/content/IContentProvider.java @@ -14,7 +14,16 @@ */ public interface IContentProvider { - @NonNull ContentValues toContentValues(); - + /** + * {@link BaseModel} from {@link ContentValues}. + * @param values an instance of {@link ContentValues}. + * @return an instance of {@link BaseModel}. + */ @NonNull BaseModel fromContentValues(@NonNull ContentValues values); + + /** + * {@link BaseModel} to {@link ContentValues}. + * @return an instance of {@link ContentValues}. + */ + @NonNull ContentValues toContentValues(); } From ec81b4e8071e9b4e515e5fc8d3d1b78f0890a57d Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 05:01:46 +0200 Subject: [PATCH 020/163] some more refactoring. --- .../github/api/{content => model}/IContentProvider.java | 2 +- .../src/main/java/io/syslogic/github/api/model/QueryString.java | 1 - .../src/main/java/io/syslogic/github/api/model/Repository.java | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) rename library/src/main/java/io/syslogic/github/api/{content => model}/IContentProvider.java (94%) diff --git a/library/src/main/java/io/syslogic/github/api/content/IContentProvider.java b/library/src/main/java/io/syslogic/github/api/model/IContentProvider.java similarity index 94% rename from library/src/main/java/io/syslogic/github/api/content/IContentProvider.java rename to library/src/main/java/io/syslogic/github/api/model/IContentProvider.java index 0a547f35..e63708bb 100644 --- a/library/src/main/java/io/syslogic/github/api/content/IContentProvider.java +++ b/library/src/main/java/io/syslogic/github/api/model/IContentProvider.java @@ -1,4 +1,4 @@ -package io.syslogic.github.api.content; +package io.syslogic.github.api.model; import android.content.ContentProvider; import android.content.ContentValues; diff --git a/library/src/main/java/io/syslogic/github/api/model/QueryString.java b/library/src/main/java/io/syslogic/github/api/model/QueryString.java index 1f64b56a..cde04f29 100644 --- a/library/src/main/java/io/syslogic/github/api/model/QueryString.java +++ b/library/src/main/java/io/syslogic/github/api/model/QueryString.java @@ -16,7 +16,6 @@ import java.util.Locale; import io.syslogic.github.api.Constants; -import io.syslogic.github.api.content.IContentProvider; /** * Model: Query-String diff --git a/library/src/main/java/io/syslogic/github/api/model/Repository.java b/library/src/main/java/io/syslogic/github/api/model/Repository.java index 8128c0db..40fc25b5 100644 --- a/library/src/main/java/io/syslogic/github/api/model/Repository.java +++ b/library/src/main/java/io/syslogic/github/api/model/Repository.java @@ -14,7 +14,6 @@ import com.google.gson.annotations.SerializedName; import io.syslogic.github.api.Constants; -import io.syslogic.github.api.content.IContentProvider; import io.syslogic.github.api.utils.StringArrayConverter; /** From 6643ec37b8800402be01e80adbdf6faeb9de4518 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 6 Aug 2023 06:12:28 +0200 Subject: [PATCH 021/163] javadoc task fixed. --- library/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/build.gradle b/library/build.gradle index e1c19be9..96bc2da5 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -100,7 +100,7 @@ tasks.register('javadoc', Javadoc) { configurations.implementation.setCanBeResolved(true) classpath = files(new File("${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")) - android.getBootClasspath().forEach{classpath += fileTree(it) } + android.getBootClasspath().forEach{ classpath += fileTree(it) } classpath += fileTree(dir: "$buildDir/tmp/aarsToJars/") classpath += configurations.implementation exclude "**/BuildConfig.java", "**/R.java", "**/*.kt" From 35d58e52c51aa094e12c346a88b2aca4a5706008 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 7 Aug 2023 06:44:57 +0200 Subject: [PATCH 022/163] endless scrolling works, but pager state not yet reflects the adapter. --- .../github/fragment/BaseFragment.java | 2 +- .../github/fragment/HomeScreenFragment.java | 2 +- .../github/fragment/ProfileFragment.java | 2 +- .../github/fragment/RepositoriesFragment.java | 36 +++++- .../github/fragment/RepositoryFragment.java | 6 +- .../fragment/RepositorySearchFragment.java | 52 ++++----- .../recyclerview/RepositoriesAdapter.java | 109 ++++++++++-------- .../recyclerview/RepositoriesLinearView.java | 24 +++- .../RepositorySearchLinearView.java | 11 +- ...w_workflow.xml => cardview_repository.xml} | 0 .../main/res/layout/fragment_repositories.xml | 54 +++++---- .../main/res/layout/toolbar_repositories.xml | 2 +- 12 files changed, 181 insertions(+), 119 deletions(-) rename mobile/src/main/res/layout/{cardview_workflow.xml => cardview_repository.xml} (100%) diff --git a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java index 14fca560..43e2999b 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java @@ -166,7 +166,7 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis abstract protected void setDataBinding(@NonNull ViewDataBinding binding); @Nullable - protected String getPersonalAccessToken() { + protected String getAccessToken() { return TokenHelper.getAccessToken(requireContext()); } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java index e319eb46..0cb87076 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java @@ -52,7 +52,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c if (! isNetworkAvailable(activity)) { this.onNetworkLost(); } else { - String token = this.getPersonalAccessToken(); + String token = this.getAccessToken(); if (getCurrentUser() == null && token != null) { this.setUser(token, this); } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java index ef7766d7..4b425131 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java @@ -71,7 +71,7 @@ public void onPageCommitVisible (WebView view, String url) { } }); - String token = this.getPersonalAccessToken(); + String token = this.getAccessToken(); if (getCurrentUser() == null && token != null) { this.setUser(token, this); } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java index 9549328e..7c504c9f 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java @@ -11,7 +11,10 @@ import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; +import io.syslogic.github.api.model.User; import io.syslogic.github.databinding.FragmentRepositoriesBinding; +import io.syslogic.github.model.PagerState; +import io.syslogic.github.network.TokenCallback; import io.syslogic.github.provider.RepositoriesMenuProvider; import io.syslogic.github.recyclerview.RepositoriesAdapter; @@ -20,7 +23,7 @@ * * @author Martin Zeitler */ -public class RepositoriesFragment extends BaseFragment { +public class RepositoriesFragment extends BaseFragment implements TokenCallback { /** Log Tag */ @SuppressWarnings("unused") @@ -41,19 +44,19 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c NavHostActivity activity = ((NavHostActivity) this.requireActivity()); this.setDataBinding(FragmentRepositoriesBinding.inflate(inflater, container, false)); + this.getDataBinding().setPagerState(new PagerState()); /* It removes & adds {@link BaseMenuProvider} */ activity.setMenuProvider(new RepositoriesMenuProvider(activity)); - activity.setSupportActionBar(this.getDataBinding().toolbarWorkflows.toolbarWorkflows); - this.mDataBinding.toolbarWorkflows.home.setOnClickListener(view -> activity.onBackPressed()); + activity.setSupportActionBar(this.getDataBinding().toolbarRepositories.toolbarRepositories); + this.mDataBinding.toolbarRepositories.home.setOnClickListener(view -> activity.onBackPressed()); if (! isNetworkAvailable(this.requireContext())) { this.onNetworkLost(); } else { RepositoriesAdapter adapter = new RepositoriesAdapter(requireContext()); - this.getDataBinding().recyclerviewWorkflows.setAdapter(adapter); - adapter.fetchPage(1); + this.getDataBinding().recyclerviewRepositories.setAdapter(adapter); } return this.getDataBinding().getRoot(); } @@ -71,11 +74,29 @@ protected void setDataBinding(@NonNull ViewDataBinding binding) { @Override public void onNetworkAvailable() { super.onNetworkAvailable(); + String token = this.getAccessToken(); + if (getCurrentUser() == null && token != null) { + this.setUser(token, this); + } + + //noinspection ConstantValue + if (this.getDataBinding() != null) { + PagerState pagerState = this.getDataBinding().getPagerState(); + pagerState.setIsOffline(false); + this.getDataBinding().setPagerState(pagerState); + } + } @Override public void onNetworkLost() { super.onNetworkLost(); + PagerState pagerState = this.getDataBinding().getPagerState(); + if (pagerState != null) { + pagerState.setIsLoading(false); + pagerState.setIsOffline(true); + this.getDataBinding().setPagerState(pagerState); + } } @Override @@ -83,4 +104,9 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis super.onRequestPermissionsResult(requestCode, permissions, grantResults); // if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {} } + + @Override + public void onLogin(@NonNull User item) { + this.mDataBinding.setUser(item); + } } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java index 9555f309..5ba54439 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java @@ -199,7 +199,7 @@ private void gitClone(@NonNull File destination, @Nullable String branch) { Thread thread = new Thread(() -> { CloneCommand cmd = Git.cloneRepository() .setURI(getRepoUrl()) - .setCredentialsProvider(new UsernamePasswordCredentialsProvider(getPersonalAccessToken(), "")) + .setCredentialsProvider(new UsernamePasswordCredentialsProvider(getAccessToken(), "")) .setProgressMonitor((ProgressMonitor) currentDialog) .setDirectory(destination) .setRemote("github"); @@ -260,7 +260,7 @@ public void onNetworkAvailable() { super.onNetworkAvailable(); if (this.getContext() != null) { - String token = this.getPersonalAccessToken(); + String token = this.getAccessToken(); if (getCurrentUser() == null && token != null) { this.setUser(token, this); } @@ -419,7 +419,7 @@ void downloadTarball(Repository item, String branch) { } void downloadRepository(@NonNull final Repository item, final String archiveFormat, String branch) { - String token = getPersonalAccessToken(); + String token = getAccessToken(); assert token != null; Call api = GithubClient.getArchiveLink(token, item.getOwner().getLogin(), item.getName(), archiveFormat, branch); if (mDebug) {Log.d(LOG_TAG, api.request().url() + "");} diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index 79835964..9b4c41c9 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -64,7 +64,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c /* It removes & adds {@link BaseMenuProvider} */ activity.setMenuProvider(new RepositorySearchMenuProvider(activity)); - // the SpinnerItem has the same ID as the QueryString. + /* the SpinnerItem has the same ID as the QueryString. */ activity.setSupportActionBar(this.getDataBinding().toolbarRepositories.toolbarRepositories); this.mDataBinding.toolbarRepositories.home.setOnClickListener(view -> activity.onBackPressed()); @@ -150,38 +150,36 @@ public void onNetworkAvailable() { super.onNetworkAvailable(); - String token = this.getPersonalAccessToken(); + String token = this.getAccessToken(); if (getCurrentUser() == null && token != null) { this.setUser(token, this); } - if (mDataBinding != null) { - PagerState pagerState = this.getDataBinding().getPagerState(); - if (pagerState != null) { - pagerState.setIsOffline(false); - this.getDataBinding().setPagerState(pagerState); - } + PagerState pagerState = this.getDataBinding().getPagerState(); + if (pagerState != null) { + pagerState.setIsOffline(false); + this.getDataBinding().setPagerState(pagerState); + } - /* When being online for the first time, adapter is null. */ - RepositorySearchAdapter adapter = ((RepositorySearchAdapter) this.getDataBinding().recyclerviewRepositories.getAdapter()); - if (adapter == null) { - /* Needs to run on UiThread */ - requireActivity().runOnUiThread(() -> { - String queryString = getDataBinding().recyclerviewRepositories.getQueryString(); - if (queryString == null) { - QueryStringAdapter queryStringArrayAdapter = (QueryStringAdapter) getDataBinding().toolbarRepositories.spinnerQueryString.getAdapter(); - if (queryStringArrayAdapter != null && queryStringArrayAdapter.getCount() > 0) { - queryString = queryStringArrayAdapter.getItem(0).getValue(); - } + /* When being online for the first time, adapter is null. */ + RepositorySearchAdapter adapter = ((RepositorySearchAdapter) this.getDataBinding().recyclerviewRepositories.getAdapter()); + if (adapter == null) { + /* Needs to run on UiThread */ + requireActivity().runOnUiThread(() -> { + String queryString = getDataBinding().recyclerviewRepositories.getQueryString(); + if (queryString == null) { + QueryStringAdapter queryStringArrayAdapter = (QueryStringAdapter) getDataBinding().toolbarRepositories.spinnerQueryString.getAdapter(); + if (queryStringArrayAdapter != null && queryStringArrayAdapter.getCount() > 0) { + queryString = queryStringArrayAdapter.getItem(0).getValue(); } - if (queryString != null) { - getDataBinding().recyclerviewRepositories.setAdapter(new RepositorySearchAdapter(requireActivity(), queryString, showRepositoryTopics, 1)); - } - }); - } else if (adapter.getItemCount() == 0) { - /* If required, fetch page 1 */ - adapter.fetchPage(1); - } + } + if (queryString != null) { + getDataBinding().recyclerviewRepositories.setAdapter(new RepositorySearchAdapter(requireActivity(), queryString, showRepositoryTopics, 1)); + } + }); + } else if (adapter.getItemCount() == 0) { + /* If required, fetch page 1 */ + adapter.fetchPage(1); } } diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index 77fc694c..b15d1321 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -31,7 +31,7 @@ import io.syslogic.github.Constants; import io.syslogic.github.R; import io.syslogic.github.activity.BaseActivity; -import io.syslogic.github.databinding.CardviewWorkflowBinding; +import io.syslogic.github.databinding.CardviewRepositoryBinding; import io.syslogic.github.databinding.FragmentRepositoriesBinding; import io.syslogic.github.api.model.Repository; import io.syslogic.github.api.model.Workflow; @@ -63,8 +63,19 @@ public class RepositoriesAdapter extends RecyclerView.Adapter mContext; + /** This may add the account in debug mode and therefore must be called first. */ + private String accessToken = null; + + /** + * This only returns a value on the second attempt, because the account + * from which it gets the cached username is being added asynchronously). + */ + private String username = null; + public RepositoriesAdapter(@NonNull Context context) { this.mContext = new WeakReference<>(context); + this.getCredentials(); + this.fetchPage(1); } @Override @@ -76,7 +87,7 @@ public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - CardviewWorkflowBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.cardview_workflow, parent, false); + CardviewRepositoryBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.cardview_repository, parent, false); binding.getRoot().setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); return new RepositoriesAdapter.ViewHolder(binding); } @@ -84,24 +95,25 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { Repository item = getItem(position); - CardviewWorkflowBinding binding = ((ViewHolder) viewHolder).getDataBinding(); + CardviewRepositoryBinding binding = ((ViewHolder) viewHolder).getDataBinding(); binding.setItem(item); } - public void fetchPage(final int pageNumber) { + private boolean getCredentials() { - /* It may add the account and therefore must be called first */ - String accessToken = getAccessToken(); + /* This may add the account in debug mode and therefore must be called first. */ + this.accessToken = getAccessToken(); /* * This only returns a value on the second attempt, because the account * from which it gets the cached username is being added asynchronously). */ - String username = getUsername(); - if (username == null) { - // TODO: try again with a delay? - return; - } + this.username = getUsername(); + + return this.accessToken != null && this.username != null; + } + + public void fetchPage(final int pageNumber) { Call> api = GithubClient.getUserRepositories(accessToken, username,"owner", "full_name","desc", 100, pageNumber); if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api.request().url() + "");} @@ -118,39 +130,8 @@ public void onResponse(@NonNull Call> call, @NonNull Respo getItems().addAll(items); notifyItemRangeChanged(positionStart, getItemCount()); - for (Repository item : items) { - - Call api2 = GithubClient.getWorkflows(accessToken, username,item.getName()); - if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api2.request().url() + "");} - - api2.enqueue(new Callback<>() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.code() == 200) { // OK - if (response.body() != null) { - WorkflowsResponse items = response.body(); - if (BuildConfig.DEBUG) { - if (items.getWorkflows() != null && items.getWorkflows().size() > 0) { - for (Workflow item2 : items.getWorkflows()) { - Log.d(LOG_TAG, item.getName() + " has workflow: " + item2.getName()); - } - } - } - } - } else { - /* "bad credentials" means that the provided access-token is invalid. */ - if (response.errorBody() != null) { - logError(response.errorBody()); - } - } - } - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - if (BuildConfig.DEBUG) {Log.e(LOG_TAG, "onFailure: " + t.getMessage());} - } - }); - } + getWorkflows(); } } else { /* "bad credentials" means that the provided access-token is invalid. */ @@ -167,6 +148,42 @@ public void onFailure(@NonNull Call> call, @NonNull Throwa }); } + private void getWorkflows() { + for (Repository item : this.getItems()) { + + Call api2 = GithubClient.getWorkflows(accessToken, username,item.getName()); + if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api2.request().url() + "");} + + api2.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.code() == 200) { // OK + if (response.body() != null) { + WorkflowsResponse items = response.body(); + if (BuildConfig.DEBUG) { + if (items.getWorkflows() != null && items.getWorkflows().size() > 0) { + for (Workflow item2 : items.getWorkflows()) { + Log.d(LOG_TAG, item.getName() + " has workflow: " + item2.getName()); + } + } + } + } + } else { + /* "bad credentials" means that the provided access-token is invalid. */ + if (response.errorBody() != null) { + logError(response.errorBody()); + } + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + if (BuildConfig.DEBUG) {Log.e(LOG_TAG, "onFailure: " + t.getMessage());} + } + }); + } + } + /** Getters */ private Repository getItem(int index) { return this.mItems.get(index); @@ -222,13 +239,13 @@ void logError(@NonNull ResponseBody responseBody) { /** {@link RecyclerView.ViewHolder} for {@link CardView} of type {@link Workflow}. */ private static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - private final CardviewWorkflowBinding mDataBinding; + private final CardviewRepositoryBinding mDataBinding; /** * ViewHolder Constructor * @param binding the item's data-binding **/ - ViewHolder(@NonNull CardviewWorkflowBinding binding) { + ViewHolder(@NonNull CardviewRepositoryBinding binding) { super(binding.getRoot()); binding.cardview.setOnClickListener(this); this.mDataBinding = binding; @@ -250,7 +267,7 @@ public void onClick(@NonNull View viewHolder) { } /** Getters */ - CardviewWorkflowBinding getDataBinding() { + CardviewRepositoryBinding getDataBinding() { return this.mDataBinding; } } diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java index b2daacad..627a77a3 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java @@ -16,7 +16,7 @@ */ public class RepositoriesLinearView extends RecyclerView { - LinearLayoutManager mLinearLayoutManager; + ScrollListener scrollListener; /** Constructor */ public RepositoriesLinearView(@NonNull Context context) { @@ -26,8 +26,26 @@ public RepositoriesLinearView(@NonNull Context context) { /** Constructor */ public RepositoriesLinearView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); - this.mLinearLayoutManager = new LinearLayoutManager(this.getContext()); - this.setLayoutManager(this.mLinearLayoutManager); this.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL)); + LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext()); + this.setLayoutManager(layoutManager); + + this.scrollListener = new ScrollListener(layoutManager) { + @Override + public boolean onLoadPage(int pageNumber, int totalItemsCount) { + RepositoriesAdapter adapter = ((RepositoriesAdapter) getAdapter()); + if (adapter != null) { + adapter.fetchPage(pageNumber); + return true; + } + return false; + } + }; + this.addOnScrollListener(scrollListener); + } + + @NonNull + public ScrollListener getOnScrollListener() { + return this.scrollListener; } } diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchLinearView.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchLinearView.java index eda4affc..c9e03b5e 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchLinearView.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchLinearView.java @@ -5,6 +5,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -15,7 +16,6 @@ */ public class RepositorySearchLinearView extends RecyclerView { - LinearLayoutManager mLinearLayoutManager; ScrollListener scrollListener; /** Constructor */ @@ -25,13 +25,12 @@ public RepositorySearchLinearView(@NonNull Context context) { /** Constructor */ public RepositorySearchLinearView(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); + this.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL)); + LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext()); + this.setLayoutManager(layoutManager); - this.mLinearLayoutManager = new LinearLayoutManager(this.getContext()); - this.setLayoutManager(this.mLinearLayoutManager); - - this.scrollListener = new ScrollListener(this.mLinearLayoutManager) { + this.scrollListener = new ScrollListener(layoutManager) { @Override public boolean onLoadPage(int pageNumber, int totalItemsCount) { RepositorySearchAdapter adapter = ((RepositorySearchAdapter) getAdapter()); diff --git a/mobile/src/main/res/layout/cardview_workflow.xml b/mobile/src/main/res/layout/cardview_repository.xml similarity index 100% rename from mobile/src/main/res/layout/cardview_workflow.xml rename to mobile/src/main/res/layout/cardview_repository.xml diff --git a/mobile/src/main/res/layout/fragment_repositories.xml b/mobile/src/main/res/layout/fragment_repositories.xml index 0bdf9d1b..fba9023e 100644 --- a/mobile/src/main/res/layout/fragment_repositories.xml +++ b/mobile/src/main/res/layout/fragment_repositories.xml @@ -1,45 +1,49 @@ - + + + + - + android:layout_height="match_parent" + android:orientation="vertical"> - - - - - - + - + - + + +
diff --git a/mobile/src/main/res/layout/toolbar_repositories.xml b/mobile/src/main/res/layout/toolbar_repositories.xml index e66948e7..c2f64290 100644 --- a/mobile/src/main/res/layout/toolbar_repositories.xml +++ b/mobile/src/main/res/layout/toolbar_repositories.xml @@ -7,7 +7,7 @@ Date: Mon, 7 Aug 2023 07:16:28 +0200 Subject: [PATCH 023/163] imports optimized once. --- .../activity/AuthenticatorActivity.java | 2 +- .../github/activity/BaseActivity.java | 2 +- .../github/adapter/BaseArrayAdapter.java | 4 +- .../github/adapter/QueryStringAdapter.java | 6 +- .../github/adapter/StringArrayAdapter.java | 4 +- .../github/content/RepositorySyncAdapter.java | 6 +- .../github/dialog/ProgressDialogFragment.java | 2 +- .../github/fragment/BaseFragment.java | 12 +- .../github/fragment/HomeScreenFragment.java | 2 +- .../github/fragment/PreferencesFragment.java | 1 - .../github/fragment/ProfileFragment.java | 4 +- .../github/fragment/QueryStringFragment.java | 2 +- .../github/fragment/RepositoryFragment.java | 25 ++-- .../fragment/RepositorySearchFragment.java | 10 +- .../github/fragment/WorkflowFragment.java | 2 +- .../syslogic/github/network/TokenHelper.java | 4 +- .../recyclerview/QueryStringsAdapter.java | 8 +- .../recyclerview/RepositoriesAdapter.java | 110 +++++++++++++----- .../recyclerview/RepositorySearchAdapter.java | 38 +++--- 19 files changed, 147 insertions(+), 97 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/activity/AuthenticatorActivity.java b/mobile/src/main/java/io/syslogic/github/activity/AuthenticatorActivity.java index 720df3b0..425e6ab0 100644 --- a/mobile/src/main/java/io/syslogic/github/activity/AuthenticatorActivity.java +++ b/mobile/src/main/java/io/syslogic/github/activity/AuthenticatorActivity.java @@ -20,9 +20,9 @@ import io.syslogic.github.BuildConfig; import io.syslogic.github.R; -import io.syslogic.github.databinding.FragmentAccessTokenBinding; import io.syslogic.github.api.GithubClient; import io.syslogic.github.api.model.User; +import io.syslogic.github.databinding.FragmentAccessTokenBinding; import io.syslogic.github.network.TokenHelper; import okhttp3.ResponseBody; diff --git a/mobile/src/main/java/io/syslogic/github/activity/BaseActivity.java b/mobile/src/main/java/io/syslogic/github/activity/BaseActivity.java index 671507cb..dd127e74 100644 --- a/mobile/src/main/java/io/syslogic/github/activity/BaseActivity.java +++ b/mobile/src/main/java/io/syslogic/github/activity/BaseActivity.java @@ -2,8 +2,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.databinding.ViewDataBinding; import androidx.appcompat.app.AppCompatActivity; +import androidx.databinding.ViewDataBinding; import androidx.fragment.app.Fragment; import androidx.lifecycle.Lifecycle; import androidx.navigation.fragment.NavHostFragment; diff --git a/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java index 6738ae39..8a41584b 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java @@ -12,11 +12,11 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatTextView; -import io.syslogic.github.api.model.SpinnerItem; - import java.util.ArrayList; import java.util.List; +import io.syslogic.github.api.model.SpinnerItem; + /** * Array {@link BaseAdapter} * diff --git a/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java index c518f8b5..5cb374b2 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java @@ -6,13 +6,13 @@ import androidx.annotation.NonNull; -import io.syslogic.github.api.model.SpinnerItem; +import java.util.List; + import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.model.SpinnerItem; import io.syslogic.github.api.room.Abstraction; import io.syslogic.github.api.room.QueryStringsDao; -import java.util.List; - /** * Query-String {@link BaseArrayAdapter} * diff --git a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java index 3f1419d6..a43fc6bb 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java @@ -4,10 +4,10 @@ import androidx.annotation.NonNull; -import io.syslogic.github.api.model.SpinnerItem; - import java.util.ArrayList; +import io.syslogic.github.api.model.SpinnerItem; + /** * String[] {@link BaseArrayAdapter} * diff --git a/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java b/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java index e05cfa8c..93807339 100644 --- a/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java @@ -17,15 +17,15 @@ import io.syslogic.github.BuildConfig; import io.syslogic.github.Constants; +import io.syslogic.github.api.GithubClient; import io.syslogic.github.api.model.QueryString; -import io.syslogic.github.api.model.RepositorySearch; import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.model.RepositorySearch; import io.syslogic.github.api.model.User; -import io.syslogic.github.network.TokenHelper; -import io.syslogic.github.api.GithubClient; import io.syslogic.github.api.room.Abstraction; import io.syslogic.github.api.room.QueryStringsDao; import io.syslogic.github.api.room.RepositoriesDao; +import io.syslogic.github.network.TokenHelper; import retrofit2.Call; import retrofit2.Callback; diff --git a/mobile/src/main/java/io/syslogic/github/dialog/ProgressDialogFragment.java b/mobile/src/main/java/io/syslogic/github/dialog/ProgressDialogFragment.java index 286963b8..ae2a1764 100644 --- a/mobile/src/main/java/io/syslogic/github/dialog/ProgressDialogFragment.java +++ b/mobile/src/main/java/io/syslogic/github/dialog/ProgressDialogFragment.java @@ -15,8 +15,8 @@ import java.util.Locale; -import io.syslogic.github.databinding.DialogProgressBinding; import io.syslogic.github.R; +import io.syslogic.github.databinding.DialogProgressBinding; /** * Progress {@link BaseDialogFragment} diff --git a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java index 43e2999b..db8afed3 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java @@ -12,9 +12,6 @@ import android.util.Log; import android.widget.Toast; -import java.io.IOException; -import java.util.Objects; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; @@ -25,15 +22,18 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import java.io.IOException; +import java.util.Objects; + import io.syslogic.github.BuildConfig; -import io.syslogic.github.R; import io.syslogic.github.Constants; +import io.syslogic.github.R; +import io.syslogic.github.api.GithubClient; import io.syslogic.github.api.model.User; -import io.syslogic.github.network.ConnectivityReceiver; import io.syslogic.github.network.ConnectivityListener; +import io.syslogic.github.network.ConnectivityReceiver; import io.syslogic.github.network.TokenCallback; import io.syslogic.github.network.TokenHelper; -import io.syslogic.github.api.GithubClient; import retrofit2.Call; import retrofit2.Callback; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java index 0cb87076..d7ab8de3 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java @@ -13,8 +13,8 @@ import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; -import io.syslogic.github.databinding.FragmentHomeScreenBinding; import io.syslogic.github.api.model.User; +import io.syslogic.github.databinding.FragmentHomeScreenBinding; import io.syslogic.github.network.TokenCallback; import io.syslogic.github.provider.HomeScreenMenuProvider; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java index f099e84e..7afca9c4 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java @@ -29,7 +29,6 @@ import io.syslogic.github.BuildConfig; import io.syslogic.github.Constants; - import io.syslogic.github.R; import io.syslogic.github.network.TokenHelper; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java index 4b425131..a72987ff 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java @@ -14,10 +14,10 @@ import androidx.annotation.RequiresApi; import androidx.databinding.ViewDataBinding; -import io.syslogic.github.R; import io.syslogic.github.Constants; -import io.syslogic.github.databinding.FragmentProfileBinding; +import io.syslogic.github.R; import io.syslogic.github.api.model.User; +import io.syslogic.github.databinding.FragmentProfileBinding; import io.syslogic.github.network.TokenCallback; /** diff --git a/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java index 8afe2a3b..0a0e864f 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java @@ -16,9 +16,9 @@ import androidx.navigation.NavController; import androidx.navigation.Navigation; +import io.syslogic.github.Constants; import io.syslogic.github.R; import io.syslogic.github.activity.BaseActivity; -import io.syslogic.github.Constants; import io.syslogic.github.api.model.QueryString; import io.syslogic.github.api.room.Abstraction; import io.syslogic.github.api.room.QueryStringsDao; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java index 5ba54439..8bfe68bb 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java @@ -21,19 +21,14 @@ import android.widget.AdapterView; import android.widget.Toast; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - -import java.io.File; -import java.io.IOException; - -import java.util.ArrayList; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatSpinner; import androidx.databinding.ViewDataBinding; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; @@ -41,15 +36,19 @@ import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; -import io.syslogic.github.R; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + import io.syslogic.github.Constants; -import io.syslogic.github.databinding.FragmentRepositoryBinding; -import io.syslogic.github.dialog.ProgressDialogFragment; -import io.syslogic.github.api.model.User; -import io.syslogic.github.network.TokenCallback; +import io.syslogic.github.R; import io.syslogic.github.api.GithubClient; import io.syslogic.github.api.model.Branch; import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.model.User; +import io.syslogic.github.databinding.FragmentRepositoryBinding; +import io.syslogic.github.dialog.ProgressDialogFragment; +import io.syslogic.github.network.TokenCallback; import okhttp3.Headers; import okhttp3.ResponseBody; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index 9b4c41c9..54ab85e6 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -17,19 +17,19 @@ import io.syslogic.github.Constants; import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; -import io.syslogic.github.model.PagerState; +import io.syslogic.github.adapter.QueryStringAdapter; import io.syslogic.github.api.model.QueryString; import io.syslogic.github.api.model.SpinnerItem; -import io.syslogic.github.adapter.QueryStringAdapter; -import io.syslogic.github.databinding.FragmentRepositorySearchBinding; import io.syslogic.github.api.model.User; +import io.syslogic.github.api.room.Abstraction; +import io.syslogic.github.api.room.QueryStringsDao; +import io.syslogic.github.databinding.FragmentRepositorySearchBinding; +import io.syslogic.github.model.PagerState; import io.syslogic.github.network.TokenCallback; import io.syslogic.github.provider.RepositorySearchMenuProvider; import io.syslogic.github.recyclerview.RepositorySearchAdapter; import io.syslogic.github.recyclerview.RepositorySearchLinearView; import io.syslogic.github.recyclerview.ScrollListener; -import io.syslogic.github.api.room.Abstraction; -import io.syslogic.github.api.room.QueryStringsDao; /** * Repository Search {@link BaseFragment} diff --git a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java index 7088ee4b..c32eb3c0 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java @@ -14,8 +14,8 @@ import io.syslogic.github.Constants; import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; -import io.syslogic.github.databinding.FragmentWorkflowBinding; import io.syslogic.github.api.model.Workflow; +import io.syslogic.github.databinding.FragmentWorkflowBinding; import io.syslogic.github.provider.WorkflowMenuProvider; /** diff --git a/mobile/src/main/java/io/syslogic/github/network/TokenHelper.java b/mobile/src/main/java/io/syslogic/github/network/TokenHelper.java index cb8df7ae..b610b57f 100644 --- a/mobile/src/main/java/io/syslogic/github/network/TokenHelper.java +++ b/mobile/src/main/java/io/syslogic/github/network/TokenHelper.java @@ -18,8 +18,8 @@ import io.syslogic.github.BuildConfig; import io.syslogic.github.Constants; -import io.syslogic.github.api.model.User; import io.syslogic.github.api.GithubClient; +import io.syslogic.github.api.model.User; import okhttp3.ResponseBody; @@ -104,7 +104,7 @@ public void onResponse(@NonNull Call call, @NonNull Response respons Account account = addAccount(accountManager, item.getLogin(), finalToken); if (BuildConfig.DEBUG) { if (account != null) {Log.d(LOG_TAG, "account added");} - else {Log.d(LOG_TAG, "account not added");} + // else {Log.d(LOG_TAG, "account not added");} } } } else { diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsAdapter.java index c143576c..284ec717 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsAdapter.java @@ -6,9 +6,6 @@ import android.view.View; import android.view.ViewGroup; -import java.lang.ref.WeakReference; -import java.util.List; - import androidx.annotation.NonNull; import androidx.cardview.widget.CardView; import androidx.databinding.DataBindingUtil; @@ -17,10 +14,13 @@ import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; +import java.lang.ref.WeakReference; +import java.util.List; + import io.syslogic.github.BuildConfig; +import io.syslogic.github.Constants; import io.syslogic.github.R; import io.syslogic.github.activity.BaseActivity; -import io.syslogic.github.Constants; import io.syslogic.github.api.model.QueryString; import io.syslogic.github.api.room.Abstraction; import io.syslogic.github.databinding.CardviewQueryStringBinding; diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index b15d1321..354c0b25 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -31,13 +31,14 @@ import io.syslogic.github.Constants; import io.syslogic.github.R; import io.syslogic.github.activity.BaseActivity; -import io.syslogic.github.databinding.CardviewRepositoryBinding; -import io.syslogic.github.databinding.FragmentRepositoriesBinding; +import io.syslogic.github.api.GithubClient; import io.syslogic.github.api.model.Repository; import io.syslogic.github.api.model.Workflow; import io.syslogic.github.api.model.WorkflowsResponse; +import io.syslogic.github.databinding.CardviewRepositoryBinding; +import io.syslogic.github.databinding.FragmentRepositoriesBinding; +import io.syslogic.github.model.PagerState; import io.syslogic.github.network.TokenHelper; -import io.syslogic.github.api.GithubClient; import okhttp3.ResponseBody; @@ -63,6 +64,10 @@ public class RepositoriesAdapter extends RecyclerView.Adapter mContext; + private RecyclerView mRecyclerView; + + private long totalItemCount = 0; + /** This may add the account in debug mode and therefore must be called first. */ private String accessToken = null; @@ -82,6 +87,7 @@ public RepositoriesAdapter(@NonNull Context context) { public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); this.mContext = new WeakReference<>(recyclerView.getContext()); + this.mRecyclerView = recyclerView; } @NonNull @@ -115,44 +121,56 @@ private boolean getCredentials() { public void fetchPage(final int pageNumber) { - Call> api = GithubClient.getUserRepositories(accessToken, username,"owner", "full_name","desc", 100, pageNumber); - if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api.request().url() + "");} + if (this.getPagerState() != null && !this.getPagerState().getIsOffline()) { - api.enqueue(new Callback<>() { - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { - int positionStart = getItemCount(); - if (response.code() == 200) { // OK - if (response.body() != null) { + /* Updating the pager data-binding */ + this.setPagerState(pageNumber, true, null); - /* Updating the adapter with the initial response already. */ - ArrayList items = response.body(); - getItems().addAll(items); - notifyItemRangeChanged(positionStart, getItemCount()); + Call> api = GithubClient.getUserRepositories(accessToken, username, "owner", "full_name", "desc", 100, pageNumber); + if (BuildConfig.DEBUG) { + Log.w(LOG_TAG, api.request().url() + ""); + } + api.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + int positionStart = getItemCount(); + if (response.code() == 200) { // OK + if (response.body() != null) { - getWorkflows(); - } - } else { - /* "bad credentials" means that the provided access-token is invalid. */ - if (response.errorBody() != null) { - logError(response.errorBody()); + /* Updating the adapter with the initial response already. */ + ArrayList items = response.body(); + getItems().addAll(items); + notifyItemRangeChanged(positionStart, getItemCount()); + + /* Updating the pager data-binding */ + setPagerState(pageNumber, false, (long) getItems().size()); + + getWorkflows(); + } + } else { + /* "bad credentials" means that the provided access-token is invalid. */ + if (response.errorBody() != null) { + logError(response.errorBody()); + } } } - } - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - if (BuildConfig.DEBUG) {Log.e(LOG_TAG, "" + t.getMessage());} - } - }); + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + if (BuildConfig.DEBUG) { + Log.e(LOG_TAG, "" + t.getMessage()); + } + } + }); + } } private void getWorkflows() { for (Repository item : this.getItems()) { Call api2 = GithubClient.getWorkflows(accessToken, username,item.getName()); - if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api2.request().url() + "");} + // if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api2.request().url() + "");} api2.enqueue(new Callback<>() { @Override @@ -220,6 +238,42 @@ private String getAccessToken() { } } + void clearItems() { + this.mItems.clear(); + notifyItemRangeChanged(0, getItemCount()); + } + + /** Reset the scroll listener. */ + protected void resetOnScrollListener() { + if (this.mRecyclerView.getAdapter() != null) { + ScrollListener listener = ((RepositorySearchLinearView) this.mRecyclerView).getOnScrollListener(); + listener.setIsLoading(false); + } + } + + @Nullable + protected PagerState getPagerState() { + if (((BaseActivity) getContext()).getFragmentDataBinding() instanceof FragmentRepositoriesBinding databinding) { + return databinding.getPagerState(); + } + return null; + } + + protected void setPagerState(int pageNumber, boolean isLoading, @Nullable Long itemCount) { + if (this.getPagerState() != null) { + PagerState state = this.getPagerState(); + state.setIsLoading(isLoading); + state.setPageNumber(pageNumber); + if (itemCount != null) { + state.setPageCount((int) Math.ceil((float) itemCount / state.getItemsPerPage())); + state.setItemCount(itemCount); + } + FragmentRepositoriesBinding databinding = (FragmentRepositoriesBinding) ((BaseActivity) getContext()).getFragmentDataBinding(); + if (databinding != null) {databinding.setPagerState(state);} + } + } + + @NonNull protected Context getContext() { return this.mContext.get(); diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java index 51cc9ad8..68d68071 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositorySearchAdapter.java @@ -14,6 +14,15 @@ import android.view.ViewGroup; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.cardview.widget.CardView; +import androidx.databinding.DataBindingUtil; +import androidx.fragment.app.FragmentTransaction; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.recyclerview.widget.RecyclerView; + import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -24,38 +33,27 @@ import java.util.List; import java.util.Locale; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.cardview.widget.CardView; -import androidx.databinding.DataBindingUtil; -import androidx.fragment.app.FragmentTransaction; -import androidx.navigation.NavController; -import androidx.navigation.Navigation; -import androidx.recyclerview.widget.RecyclerView; - -import io.syslogic.github.R; import io.syslogic.github.BuildConfig; -import io.syslogic.github.activity.BaseActivity; import io.syslogic.github.Constants; -import io.syslogic.github.databinding.CardviewRepositorySearchBinding; -import io.syslogic.github.databinding.FragmentRepositorySearchBinding; -import io.syslogic.github.fragment.RepositoryFragment; - +import io.syslogic.github.R; +import io.syslogic.github.activity.BaseActivity; +import io.syslogic.github.api.GithubClient; import io.syslogic.github.api.model.RateLimit; import io.syslogic.github.api.model.RateLimits; -import io.syslogic.github.api.model.RepositorySearch; import io.syslogic.github.api.model.Repository; -import io.syslogic.github.api.GithubClient; - +import io.syslogic.github.api.model.RepositorySearch; +import io.syslogic.github.databinding.CardviewRepositorySearchBinding; +import io.syslogic.github.databinding.FragmentRepositorySearchBinding; +import io.syslogic.github.fragment.RepositoryFragment; import io.syslogic.github.model.PagerState; +import io.syslogic.github.network.TokenHelper; + import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; -import io.syslogic.github.network.TokenHelper; - /** * Repository Search {@link RecyclerView.Adapter} * From 5f215885a90760007b3986491dbd83f0dbebbb29 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 7 Aug 2023 07:25:39 +0200 Subject: [PATCH 024/163] the pager-state merely reflects the adapter, except that the total count is unknown unless loaded. --- .../syslogic/github/recyclerview/RepositoriesAdapter.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index 354c0b25..13eebe95 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -76,6 +76,7 @@ public class RepositoriesAdapter extends RecyclerView.Adapter(context); @@ -125,8 +126,9 @@ public void fetchPage(final int pageNumber) { /* Updating the pager data-binding */ this.setPagerState(pageNumber, true, null); + this.getPagerState().setItemsPerPage(this.pageSize); - Call> api = GithubClient.getUserRepositories(accessToken, username, "owner", "full_name", "desc", 100, pageNumber); + Call> api = GithubClient.getUserRepositories(accessToken, username, "owner", "full_name", "desc", this.pageSize, pageNumber); if (BuildConfig.DEBUG) { Log.w(LOG_TAG, api.request().url() + ""); } @@ -246,7 +248,7 @@ void clearItems() { /** Reset the scroll listener. */ protected void resetOnScrollListener() { if (this.mRecyclerView.getAdapter() != null) { - ScrollListener listener = ((RepositorySearchLinearView) this.mRecyclerView).getOnScrollListener(); + ScrollListener listener = ((RepositoriesLinearView) this.mRecyclerView).getOnScrollListener(); listener.setIsLoading(false); } } From 92224733584552817115f1d502fbc117435367ac Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 7 Aug 2023 07:55:05 +0200 Subject: [PATCH 025/163] sync-adapter should cache the own repositories. --- .../github/content/RepositorySyncAdapter.java | 118 ++++++++---------- 1 file changed, 53 insertions(+), 65 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java b/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java index 93807339..a20d6f0c 100644 --- a/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java @@ -12,21 +12,22 @@ import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import java.io.IOException; import java.util.ArrayList; -import java.util.List; import io.syslogic.github.BuildConfig; import io.syslogic.github.Constants; import io.syslogic.github.api.GithubClient; -import io.syslogic.github.api.model.QueryString; import io.syslogic.github.api.model.Repository; -import io.syslogic.github.api.model.RepositorySearch; -import io.syslogic.github.api.model.User; import io.syslogic.github.api.room.Abstraction; -import io.syslogic.github.api.room.QueryStringsDao; import io.syslogic.github.api.room.RepositoriesDao; import io.syslogic.github.network.TokenHelper; +import okhttp3.ResponseBody; + import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -42,27 +43,21 @@ public class RepositorySyncAdapter extends AbstractThreadedSyncAdapter { @NonNull private static final String LOG_TAG = RepositorySyncAdapter.class.getSimpleName(); - /** Debug Output */ - static final boolean mDebug = BuildConfig.DEBUG; + private final SharedPreferences prefs; - final QueryStringsDao queryStringsDao; - final RepositoriesDao repositoriesDao; + private final RepositoriesDao dao; private final String accessToken; - private final SharedPreferences prefs; - private ArrayList repositories = new ArrayList<>(); + private final String username; /** Constructor. */ public RepositorySyncAdapter(@NonNull Context context, boolean autoInitialize, boolean allowParallelSyncs) { super(context, autoInitialize, allowParallelSyncs); - this.accessToken = TokenHelper.getAccessToken(context); this.prefs = PreferenceManager.getDefaultSharedPreferences(context); - this.repositoriesDao = Abstraction.getInstance(context).repositoriesDao(); - this.queryStringsDao = Abstraction.getInstance(context).queryStringsDao(); - if (mDebug && this.prefs.getBoolean(Constants.PREFERENCE_KEY_DEBUG_LOGGING, false)) { - Log.d(LOG_TAG, "Verbose logging is active."); - } + this.dao = Abstraction.getInstance(context).repositoriesDao(); + this.accessToken = TokenHelper.getAccessToken(context); + this.username = TokenHelper.getUsername(context); } /** @@ -77,64 +72,57 @@ public RepositorySyncAdapter(@NonNull Context context, boolean autoInitialize, b */ @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { - if (this.accessToken != null) { - Call api = GithubClient.getUser(this.accessToken); - this.log("" + api.request().url()); - api.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.body() != null) { - onUser(response.body()); - Abstraction.executorService.execute(() -> { - assert queryStringsDao != null; - onQueryStrings(queryStringsDao.getItems()); - }); - } - } - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - if (mDebug) {Log.e(LOG_TAG, "" + t.getMessage());} - } - }); - } - } + if (this.accessToken != null && this.username != null) { - void onUser(@NonNull User item) { - this.log("onUser: " + item.getLogin()); - } + int pageNumber = 1; + int pageSize = 100; + + Call> api = GithubClient.getUserRepositories(accessToken, username, "owner", "full_name", "desc", pageSize, pageNumber); + if (BuildConfig.DEBUG && this.prefs.getBoolean(Constants.PREFERENCE_KEY_DEBUG_LOGGING, false)) { + Log.d(LOG_TAG, api.request().url() + ""); + } - void onQueryStrings(@NonNull List items) { - this.log("onQueryStrings: " + items.size()); - for (QueryString item: items) { - Call api = GithubClient.searchRepositories(this.accessToken, item.toQueryString(), "forks", "desc", 1); - this.log("Building content cache for query-string: " + item.toQueryString()); - this.log("" + api.request().url()); - api.enqueue(new Callback() { + api.enqueue(new Callback<>() { @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.body() != null) {onRepositories(response.body());} + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + if (response.code() == 200) { // OK + if (response.body() != null) { + + /* Updating the adapter with the initial response already. */ + ArrayList items = response.body(); + for (Repository item : items) { + Abstraction.executorService.execute(() -> { + + }); + } + } + } else { + /* "bad credentials" means that the provided access-token is invalid. */ + if (response.errorBody() != null) { + logError(response.errorBody()); + } + } } + @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - if (mDebug) {Log.e(LOG_TAG, "" + t.getMessage());} + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + if (BuildConfig.DEBUG) { + Log.e(LOG_TAG, "" + t.getMessage()); + } } }); } } - void onRepositories(@NonNull RepositorySearch item) { - this.log("onRepositories: " + item.getRepositories().size()); - for (Repository repository: item.getRepositories()) { - this.log("Repo: " + repository.getUrl()); - this.repositories.add(repository); - } - this.log("expected item count: " + item.getTotalCount()); - this.log("expected page count: " + item.getPageCount()); - this.log("loaded so far: " + this.repositories.size()); - } - - void log(String message) { - if (mDebug && this.prefs.getBoolean(Constants.PREFERENCE_KEY_DEBUG_LOGGING, false)) { - Log.d(LOG_TAG, message); + void logError(@NonNull ResponseBody responseBody) { + if (BuildConfig.DEBUG && this.prefs.getBoolean(Constants.PREFERENCE_KEY_DEBUG_LOGGING, false)) { + try { + String errors = responseBody.string(); + JsonObject jsonObject = JsonParser.parseString(errors).getAsJsonObject(); + Log.e(LOG_TAG, jsonObject.get("message").toString()); + } catch (IOException e) { + Log.e(LOG_TAG, "" + e.getMessage()); + } } } } \ No newline at end of file From 68cef0c842a4d35cea7a0475556e54eb620b26fd Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 7 Aug 2023 07:55:29 +0200 Subject: [PATCH 026/163] preference ID fixed. --- mobile/src/main/java/io/syslogic/github/Constants.java | 2 +- .../io/syslogic/github/fragment/PreferencesFragment.java | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/Constants.java b/mobile/src/main/java/io/syslogic/github/Constants.java index 02e3595e..83b70276 100644 --- a/mobile/src/main/java/io/syslogic/github/Constants.java +++ b/mobile/src/main/java/io/syslogic/github/Constants.java @@ -30,7 +30,7 @@ public final class Constants { @NonNull public static final Integer RECYCLERVIEW_DEFAULT_PAGE_SIZE = 30; /** Preference Keys */ - @NonNull public static final String PREFERENCE_KEY_PERSONAL_ACCESS_TOKEN = "personal_access_token"; + @NonNull public static final String PREFERENCE_KEY_ACCOUNT_SETTINGS = "account_settings"; @NonNull public static final String PREFERENCE_KEY_WORKSPACE_DIRECTORY = "workspace_directory"; @NonNull public static final String PREFERENCE_KEY_SHOW_REPOSITORY_TOPICS = "show_repository_topics"; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java index 7afca9c4..84f28dda 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java @@ -76,13 +76,11 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S this.setPreferencesFromResource(resId, rootKey); /* Preference: Account Manager */ - Preference pref = this.findPreference(Constants.PREFERENCE_KEY_PERSONAL_ACCESS_TOKEN); + Preference pref = this.findPreference(Constants.PREFERENCE_KEY_ACCOUNT_SETTINGS); if (pref != null) { String accessToken = TokenHelper.getAccessToken(requireContext()); - if (accessToken != null) { - pref.setSummary(R.string.summary_personal_access_token); - } + if (accessToken != null) {pref.setSummary(R.string.summary_personal_access_token);} pref.setOnPreferenceClickListener(preference -> { Intent intent = new Intent(); From b54a585f95099b599b283659c693d5174ad025e4 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 7 Aug 2023 08:18:24 +0200 Subject: [PATCH 027/163] sync-adapter should cache the own repositories. --- .../github/api/room/QueryStringsDao.java | 4 +- .../github/api/room/RepositoriesDao.java | 4 +- mobile/src/main/AndroidManifest.xml | 1 + .../github/content/QueryStringProvider.java | 39 ++++++++++++------- .../github/content/RepositoryProvider.java | 39 ++++++++++++------- .../github/fragment/PreferencesFragment.java | 12 +++--- .../recyclerview/RepositoriesAdapter.java | 18 +++++++-- 7 files changed, 78 insertions(+), 39 deletions(-) diff --git a/library/src/main/java/io/syslogic/github/api/room/QueryStringsDao.java b/library/src/main/java/io/syslogic/github/api/room/QueryStringsDao.java index d4ff1b7b..7abe2c0e 100644 --- a/library/src/main/java/io/syslogic/github/api/room/QueryStringsDao.java +++ b/library/src/main/java/io/syslogic/github/api/room/QueryStringsDao.java @@ -35,13 +35,13 @@ public interface QueryStringsDao { Long insert(QueryString item); @Update() - void update(QueryString item); + int update(QueryString item); @Delete() void delete(QueryString item); @Query("DELETE FROM " + Constants.TABLE_QUERY_STRINGS + " WHERE id = :itemId") - void deleteById(Long itemId); + int deleteById(Long itemId); @Query("DELETE FROM " + Constants.TABLE_QUERY_STRINGS) void clear(); diff --git a/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java b/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java index 2c047af1..fef3d197 100644 --- a/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java +++ b/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java @@ -34,13 +34,13 @@ public interface RepositoriesDao { Long insert(Repository item); @Update() - void update(Repository item); + int update(Repository item); @Delete() void delete(Repository item); @Query("DELETE FROM " + Constants.TABLE_REPOSITORIES + " WHERE id = :itemId") - void deleteById(Long itemId); + int deleteById(Long itemId); @Query("DELETE FROM " + Constants.TABLE_REPOSITORIES) void clear(); diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml index b0cc6f55..de5d866b 100644 --- a/mobile/src/main/AndroidManifest.xml +++ b/mobile/src/main/AndroidManifest.xml @@ -29,6 +29,7 @@ android:allowBackup="false" android:supportsRtl="true" tools:ignore="DataExtractionRules" + tools:remove="android:appComponentFactory" tools:targetApi="s"> 0) { + return dao.deleteById(Long.valueOf(selectionArgs[0])); + } else { + return 0; + } } - public int update(@NonNull Uri uri, @NonNull ContentValues values, @NonNull String selectionClause, @NonNull String[] selectionArgs) { - QueryString item = new QueryString().fromContentValues(values); - dao.update(item); - return 1; + public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selectionClause, @Nullable String[] selectionArgs) { + if (values != null) { + QueryString item = new QueryString().fromContentValues(values); + return dao.update(item); + } else { + return 0; + } } } \ No newline at end of file diff --git a/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java b/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java index 90beaf5b..45ddf3a6 100644 --- a/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java +++ b/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java @@ -7,6 +7,7 @@ import android.net.Uri; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import io.syslogic.github.api.model.Repository; import io.syslogic.github.api.room.Abstraction; @@ -23,7 +24,9 @@ public class RepositoryProvider extends ContentProvider { @Override public boolean onCreate() { - this.dao = Abstraction.getInstance(getContext()).repositoriesDao(); + if (getContext() != null) { + this.dao = Abstraction.getInstance(getContext()).repositoriesDao(); + } return true; } @@ -34,27 +37,37 @@ public String getType(@NonNull Uri uri) { @NonNull @Override - public Cursor query(@NonNull Uri uri, @NonNull String[] projection, @NonNull String selectionClause, @NonNull String[] selectionArgs, @NonNull String sortOrder) { + public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selectionClause, @Nullable String[] selectionArgs, @Nullable String sortOrder) { return dao.selectAll(); } @NonNull @Override - public Uri insert(@NonNull Uri uri, @NonNull ContentValues values) { - Repository item = new Repository().fromContentValues(values); - long id = dao.insert(item); - return ContentUris.withAppendedId(uri, id); + public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { + if (values != null) { + Repository item = new Repository().fromContentValues(values); + long id = dao.insert(item); + return ContentUris.withAppendedId(uri, id); + } else { + return uri; + } } @Override - public int delete(@NonNull Uri uri, @NonNull String selectionClause, @NonNull String[] selectionArgs) { - dao.deleteById(Long.valueOf(selectionArgs[0])); - return 1; + public int delete(@NonNull Uri uri, @Nullable String selectionClause, @Nullable String[] selectionArgs) { + if (selectionArgs != null && selectionArgs.length > 0) { + return dao.deleteById(Long.valueOf(selectionArgs[0])); + } else { + return 0; + } } - public int update(@NonNull Uri uri, @NonNull ContentValues values, @NonNull String selectionClause, @NonNull String[] selectionArgs) { - Repository item = new Repository().fromContentValues(values); - dao.update(item); - return 1; + public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selectionClause, @Nullable String[] selectionArgs) { + if (values != null) { + Repository item = new Repository().fromContentValues(values); + return dao.update(item); + } else { + return 0; + } } } \ No newline at end of file diff --git a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java index 84f28dda..2669850d 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java @@ -83,20 +83,22 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S if (accessToken != null) {pref.setSummary(R.string.summary_personal_access_token);} pref.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[] {Constants.ACCOUNT_TYPE}); + // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (accessToken != null) { + // intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {Constants.ACCOUNT_TYPE}); intent.setAction(Settings.ACTION_SYNC_SETTINGS); } else { + intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[] {Constants.ACCOUNT_TYPE}); intent.setAction(Settings.ACTION_ADD_ACCOUNT); } try { requireActivity().startActivityFromFragment(this, intent, 100); return true; } catch (ActivityNotFoundException e) { - Log.e(LOG_TAG, e.getMessage()); + Log.e(LOG_TAG, "" + e.getMessage()); return false; } }); @@ -152,7 +154,7 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S * a {@code null} value when preferences are cleared. */ @Override - public void onSharedPreferenceChanged(@NonNull SharedPreferences preferences, @NonNull String key) { + public void onSharedPreferenceChanged(@NonNull SharedPreferences preferences, @Nullable String key) { if (mDebug) {Log.d(LOG_TAG, "onSharedPreferenceChanged " + key);} } @@ -166,7 +168,7 @@ private void chooseDirectory() { try { requestFileChooserResult.launch(intent); } catch (ActivityNotFoundException e) { - Log.e(LOG_TAG, e.getMessage()); + Log.e(LOG_TAG, "" + e.getMessage()); } } diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index 13eebe95..d345bcc0 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -76,7 +76,8 @@ public class RepositoriesAdapter extends RecyclerView.Adapter(context); @@ -129,9 +130,7 @@ public void fetchPage(final int pageNumber) { this.getPagerState().setItemsPerPage(this.pageSize); Call> api = GithubClient.getUserRepositories(accessToken, username, "owner", "full_name", "desc", this.pageSize, pageNumber); - if (BuildConfig.DEBUG) { - Log.w(LOG_TAG, api.request().url() + ""); - } + if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api.request().url() + "");} api.enqueue(new Callback<>() { @Override @@ -281,6 +280,17 @@ protected Context getContext() { return this.mContext.get(); } + /** Setters */ + void setTotalItemCount(long value) { + this.totalItemCount = value; + } + + /** Getters */ + @SuppressWarnings("unused") + private long getTotalItemCount() { + return this.totalItemCount; + } + void logError(@NonNull ResponseBody responseBody) { try { String errors = responseBody.string(); From d35275c4199fd8f9bc74d18937fcdbbcd89e210d Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 7 Aug 2023 08:45:35 +0200 Subject: [PATCH 028/163] sync seems to work, so far. --- .../github/api/room/RepositoriesDao.java | 3 + .../github/content/RepositorySyncAdapter.java | 74 +++++++++++-------- .../fragment/RepositorySearchFragment.java | 50 +++++++------ 3 files changed, 74 insertions(+), 53 deletions(-) diff --git a/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java b/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java index fef3d197..009920a5 100644 --- a/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java +++ b/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java @@ -30,6 +30,9 @@ public interface RepositoriesDao { @Query("SELECT * FROM " + Constants.TABLE_REPOSITORIES) Cursor selectAll(); + @Query("SELECT * FROM " + Constants.TABLE_REPOSITORIES + " WHERE id LIKE :itemId LIMIT 1") + Repository getItem(Long itemId); + @Insert() Long insert(Repository item); diff --git a/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java b/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java index a20d6f0c..3c4190ca 100644 --- a/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/content/RepositorySyncAdapter.java @@ -51,6 +51,12 @@ public class RepositorySyncAdapter extends AbstractThreadedSyncAdapter { private final String username; + boolean hasRecords = true; + + int pageSize = 100; + + int pageNumber = 1; + /** Constructor. */ public RepositorySyncAdapter(@NonNull Context context, boolean autoInitialize, boolean allowParallelSyncs) { super(context, autoInitialize, allowParallelSyncs); @@ -74,43 +80,51 @@ public RepositorySyncAdapter(@NonNull Context context, boolean autoInitialize, b public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { if (this.accessToken != null && this.username != null) { - int pageNumber = 1; - int pageSize = 100; + while (hasRecords) { - Call> api = GithubClient.getUserRepositories(accessToken, username, "owner", "full_name", "desc", pageSize, pageNumber); - if (BuildConfig.DEBUG && this.prefs.getBoolean(Constants.PREFERENCE_KEY_DEBUG_LOGGING, false)) { - Log.d(LOG_TAG, api.request().url() + ""); - } - - api.enqueue(new Callback<>() { - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { - if (response.code() == 200) { // OK - if (response.body() != null) { - - /* Updating the adapter with the initial response already. */ - ArrayList items = response.body(); - for (Repository item : items) { - Abstraction.executorService.execute(() -> { + Call> api = GithubClient.getUserRepositories(accessToken, username, "owner", "full_name", "desc", pageSize, pageNumber); + if (BuildConfig.DEBUG && this.prefs.getBoolean(Constants.PREFERENCE_KEY_DEBUG_LOGGING, false)) { + Log.d(LOG_TAG, api.request().url() + ""); + } - }); + api.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + if (response.code() == 200) { // OK + if (response.body() != null) { + + ArrayList items = response.body(); + if (items.size() == pageSize) {pageNumber++;} + else {hasRecords = false;} + + for (Repository item : items) { + Abstraction.executorService.execute(() -> { + assert dao != null; + if (dao.getItem(item.getId()) == null) { + dao.insert(item); + } else { + dao.update(item); + } + }); + } + } + } else { + /* "bad credentials" means that the provided access-token is invalid. */ + if (response.errorBody() != null) { + logError(response.errorBody()); + hasRecords = false; } - } - } else { - /* "bad credentials" means that the provided access-token is invalid. */ - if (response.errorBody() != null) { - logError(response.errorBody()); } } - } - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - if (BuildConfig.DEBUG) { - Log.e(LOG_TAG, "" + t.getMessage()); + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + if (BuildConfig.DEBUG) { + Log.e(LOG_TAG, "" + t.getMessage()); + } } - } - }); + }); + } } } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index 54ab85e6..b2db9fdc 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -155,31 +155,35 @@ public void onNetworkAvailable() { this.setUser(token, this); } - PagerState pagerState = this.getDataBinding().getPagerState(); - if (pagerState != null) { - pagerState.setIsOffline(false); - this.getDataBinding().setPagerState(pagerState); - } + //noinspection ConstantValue + if (this.getDataBinding() != null) { + + PagerState pagerState = this.getDataBinding().getPagerState(); + if (pagerState != null) { + pagerState.setIsOffline(false); + this.getDataBinding().setPagerState(pagerState); + } - /* When being online for the first time, adapter is null. */ - RepositorySearchAdapter adapter = ((RepositorySearchAdapter) this.getDataBinding().recyclerviewRepositories.getAdapter()); - if (adapter == null) { - /* Needs to run on UiThread */ - requireActivity().runOnUiThread(() -> { - String queryString = getDataBinding().recyclerviewRepositories.getQueryString(); - if (queryString == null) { - QueryStringAdapter queryStringArrayAdapter = (QueryStringAdapter) getDataBinding().toolbarRepositories.spinnerQueryString.getAdapter(); - if (queryStringArrayAdapter != null && queryStringArrayAdapter.getCount() > 0) { - queryString = queryStringArrayAdapter.getItem(0).getValue(); + /* When being online for the first time, adapter is null. */ + RepositorySearchAdapter adapter = ((RepositorySearchAdapter) this.getDataBinding().recyclerviewRepositories.getAdapter()); + if (adapter == null) { + /* Needs to run on UiThread */ + requireActivity().runOnUiThread(() -> { + String queryString = getDataBinding().recyclerviewRepositories.getQueryString(); + if (queryString == null) { + QueryStringAdapter queryStringArrayAdapter = (QueryStringAdapter) getDataBinding().toolbarRepositories.spinnerQueryString.getAdapter(); + if (queryStringArrayAdapter != null && queryStringArrayAdapter.getCount() > 0) { + queryString = queryStringArrayAdapter.getItem(0).getValue(); + } } - } - if (queryString != null) { - getDataBinding().recyclerviewRepositories.setAdapter(new RepositorySearchAdapter(requireActivity(), queryString, showRepositoryTopics, 1)); - } - }); - } else if (adapter.getItemCount() == 0) { - /* If required, fetch page 1 */ - adapter.fetchPage(1); + if (queryString != null) { + getDataBinding().recyclerviewRepositories.setAdapter(new RepositorySearchAdapter(requireActivity(), queryString, showRepositoryTopics, 1)); + } + }); + } else if (adapter.getItemCount() == 0) { + /* If required, fetch page 1 */ + adapter.fetchPage(1); + } } } From 4740bee7e4a3b2e1bf170322c3d0cf0f11aead2e Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 7 Aug 2023 11:53:14 +0200 Subject: [PATCH 029/163] content-provider fixed. --- .../github/api/room/RepositoriesDao.java | 5 +- mobile/src/main/AndroidManifest.xml | 7 -- .../java/io/syslogic/github/Constants.java | 12 --- .../github/content/QueryStringProvider.java | 73 ------------------- .../github/content/RepositoryProvider.java | 35 ++++++++- .../github/fragment/PreferencesFragment.java | 10 +-- .../fragment/RepositorySearchFragment.java | 2 +- .../recyclerview/RepositoriesAdapter.java | 5 +- 8 files changed, 47 insertions(+), 102 deletions(-) delete mode 100644 mobile/src/main/java/io/syslogic/github/content/QueryStringProvider.java diff --git a/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java b/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java index 009920a5..40953b32 100644 --- a/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java +++ b/library/src/main/java/io/syslogic/github/api/room/RepositoriesDao.java @@ -26,10 +26,13 @@ public interface RepositoriesDao { List getItems(); /* For ContentProvider */ - // @Transaction @Query("SELECT * FROM " + Constants.TABLE_REPOSITORIES) Cursor selectAll(); + /* For ContentProvider */ + @Query("SELECT * FROM " + Constants.TABLE_REPOSITORIES + " WHERE id LIKE :itemId LIMIT 1") + Cursor getCursor(Long itemId); + @Query("SELECT * FROM " + Constants.TABLE_REPOSITORIES + " WHERE id LIKE :itemId LIMIT 1") Repository getItem(Long itemId); diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml index de5d866b..5332cd70 100644 --- a/mobile/src/main/AndroidManifest.xml +++ b/mobile/src/main/AndroidManifest.xml @@ -79,13 +79,6 @@ android:resource="@xml/account_authenticator"/> - - 0) { - return dao.deleteById(Long.valueOf(selectionArgs[0])); - } else { - return 0; - } - } - - public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selectionClause, @Nullable String[] selectionArgs) { - if (values != null) { - QueryString item = new QueryString().fromContentValues(values); - return dao.update(item); - } else { - return 0; - } - } -} \ No newline at end of file diff --git a/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java b/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java index 45ddf3a6..1f987cf5 100644 --- a/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java +++ b/mobile/src/main/java/io/syslogic/github/content/RepositoryProvider.java @@ -3,12 +3,16 @@ import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; +import android.content.UriMatcher; import android.database.Cursor; import android.net.Uri; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import java.util.Objects; + +import io.syslogic.github.Constants; import io.syslogic.github.api.model.Repository; import io.syslogic.github.api.room.Abstraction; import io.syslogic.github.api.room.RepositoriesDao; @@ -21,6 +25,12 @@ public class RepositoryProvider extends ContentProvider { private RepositoriesDao dao; + private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + + static { + uriMatcher.addURI(Constants.ACCOUNT_TYPE + ".content.RepositoryProvider", "repositories", 1); + uriMatcher.addURI(Constants.ACCOUNT_TYPE + ".content.RepositoryProvider", "repositories/#", 2); + } @Override public boolean onCreate() { @@ -38,7 +48,30 @@ public String getType(@NonNull Uri uri) { @NonNull @Override public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selectionClause, @Nullable String[] selectionArgs, @Nullable String sortOrder) { - return dao.selectAll(); + /* + * Choose the table to query and a sort order based on the code returned for the incoming + * URI. Here, too, only the statements for table 3 are shown. + */ + switch (uriMatcher.match(uri)) { + + + // If the incoming URI was for all of table3 + case 1 -> { + return dao.selectAll(); + } + + // If the incoming URI was for a single row + case 2 -> { + + /* + * Because this URI was for a single row, the _ID value part is + * present. Get the last path segment from the URI; this is the _ID value. + * Then, append the value to the WHERE clause for the query. + */ + return dao.getCursor(Long.valueOf(Objects.requireNonNull(uri.getLastPathSegment()))); + } + default -> throw new IllegalArgumentException("uriMatcher.match must be 1 or 2"); + } } @NonNull diff --git a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java index 2669850d..54589474 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java @@ -83,15 +83,15 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S if (accessToken != null) {pref.setSummary(R.string.summary_personal_access_token);} pref.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(); - // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (accessToken != null) { - // intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {Constants.ACCOUNT_TYPE}); + String[] authorities = {Constants.ACCOUNT_TYPE + ".content.RepositoryProvider"}; + intent.putExtra(Settings.EXTRA_AUTHORITIES, authorities); intent.setAction(Settings.ACTION_SYNC_SETTINGS); } else { - intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[] {Constants.ACCOUNT_TYPE}); + String[] accountTypes = new String[] {Constants.ACCOUNT_TYPE}; + intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, accountTypes); intent.setAction(Settings.ACTION_ADD_ACCOUNT); } try { diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index b2db9fdc..628b46e7 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -118,7 +118,7 @@ public void onNothingSelected(AdapterView parent) {} } }); } else { - if (mDebug) {Log.e(LOG_TAG, "table `" + Constants.TABLE_QUERY_STRINGS +"` has no records.");} + if (mDebug) {Log.e(LOG_TAG, "table `query_strings` has no records.");} this.getDataBinding().toolbarRepositories.spinnerQueryString.setVisibility(View.INVISIBLE); } } catch (IllegalStateException e) { diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index d345bcc0..3cd16b63 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -81,8 +81,9 @@ public class RepositoriesAdapter extends RecyclerView.Adapter(context); - this.getCredentials(); - this.fetchPage(1); + if (this.getCredentials()) { + this.fetchPage(1); + } } @Override From 4b24c5015c8e5aeecf4370b7de0eac7599fb177f Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 00:02:06 +0200 Subject: [PATCH 030/163] more javavdoc comments added. --- .../github/fragment/BaseFragment.java | 3 +- .../github/fragment/HomeScreenFragment.java | 6 +-- .../github/fragment/PreferencesFragment.java | 39 ++++++++++++------- .../github/fragment/ProfileFragment.java | 9 ++--- .../github/fragment/QueryStringFragment.java | 6 +-- .../github/fragment/QueryStringsFragment.java | 6 +-- .../github/fragment/RepositoriesFragment.java | 9 ++--- .../github/fragment/RepositoryFragment.java | 3 +- .../fragment/RepositorySearchFragment.java | 3 +- .../github/fragment/WorkflowFragment.java | 9 ++--- mobile/src/main/res/values/strings.xml | 1 + 11 files changed, 52 insertions(+), 42 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java index db8afed3..695e36a7 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/BaseFragment.java @@ -53,7 +53,6 @@ abstract public class BaseFragment extends Fragment implements ConnectivityListe static final boolean mDebug = BuildConfig.DEBUG; @Nullable User currentUser = null; - @Nullable SharedPreferences prefs; @NonNull Boolean contentLoaded = false; @@ -225,7 +224,7 @@ public void onResponse(@NonNull Call call, @NonNull Response respons @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - if (mDebug) {Log.e(LOG_TAG, t.getMessage());} + if (mDebug) {Log.e(LOG_TAG, "" + t.getMessage());} } }); } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java index d7ab8de3..40dbeb1c 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java @@ -29,10 +29,10 @@ public class HomeScreenFragment extends BaseFragment implements TokenCallback { @SuppressWarnings("unused") private static final String LOG_TAG = HomeScreenFragment.class.getSimpleName(); - @SuppressWarnings("unused") - private static final int resId = R.layout.fragment_home_screen; + /** Layout resource ID kept for reference. */ + @SuppressWarnings("unused") private static final int resId = R.layout.fragment_home_screen; - /** Data Binding */ + /** Data-Binding */ private FragmentHomeScreenBinding mDataBinding; /** Constructor */ diff --git a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java index 54589474..3251a931 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java @@ -26,6 +26,7 @@ import androidx.preference.PreferenceScreen; import java.io.File; +import java.util.Objects; import io.syslogic.github.BuildConfig; import io.syslogic.github.Constants; @@ -43,9 +44,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat /** Log Tag */ private static final String LOG_TAG = PreferencesFragment.class.getSimpleName(); - /** Debug Output */ - static final boolean mDebug = BuildConfig.DEBUG; - + /** Layout resource ID. */ private static final int resId = R.xml.preferences_general; /** {@link SharedPreferences} */ @@ -54,7 +53,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat /** Constructor */ public PreferencesFragment() {} - /** Called when a fragment is first attached to its context. */ + /** Called when the fragment is first attached to its context. */ @Override public void onAttach(@NonNull Context context) { super.onAttach(context); @@ -62,6 +61,15 @@ public void onAttach(@NonNull Context context) { this.prefs.registerOnSharedPreferenceChangeListener(this); } + /** Called when the fragment is being detached from its context. */ + @Override + public void onDetach() { + super.onDetach(); + if (this.prefs != null) { + this.prefs.unregisterOnSharedPreferenceChangeListener(this); + } + } + /** * Called during {@link #onCreate(Bundle)} to supply the preferences for this fragment. * Subclasses are expected to call {@link #setPreferenceScreen(PreferenceScreen)} either @@ -78,18 +86,21 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S /* Preference: Account Manager */ Preference pref = this.findPreference(Constants.PREFERENCE_KEY_ACCOUNT_SETTINGS); if (pref != null) { - String accessToken = TokenHelper.getAccessToken(requireContext()); - if (accessToken != null) {pref.setSummary(R.string.summary_personal_access_token);} - + //if (accessToken != null) {pref.setSummary(R.string.summary_personal_access_token_alt);} pref.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + /* Depending whether there is an access token... */ if (accessToken != null) { + /* It will either open the sync-settings. */ String[] authorities = {Constants.ACCOUNT_TYPE + ".content.RepositoryProvider"}; intent.putExtra(Settings.EXTRA_AUTHORITIES, authorities); intent.setAction(Settings.ACTION_SYNC_SETTINGS); } else { + /* Or it will add an account. */ String[] accountTypes = new String[] {Constants.ACCOUNT_TYPE}; intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, accountTypes); intent.setAction(Settings.ACTION_ADD_ACCOUNT); @@ -98,7 +109,7 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S requireActivity().startActivityFromFragment(this, intent, 100); return true; } catch (ActivityNotFoundException e) { - Log.e(LOG_TAG, "" + e.getMessage()); + if (BuildConfig.DEBUG) {Log.e(LOG_TAG, "" + e.getMessage());} return false; } }); @@ -115,9 +126,9 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S if (! defaultDir.mkdir()) { /* Try internal storage instead */ - Log.w(LOG_TAG, "workspace not created: " + defaultDir.getAbsolutePath()); - defaultDir = new File(requireContext().getExternalFilesDir(null).toURI()); - Log.d(LOG_TAG, "workspace using internal storage: " + defaultDir.getAbsolutePath()); + if (BuildConfig.DEBUG) {Log.w(LOG_TAG, "workspace not created: " + defaultDir.getAbsolutePath());} + defaultDir = new File(Objects.requireNonNull(requireContext().getExternalFilesDir(null)).toURI()); + if (BuildConfig.DEBUG) {Log.d(LOG_TAG, "workspace using internal storage: " + defaultDir.getAbsolutePath());} } } if (! directory.equals(defaultDir.getAbsolutePath())) { @@ -155,7 +166,7 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S */ @Override public void onSharedPreferenceChanged(@NonNull SharedPreferences preferences, @Nullable String key) { - if (mDebug) {Log.d(LOG_TAG, "onSharedPreferenceChanged " + key);} + if (BuildConfig.DEBUG) {Log.d(LOG_TAG, "onSharedPreferenceChanged " + key);} } private void chooseDirectory() { @@ -172,7 +183,7 @@ private void chooseDirectory() { } } - /** Register the permissions callback. */ + /** Register the permission-request callback. */ final ActivityResultLauncher requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { if (isGranted) { @@ -184,6 +195,7 @@ private void chooseDirectory() { final ActivityResultLauncher requestFileChooserResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { + // There are no request codes Intent data = result.getData(); @@ -191,5 +203,4 @@ private void chooseDirectory() { } }); - } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java index a72987ff..644f790f 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/ProfileFragment.java @@ -28,13 +28,12 @@ public class ProfileFragment extends BaseFragment implements TokenCallback { /** Log Tag */ - @SuppressWarnings("unused") - private static final String LOG_TAG = ProfileFragment.class.getSimpleName(); + @SuppressWarnings("unused") private static final String LOG_TAG = ProfileFragment.class.getSimpleName(); - @SuppressWarnings("unused") - private static final int resId = R.layout.fragment_profile; + /** Layout resource ID kept for reference. */ + @SuppressWarnings("unused") private static final int resId = R.layout.fragment_profile; - /** Data Binding */ + /** Data-Binding */ private FragmentProfileBinding mDataBinding; private Long itemId = -1L; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java index 0a0e864f..fc4cdfcc 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/QueryStringFragment.java @@ -39,12 +39,12 @@ public class QueryStringFragment extends BaseFragment { /** Log Tag */ - @SuppressWarnings("unused") - private static final String LOG_TAG = QueryStringFragment.class.getSimpleName(); + @SuppressWarnings("unused") private static final String LOG_TAG = QueryStringFragment.class.getSimpleName(); + /** Layout resource ID kept for reference. */ @SuppressWarnings("unused") private static final int resId = R.layout.fragment_query_string; - /** Data Binding */ + /** Data-Binding */ private FragmentQueryStringBinding mDataBinding; private Long itemId = -1L; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/QueryStringsFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/QueryStringsFragment.java index 7f76fb5d..b70305b5 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/QueryStringsFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/QueryStringsFragment.java @@ -26,12 +26,12 @@ public class QueryStringsFragment extends BaseFragment { /** Log Tag */ - @SuppressWarnings("unused") - private static final String LOG_TAG = QueryStringsFragment.class.getSimpleName(); + @SuppressWarnings("unused") private static final String LOG_TAG = QueryStringsFragment.class.getSimpleName(); + /** Layout resource ID kept for reference. */ @SuppressWarnings("unused") private static final int resId = R.layout.fragment_query_strings; - /** Data Binding */ + /** Data-Binding */ private FragmentQueryStringsBinding mDataBinding; /** Constructor */ diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java index 7c504c9f..4e08578d 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java @@ -26,13 +26,12 @@ public class RepositoriesFragment extends BaseFragment implements TokenCallback { /** Log Tag */ - @SuppressWarnings("unused") - private static final String LOG_TAG = RepositoriesFragment.class.getSimpleName(); + @SuppressWarnings("unused") private static final String LOG_TAG = RepositoriesFragment.class.getSimpleName(); - @SuppressWarnings("unused") - private static final int resId = R.layout.fragment_repositories; + /** Layout resource ID kept for reference. */ + @SuppressWarnings("unused") private static final int resId = R.layout.fragment_repositories; - /** Data Binding */ + /** Data-Binding */ private FragmentRepositoriesBinding mDataBinding; /** Constructor */ diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java index 8bfe68bb..33b2c378 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java @@ -68,9 +68,10 @@ public class RepositoryFragment extends BaseFragment implements TokenCallback { @SuppressWarnings("unused") private static final String LOG_TAG = RepositoryFragment.class.getSimpleName(); + /** Layout resource ID kept for reference. */ @SuppressWarnings("unused") private static final int resId = R.layout.fragment_repository; - /** Data Binding */ + /** Data-Binding */ FragmentRepositoryBinding mDataBinding; ProgressDialogFragment currentDialog; Long itemId = 0L; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index 628b46e7..8953a752 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -42,9 +42,10 @@ public class RepositorySearchFragment extends BaseFragment implements TokenCallb @SuppressWarnings("unused") private static final String LOG_TAG = RepositorySearchFragment.class.getSimpleName(); + /** Layout resource ID kept for reference. */ @SuppressWarnings("unused") private static final int resId = R.layout.fragment_repository_search; - /** Data Binding */ + /** Data-Binding */ private FragmentRepositorySearchBinding mDataBinding; /** Preference: PREFERENCE_KEY_SHOW_REPOSITORY_TOPICS */ diff --git a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java index c32eb3c0..d362ae05 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java @@ -26,13 +26,12 @@ public class WorkflowFragment extends BaseFragment { /** Log Tag */ - @SuppressWarnings("unused") - private static final String LOG_TAG = WorkflowFragment.class.getSimpleName(); + @SuppressWarnings("unused") private static final String LOG_TAG = WorkflowFragment.class.getSimpleName(); - @SuppressWarnings("unused") - private static final int resId = R.layout.fragment_workflow; + /** Layout resource ID kept for reference. */ + @SuppressWarnings("unused") private static final int resId = R.layout.fragment_workflow; - /** Data Binding */ + /** Data-Binding */ private FragmentWorkflowBinding mDataBinding; private Long itemId = -1L; diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index 54bde9c9..9d688685 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -18,6 +18,7 @@ Personal Access Token Open Android Account Manager + Open the Sync Settings Local Workspace Directory @null From 147ac6b744496aeab3bf5c7bf69ea2c221ccaf6e Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 00:05:18 +0200 Subject: [PATCH 031/163] readme updated. --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b5a7086c..1366791c 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,16 @@ When file `token.properties` is absent, the personal access token still can be a ![Repositories](screenshots/repositories_30.png?raw=true&sanitize=true "Repositories") - -[![](https://jitci.com/gh/syslogic/androidx-github/svg)](https://jitci.com/gh/syslogic/androidx-github) [![Release](https://jitpack.io/v/syslogic/androidx-github.svg)](https://jitpack.io/#io.syslogic/androidx-github) -[![MIT License](https://img.shields.io/github/license/syslogic/androidx-github)](https://github.com/syslogic/androidx-github/blob/master/LICENSE) - --- -The library is also available on JitPack; either by version tag or `master-SNAPSHOT`.
+The library module is available on JitPack; either by version tag or `master-SNAPSHOT`.
The JitPack repository URL would be: `maven { url 'https://jitpack.io' }` dependencies { implementation "io.syslogic:androidx-github:1.0.0" } + + --- + +[![Release](https://jitpack.io/v/syslogic/androidx-github.svg)](https://jitpack.io/#io.syslogic/androidx-github) +[![MIT License](https://img.shields.io/github/license/syslogic/androidx-github)](https://github.com/syslogic/androidx-github/blob/master/LICENSE) From 836b4a937bd0fa995ba7fbd077ece7cadb3232db Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 00:23:22 +0200 Subject: [PATCH 032/163] readme updated. --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1366791c..b27d3da0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ ## androidx-github This is an unofficial Android client for GitHub, which utilizes the AndroidX & Retrofit2 libraries.
-By default one can browse Android/Kotlin/Gradle projects, but it also features an editor for bookmarks. +- by default, one can browse Android/Kotlin/Gradle projects, but it also features an editor for bookmarks. +- one can also browse the own repositories and workflows (work in progress). +- it even features rudimentary git support (check out only, so far). ### Client Setup @@ -15,7 +17,7 @@ When file `token.properties` is absent, the personal access token still can be a --- -The library module is available on JitPack; either by version tag or `master-SNAPSHOT`.
+The `:library` module is available on JitPack; either by version tag or `master-SNAPSHOT`.
The JitPack repository URL would be: `maven { url 'https://jitpack.io' }` dependencies { From 30cd5269dff19bbbedf48dc6bcca541fbe91fd92 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 00:27:41 +0200 Subject: [PATCH 033/163] readme updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b27d3da0..b3e745c8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is an unofficial Android client for GitHub, which utilizes the AndroidX & Retrofit2 libraries.
- by default, one can browse Android/Kotlin/Gradle projects, but it also features an editor for bookmarks. - one can also browse the own repositories and workflows (work in progress). -- it even features rudimentary git support (check out only, so far). +- it generally supports git operations (check out only, so far), see [jgit](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/6.2.0.202206071550-r/org.eclipse.jgit/module-summary.html). ### Client Setup From 14ab4a107de0fa6085990392ad5d76a6bb884711 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 00:36:15 +0200 Subject: [PATCH 034/163] readme updated. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b3e745c8..31497eaf 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ This is an unofficial Android client for GitHub, which utilizes the AndroidX & R - one can also browse the own repositories and workflows (work in progress). - it generally supports git operations (check out only, so far), see [jgit](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/6.2.0.202206071550-r/org.eclipse.jgit/module-summary.html). -### Client Setup +### Debug Builds File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`.
-without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession.
+Without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession.
When file `token.properties` is absent, the personal access token still can be added in the preferences. ### Screenshots From 96231238bec57dbddd3d95d6516abdff6da551e4 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:32:13 +0200 Subject: [PATCH 035/163] some code refactoring, combo for repository-type added. --- .../github/adapter/StringArrayAdapter.java | 11 +--- .../github/fragment/HomeScreenFragment.java | 5 +- .../github/fragment/PreferencesFragment.java | 11 ++-- .../github/fragment/RepositoriesFragment.java | 49 +++++++++++++++++- .../fragment/RepositorySearchFragment.java | 22 ++++---- .../recyclerview/RepositoriesAdapter.java | 51 +++++++++++++++---- .../recyclerview/RepositoriesLinearView.java | 22 ++++++++ .../github/recyclerview/TopicsAdapter.java | 15 +++--- .../fragment_repository_search.xml | 4 +- .../main/res/layout/fragment_home_screen.xml | 4 +- .../main/res/layout/fragment_repositories.xml | 13 ++++- .../res/layout/fragment_repository_search.xml | 6 +-- .../main/res/layout/toolbar_repositories.xml | 50 ++++++++++++------ .../res/layout/toolbar_repository_search.xml | 4 +- mobile/src/main/res/values/strings.xml | 5 +- 15 files changed, 200 insertions(+), 72 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java index a43fc6bb..1cd1ab23 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java @@ -14,16 +14,9 @@ * @author Martin Zeitler */ public class StringArrayAdapter extends BaseArrayAdapter { - - ArrayList mItems; - - public StringArrayAdapter(@NonNull Context context) { + public StringArrayAdapter(@NonNull Context context, @NonNull String[] array) { super(context); - } - - void setItems(@NonNull Context context, @NonNull String[] array) { - this.clearItems(); - for(int i = 0; i < array.length; i++) { + for (int i = 0; i < array.length; i++) { this.mItems.add(i, new SpinnerItem(i + 1, array[i], array[i])); } } diff --git a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java index 40dbeb1c..d5c19159 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/HomeScreenFragment.java @@ -26,8 +26,7 @@ public class HomeScreenFragment extends BaseFragment implements TokenCallback { /** Log Tag */ - @SuppressWarnings("unused") - private static final String LOG_TAG = HomeScreenFragment.class.getSimpleName(); + @SuppressWarnings("unused") private static final String LOG_TAG = HomeScreenFragment.class.getSimpleName(); /** Layout resource ID kept for reference. */ @SuppressWarnings("unused") private static final int resId = R.layout.fragment_home_screen; @@ -59,7 +58,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } /* Navigating to RepositoriesFragment */ - this.mDataBinding.buttonRepositories + this.mDataBinding.buttonUserRepositories .setOnClickListener(view -> activity.getNavController() .navigate(R.id.action_homeScreenFragment_to_repositoriesFragment)); diff --git a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java index 3251a931..18038617 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/PreferencesFragment.java @@ -44,6 +44,9 @@ public class PreferencesFragment extends PreferenceFragmentCompat /** Log Tag */ private static final String LOG_TAG = PreferencesFragment.class.getSimpleName(); + /** Debug Output */ + static final boolean mDebug = BuildConfig.DEBUG; + /** Layout resource ID. */ private static final int resId = R.xml.preferences_general; @@ -109,7 +112,7 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S requireActivity().startActivityFromFragment(this, intent, 100); return true; } catch (ActivityNotFoundException e) { - if (BuildConfig.DEBUG) {Log.e(LOG_TAG, "" + e.getMessage());} + if (mDebug) {Log.e(LOG_TAG, "" + e.getMessage());} return false; } }); @@ -126,9 +129,9 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S if (! defaultDir.mkdir()) { /* Try internal storage instead */ - if (BuildConfig.DEBUG) {Log.w(LOG_TAG, "workspace not created: " + defaultDir.getAbsolutePath());} + if (mDebug) {Log.w(LOG_TAG, "workspace not created: " + defaultDir.getAbsolutePath());} defaultDir = new File(Objects.requireNonNull(requireContext().getExternalFilesDir(null)).toURI()); - if (BuildConfig.DEBUG) {Log.d(LOG_TAG, "workspace using internal storage: " + defaultDir.getAbsolutePath());} + if (mDebug) {Log.d(LOG_TAG, "workspace using internal storage: " + defaultDir.getAbsolutePath());} } } if (! directory.equals(defaultDir.getAbsolutePath())) { @@ -166,7 +169,7 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S */ @Override public void onSharedPreferenceChanged(@NonNull SharedPreferences preferences, @Nullable String key) { - if (BuildConfig.DEBUG) {Log.d(LOG_TAG, "onSharedPreferenceChanged " + key);} + if (mDebug) {Log.d(LOG_TAG, "onSharedPreferenceChanged " + key);} } private void chooseDirectory() { diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java index 4e08578d..8d5c74a2 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java @@ -4,23 +4,29 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatSpinner; import androidx.databinding.ViewDataBinding; import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; +import io.syslogic.github.adapter.StringArrayAdapter; +import io.syslogic.github.api.model.SpinnerItem; import io.syslogic.github.api.model.User; import io.syslogic.github.databinding.FragmentRepositoriesBinding; import io.syslogic.github.model.PagerState; import io.syslogic.github.network.TokenCallback; import io.syslogic.github.provider.RepositoriesMenuProvider; import io.syslogic.github.recyclerview.RepositoriesAdapter; +import io.syslogic.github.recyclerview.RepositoriesLinearView; +import io.syslogic.github.recyclerview.ScrollListener; /** * Repositories {@link BaseFragment} - * + * @see List repositories for a user * @author Martin Zeitler */ public class RepositoriesFragment extends BaseFragment implements TokenCallback { @@ -34,6 +40,15 @@ public class RepositoriesFragment extends BaseFragment implements TokenCallback /** Data-Binding */ private FragmentRepositoriesBinding mDataBinding; + /** Default: `owner`. */ + String[] repositoryTypes = new String[] {"all", "owner", "member"}; + + /** Default: `full_name`. */ + String[] sortFields = new String[] {"created", "updated", "pushed", "full_name"}; + + /** Default: `asc` when using `full_name`, otherwise `desc`. */ + String[] sortOrders = new String[] {"asc", "desc"}; + /** Constructor */ public RepositoriesFragment() {} @@ -51,6 +66,38 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c activity.setSupportActionBar(this.getDataBinding().toolbarRepositories.toolbarRepositories); this.mDataBinding.toolbarRepositories.home.setOnClickListener(view -> activity.onBackPressed()); + AppCompatSpinner spinner = this.getDataBinding().toolbarRepositories.spinnerRepositoryType; + spinner.setAdapter(new StringArrayAdapter(requireContext(), this.repositoryTypes)); + spinner.setSelection(1); + + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + int count = 0; + @Override + public void onItemSelected(AdapterView parent, View view, int position, long resId) { + if (count > 0) { + SpinnerItem item = (SpinnerItem) view.getTag(); + ScrollListener.setPageNumber(1); + String repositoryType = item.getValue(); + RepositoriesLinearView recyclerview = getDataBinding().recyclerviewRepositories; + recyclerview.setRepositoryType(repositoryType); + + PagerState pagerState = getDataBinding().getPagerState(); + if (pagerState != null) { + pagerState.setQueryString(repositoryType); + getDataBinding().setPagerState(pagerState); + } + if (recyclerview.getAdapter() != null) { + recyclerview.clearAdapter(); + ((RepositoriesAdapter) recyclerview.getAdapter()).fetchPage(1); + } + } + count++; + } + @Override + public void onNothingSelected(AdapterView parent) {} + }); + + if (! isNetworkAvailable(this.requireContext())) { this.onNetworkLost(); } else { diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index 8953a752..a85adec9 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -66,10 +66,10 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c activity.setMenuProvider(new RepositorySearchMenuProvider(activity)); /* the SpinnerItem has the same ID as the QueryString. */ - activity.setSupportActionBar(this.getDataBinding().toolbarRepositories.toolbarRepositories); - this.mDataBinding.toolbarRepositories.home.setOnClickListener(view -> activity.onBackPressed()); + activity.setSupportActionBar(this.getDataBinding().toolbarRepositorySearch.toolbarRepositorySearch); + this.mDataBinding.toolbarRepositorySearch.home.setOnClickListener(view -> activity.onBackPressed()); - AppCompatSpinner spinner = this.getDataBinding().toolbarRepositories.spinnerQueryString; + AppCompatSpinner spinner = this.getDataBinding().toolbarRepositorySearch.spinnerQueryString; spinner.setAdapter(new QueryStringAdapter(requireContext())); spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { int count = 0; @@ -79,7 +79,7 @@ public void onItemSelected(AdapterView parent, View view, int position, long SpinnerItem item = (SpinnerItem) view.getTag(); ScrollListener.setPageNumber(1); String queryString = item.getValue(); - RepositorySearchLinearView recyclerview = getDataBinding().recyclerviewRepositories; + RepositorySearchLinearView recyclerview = getDataBinding().recyclerviewRepositorySearch; recyclerview.setQueryString(queryString); PagerState pagerState = getDataBinding().getPagerState(); if (pagerState != null) { @@ -100,7 +100,7 @@ public void onNothingSelected(AdapterView parent) {} /* It is quicker to query Room, because the QueryStringAdapter is populating too slow. */ assert this.prefs != null; showRepositoryTopics = this.prefs.getBoolean(Constants.PREFERENCE_KEY_SHOW_REPOSITORY_TOPICS, false); - if (this.getDataBinding().recyclerviewRepositories.getAdapter() == null) { + if (this.getDataBinding().recyclerviewRepositorySearch.getAdapter() == null) { if (isNetworkAvailable(requireContext())) { QueryStringsDao dao = Abstraction.getInstance(requireContext()).queryStringsDao(); Abstraction.executorService.execute(() -> { @@ -111,7 +111,7 @@ public void onNothingSelected(AdapterView parent) {} String queryString = items.get(0).toQueryString(); requireActivity().runOnUiThread(() -> { RepositorySearchAdapter adapter = new RepositorySearchAdapter(requireContext(), queryString, showRepositoryTopics, 1); - getDataBinding().recyclerviewRepositories.setAdapter(adapter); + getDataBinding().recyclerviewRepositorySearch.setAdapter(adapter); PagerState pagerState = getDataBinding().getPagerState(); if (pagerState != null) { pagerState.setQueryString(queryString); @@ -120,7 +120,7 @@ public void onNothingSelected(AdapterView parent) {} }); } else { if (mDebug) {Log.e(LOG_TAG, "table `query_strings` has no records.");} - this.getDataBinding().toolbarRepositories.spinnerQueryString.setVisibility(View.INVISIBLE); + this.getDataBinding().toolbarRepositorySearch.spinnerQueryString.setVisibility(View.INVISIBLE); } } catch (IllegalStateException e) { if (mDebug) {Log.e(LOG_TAG, "" + e.getMessage());} @@ -166,19 +166,19 @@ public void onNetworkAvailable() { } /* When being online for the first time, adapter is null. */ - RepositorySearchAdapter adapter = ((RepositorySearchAdapter) this.getDataBinding().recyclerviewRepositories.getAdapter()); + RepositorySearchAdapter adapter = ((RepositorySearchAdapter) this.getDataBinding().recyclerviewRepositorySearch.getAdapter()); if (adapter == null) { /* Needs to run on UiThread */ requireActivity().runOnUiThread(() -> { - String queryString = getDataBinding().recyclerviewRepositories.getQueryString(); + String queryString = getDataBinding().recyclerviewRepositorySearch.getQueryString(); if (queryString == null) { - QueryStringAdapter queryStringArrayAdapter = (QueryStringAdapter) getDataBinding().toolbarRepositories.spinnerQueryString.getAdapter(); + QueryStringAdapter queryStringArrayAdapter = (QueryStringAdapter) getDataBinding().toolbarRepositorySearch.spinnerQueryString.getAdapter(); if (queryStringArrayAdapter != null && queryStringArrayAdapter.getCount() > 0) { queryString = queryStringArrayAdapter.getItem(0).getValue(); } } if (queryString != null) { - getDataBinding().recyclerviewRepositories.setAdapter(new RepositorySearchAdapter(requireActivity(), queryString, showRepositoryTopics, 1)); + getDataBinding().recyclerviewRepositorySearch.setAdapter(new RepositorySearchAdapter(requireActivity(), queryString, showRepositoryTopics, 1)); } }); } else if (adapter.getItemCount() == 0) { diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index 3cd16b63..f1c9ad99 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -66,8 +66,6 @@ public class RepositoriesAdapter extends RecyclerView.Adapter> api = GithubClient.getUserRepositories(accessToken, username, "owner", "full_name", "desc", this.pageSize, pageNumber); + Call> api = GithubClient.getUserRepositories(this.accessToken, this.username, this.repositoryType, this.sortField, this.sortOrder, this.pageSize, pageNumber); if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api.request().url() + "");} api.enqueue(new Callback<>() { @@ -275,23 +277,54 @@ protected void setPagerState(int pageNumber, boolean isLoading, @Nullable Long i } } - - @NonNull - protected Context getContext() { - return this.mContext.get(); - } - /** Setters */ + public void setRepositoryType(String value) { + this.repositoryType = value; + } + @SuppressWarnings("unused") + public void setSortField(String value) { + this.sortField = value; + } + @SuppressWarnings("unused") + public void setSortOrder(String value) { + this.sortOrder = value; + } + @SuppressWarnings("unused") + public void setPageSize(int value) { + if (value <= 0 || value > 100) {return;} + this.pageSize = value; + } + @SuppressWarnings("unused") void setTotalItemCount(long value) { this.totalItemCount = value; } /** Getters */ + public String getRepositoryType() { + return this.repositoryType; + } + @SuppressWarnings("unused") + public String getSortField() { + return this.sortField; + } + @SuppressWarnings("unused") + public String getSortOrder() { + return this.sortOrder; + } + @SuppressWarnings("unused") + public int getPageSize() { + return this.pageSize; + } @SuppressWarnings("unused") private long getTotalItemCount() { return this.totalItemCount; } + @NonNull + protected Context getContext() { + return this.mContext.get(); + } + void logError(@NonNull ResponseBody responseBody) { try { String errors = responseBody.string(); diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java index 627a77a3..2cedbe24 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java @@ -1,5 +1,6 @@ package io.syslogic.github.recyclerview; +import android.annotation.SuppressLint; import android.content.Context; import android.util.AttributeSet; @@ -44,6 +45,27 @@ public boolean onLoadPage(int pageNumber, int totalItemsCount) { this.addOnScrollListener(scrollListener); } + @SuppressLint("NotifyDataSetChanged") + public void clearAdapter() { + RepositoriesAdapter adapter = ((RepositoriesAdapter) getAdapter()); + if (adapter != null) { + adapter.clearItems(); + adapter.notifyDataSetChanged(); + } + } + + public void setRepositoryType(@NonNull String value) { + RepositoriesAdapter adapter = ((RepositoriesAdapter) getAdapter()); + if (adapter != null) {adapter.setRepositoryType(value);} + } + + @Nullable + public String getRepositoryType() { + RepositoriesAdapter adapter = ((RepositoriesAdapter) getAdapter()); + if (adapter == null) {return null;} + return adapter.getRepositoryType(); + } + @NonNull public ScrollListener getOnScrollListener() { return this.scrollListener; diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/TopicsAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/TopicsAdapter.java index 82eee42a..d93deba0 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/TopicsAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/TopicsAdapter.java @@ -83,20 +83,19 @@ public void onClick(@NonNull View viewHolder) { /* Set the query-string on the adapter and reload it. */ if (databinding != null) { ScrollListener.setPageNumber(1); - String queryString = "topic:" + item; - databinding.recyclerviewRepositories.setQueryString(queryString); - PagerState pagerState = databinding.getPagerState(); if (pagerState != null) { pagerState.setQueryString(queryString); databinding.setPagerState(pagerState); } - databinding.toolbarRepositories.spinnerQueryString.setVisibility(View.INVISIBLE); - databinding.toolbarRepositories.textCurrentTopic.setText(activity.getString(R.string.text_current_topic, item)); - if (databinding.recyclerviewRepositories.getAdapter() != null) { - databinding.recyclerviewRepositories.clearAdapter(); - ((RepositorySearchAdapter) databinding.recyclerviewRepositories.getAdapter()).fetchPage(1); + databinding.toolbarRepositorySearch.spinnerQueryString.setVisibility(View.INVISIBLE); + databinding.toolbarRepositorySearch.textCurrentTopic.setText(activity.getString(R.string.text_current_topic, item)); + + databinding.recyclerviewRepositorySearch.setQueryString(queryString); + if (databinding.recyclerviewRepositorySearch.getAdapter() != null) { + databinding.recyclerviewRepositorySearch.clearAdapter(); + ((RepositorySearchAdapter) databinding.recyclerviewRepositorySearch.getAdapter()).fetchPage(1); } } } diff --git a/mobile/src/main/res/layout-land/fragment_repository_search.xml b/mobile/src/main/res/layout-land/fragment_repository_search.xml index a778f656..36957fc5 100644 --- a/mobile/src/main/res/layout-land/fragment_repository_search.xml +++ b/mobile/src/main/res/layout-land/fragment_repository_search.xml @@ -47,7 +47,7 @@ @@ -61,7 +61,7 @@ android:padding="0dp"/> + android:text="@string/button_user_repositories"/>
diff --git a/mobile/src/main/res/layout/fragment_repositories.xml b/mobile/src/main/res/layout/fragment_repositories.xml index fba9023e..b506e46b 100644 --- a/mobile/src/main/res/layout/fragment_repositories.xml +++ b/mobile/src/main/res/layout/fragment_repositories.xml @@ -18,8 +18,19 @@ android:orientation="vertical"> + android:layout_width="match_parent" + android:layout_height="?android:attr/actionBarSize" + android:layout_margin="0dp"/> + + @@ -41,7 +41,7 @@ android:visibility="gone"/> - - + app:contentInsetStart="0dp"> + + + + + + + + + + diff --git a/mobile/src/main/res/layout/toolbar_repository_search.xml b/mobile/src/main/res/layout/toolbar_repository_search.xml index 9777ffad..13866899 100644 --- a/mobile/src/main/res/layout/toolbar_repository_search.xml +++ b/mobile/src/main/res/layout/toolbar_repository_search.xml @@ -7,7 +7,7 @@ Please sponsor this project on GitHub https://github.com/sponsors/syslogic - Repositories - Search + User Repositories + Org Repositories + Repository Search "Account Authenticator TODO From d9ca8dfefde1298d8d84f5779f22884d39fc17a2 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:48:58 +0200 Subject: [PATCH 036/163] readme updated. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 31497eaf..9e2be490 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ This is an unofficial Android client for GitHub, which utilizes the AndroidX & R ### Debug Builds -File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`.
-Without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession.
-When file `token.properties` is absent, the personal access token still can be added in the preferences. +File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`. +Without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), +the personal access token still can be added in the preferences. ### Screenshots From 1e18ed53cb48010fa052d3fb5bd2b04699afc0cd Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:50:41 +0200 Subject: [PATCH 037/163] readme updated. --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9e2be490..29bee432 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,8 @@ This is an unofficial Android client for GitHub, which utilizes the AndroidX & R ### Debug Builds -File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`. -Without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), -the personal access token still can be added in the preferences. +File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`.
+Without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), the personal access token still can be added in the preferences. ### Screenshots From 7683ed8084f29e8b20f74755ce4fe7378cf3bbf9 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:52:24 +0200 Subject: [PATCH 038/163] readme updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 29bee432..cee63d5b 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is an unofficial Android client for GitHub, which utilizes the AndroidX & R ### Debug Builds File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`.
-Without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), the personal access token still can be added in the preferences. +Without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), the personal access token still can be added in the application's preferences. ### Screenshots From a25f0791a671f5b26906d9fca88579257492bccc Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:53:15 +0200 Subject: [PATCH 039/163] readme updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cee63d5b..d336d482 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is an unofficial Android client for GitHub, which utilizes the AndroidX & R ### Debug Builds File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`.
-Without personal access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), the personal access token still can be added in the application's preferences. +Without an access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), the access token still can be added in the application's preferences. ### Screenshots From 246041e75ea5884fd6bb7d4ef8283b324b3fcd78 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:53:43 +0200 Subject: [PATCH 040/163] readme updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d336d482..120cb9f6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is an unofficial Android client for GitHub, which utilizes the AndroidX & R ### Debug Builds File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`.
-Without an access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), the access token still can be added in the application's preferences. +Without an access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), the access token still can be added in the preferences. ### Screenshots From 03a0ab7580cfba0ca52a61ea84f1c9bfa08ad635 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:54:20 +0200 Subject: [PATCH 041/163] readme updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 120cb9f6..343246d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## androidx-github -This is an unofficial Android client for GitHub, which utilizes the AndroidX & Retrofit2 libraries.
+This is an unofficial Android client for GitHub API, which utilizes the AndroidX & Retrofit2 libraries.
- by default, one can browse Android/Kotlin/Gradle projects, but it also features an editor for bookmarks. - one can also browse the own repositories and workflows (work in progress). - it generally supports git operations (check out only, so far), see [jgit](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/6.2.0.202206071550-r/org.eclipse.jgit/module-summary.html). From e1724edb49b5792e2c69a60588328a6fbaec38c0 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:55:09 +0200 Subject: [PATCH 042/163] readme updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 343246d9..62a3194c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Without an access token the API will be "rate limited", after having loaded the ![Repositories](screenshots/repositories_30.png?raw=true&sanitize=true "Repositories") - --- +### Android Library The `:library` module is available on JitPack; either by version tag or `master-SNAPSHOT`.
The JitPack repository URL would be: `maven { url 'https://jitpack.io' }` From c450a47f1908e15ecb0b27cb77bb0a4488aa4f82 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 01:56:12 +0200 Subject: [PATCH 043/163] readme updated. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 62a3194c..062cee23 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,5 @@ The JitPack repository URL would be: `maven { url 'https://jitpack.io' }` implementation "io.syslogic:androidx-github:1.0.0" } - --- - [![Release](https://jitpack.io/v/syslogic/androidx-github.svg)](https://jitpack.io/#io.syslogic/androidx-github) [![MIT License](https://img.shields.io/github/license/syslogic/androidx-github)](https://github.com/syslogic/androidx-github/blob/master/LICENSE) From 7e9be99ff723f0e0517ba68e8a568fc0a406acd2 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 02:09:17 +0200 Subject: [PATCH 044/163] readme updated. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 062cee23..74d15cd1 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ This is an unofficial Android client for GitHub API, which utilizes the AndroidX File `token.properties` may be created with a GitHub [access token](https://github.com/settings/tokens) declared as `accessToken=ghp_...`.
Without an access token the API will be "rate limited", after having loaded the first 10 pages in quick succession. When file `token.properties` is absent (or in release builds), the access token still can be added in the preferences. +### Security + +Only GitHub traffic is being permitted, see [`network_security_config.xml`](https://github.com/syslogic/androidx-github/blob/master/mobile/src/main/res/xml/network_security_config.xml). + ### Screenshots ![Repositories](screenshots/repositories_30.png?raw=true&sanitize=true "Repositories") From 136cb1d47d77589e263189c6ede70691f737b3a6 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 03:30:01 +0200 Subject: [PATCH 045/163] spinner items loaded from resources. --- .../java/io/syslogic/github/Constants.java | 3 + .../github/adapter/BaseArrayAdapter.java | 5 +- .../github/adapter/QueryStringAdapter.java | 2 +- .../github/adapter/RepositoryTypeAdapter.java | 19 ++++ .../github/adapter/SortFieldAdapter.java | 20 ----- .../adapter/SortFieldListingAdapter.java | 19 ++++ .../adapter/SortFieldSearchAdapter.java | 19 ++++ .../github/adapter/SortOrderAdapter.java | 2 +- .../github/adapter/StringArrayAdapter.java | 4 +- .../github/fragment/RepositoriesFragment.java | 86 +++++++++++++++---- .../fragment/RepositorySearchFragment.java | 2 +- .../syslogic/github}/model/SpinnerItem.java | 2 +- .../recyclerview/RepositoriesAdapter.java | 4 +- .../recyclerview/RepositoriesLinearView.java | 12 ++- .../main/res/layout/spinner_dropdown_item.xml | 11 +++ .../main/res/layout/toolbar_repositories.xml | 64 ++++++++++++-- .../res/layout/toolbar_repository_search.xml | 2 +- .../src/main/res/layout/toolbar_workflow.xml | 65 +++++++------- mobile/src/main/res/values/arrays.xml | 34 +++++++- mobile/src/main/res/values/strings.xml | 4 + 20 files changed, 283 insertions(+), 96 deletions(-) create mode 100644 mobile/src/main/java/io/syslogic/github/adapter/RepositoryTypeAdapter.java delete mode 100644 mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java create mode 100644 mobile/src/main/java/io/syslogic/github/adapter/SortFieldListingAdapter.java create mode 100644 mobile/src/main/java/io/syslogic/github/adapter/SortFieldSearchAdapter.java rename {library/src/main/java/io/syslogic/github/api => mobile/src/main/java/io/syslogic/github}/model/SpinnerItem.java (96%) create mode 100644 mobile/src/main/res/layout/spinner_dropdown_item.xml diff --git a/mobile/src/main/java/io/syslogic/github/Constants.java b/mobile/src/main/java/io/syslogic/github/Constants.java index 16284506..7a31cee6 100644 --- a/mobile/src/main/java/io/syslogic/github/Constants.java +++ b/mobile/src/main/java/io/syslogic/github/Constants.java @@ -21,6 +21,9 @@ public final class Constants { /** Deprecated SDK Constant */ @NonNull public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; + /** Table Names */ + @NonNull public static final String TABLE_QUERY_STRINGS = "query_strings"; + /** RecyclerView Settings */ @NonNull public static final Integer RECYCLERVIEW_SCROLLING_THRESHOLD = 12; @NonNull public static final Integer RECYCLERVIEW_DEFAULT_PAGE_SIZE = 30; diff --git a/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java index 8a41584b..f7d2f3fc 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/BaseArrayAdapter.java @@ -15,7 +15,8 @@ import java.util.ArrayList; import java.util.List; -import io.syslogic.github.api.model.SpinnerItem; +import io.syslogic.github.R; +import io.syslogic.github.model.SpinnerItem; /** * Array {@link BaseAdapter} @@ -52,7 +53,7 @@ public long getItemId(int position) { @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { if (convertView == null) { - convertView = this.layoutInflater.inflate(com.google.android.material.R.layout.support_simple_spinner_dropdown_item, parent, false); + convertView = this.layoutInflater.inflate(R.layout.spinner_dropdown_item, parent, false); } convertView.setTag(this.mItems.get(position)); AppCompatTextView textView = convertView.findViewById(android.R.id.text1); diff --git a/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java index 5cb374b2..3bfcc55d 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/QueryStringAdapter.java @@ -9,7 +9,7 @@ import java.util.List; import io.syslogic.github.api.model.QueryString; -import io.syslogic.github.api.model.SpinnerItem; +import io.syslogic.github.model.SpinnerItem; import io.syslogic.github.api.room.Abstraction; import io.syslogic.github.api.room.QueryStringsDao; diff --git a/mobile/src/main/java/io/syslogic/github/adapter/RepositoryTypeAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/RepositoryTypeAdapter.java new file mode 100644 index 00000000..4b251b79 --- /dev/null +++ b/mobile/src/main/java/io/syslogic/github/adapter/RepositoryTypeAdapter.java @@ -0,0 +1,19 @@ +package io.syslogic.github.adapter; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import io.syslogic.github.R; + +/** + * Repository-Type {@link BaseArrayAdapter}. + * + * @author Martin Zeitler + */ +public class RepositoryTypeAdapter extends BaseArrayAdapter { + public RepositoryTypeAdapter(@NonNull Context context) { + super(context); + this.setItems(context, R.array.repository_type_keys, R.array.repository_type_values); + } +} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java deleted file mode 100644 index 74fb723e..00000000 --- a/mobile/src/main/java/io/syslogic/github/adapter/SortFieldAdapter.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.syslogic.github.adapter; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import io.syslogic.github.R; - -/** - * Sort-Field {@link BaseArrayAdapter} - * - * @author Martin Zeitler - */ -public class SortFieldAdapter extends BaseArrayAdapter { - - public SortFieldAdapter(@NonNull Context context) { - super(context); - this.setItems(context, R.array.sortfield_keys, R.array.sortfield_values); - } -} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SortFieldListingAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldListingAdapter.java new file mode 100644 index 00000000..614fec62 --- /dev/null +++ b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldListingAdapter.java @@ -0,0 +1,19 @@ +package io.syslogic.github.adapter; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import io.syslogic.github.R; + +/** + * Sort-Field {@link BaseArrayAdapter} for repository listing. + * + * @author Martin Zeitler + */ +public class SortFieldListingAdapter extends BaseArrayAdapter { + public SortFieldListingAdapter(@NonNull Context context) { + super(context); + this.setItems(context, R.array.listing_sort_field_keys, R.array.listing_sort_field_values); + } +} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SortFieldSearchAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldSearchAdapter.java new file mode 100644 index 00000000..049b921e --- /dev/null +++ b/mobile/src/main/java/io/syslogic/github/adapter/SortFieldSearchAdapter.java @@ -0,0 +1,19 @@ +package io.syslogic.github.adapter; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import io.syslogic.github.R; + +/** + * Sort-Field {@link BaseArrayAdapter} for repository search. + * + * @author Martin Zeitler + */ +public class SortFieldSearchAdapter extends BaseArrayAdapter { + public SortFieldSearchAdapter(@NonNull Context context) { + super(context); + this.setItems(context, R.array.search_sort_field_keys, R.array.search_sort_field_values); + } +} diff --git a/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java index 83da2009..6670110b 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/SortOrderAdapter.java @@ -15,6 +15,6 @@ public class SortOrderAdapter extends BaseArrayAdapter { public SortOrderAdapter(@NonNull Context context) { super(context); - this.setItems(context, R.array.sortorder_keys, R.array.sortorder_values); + this.setItems(context, R.array.sort_order_keys, R.array.sort_order_values); } } diff --git a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java index 1cd1ab23..3dc6a4f0 100644 --- a/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/adapter/StringArrayAdapter.java @@ -4,9 +4,7 @@ import androidx.annotation.NonNull; -import java.util.ArrayList; - -import io.syslogic.github.api.model.SpinnerItem; +import io.syslogic.github.model.SpinnerItem; /** * String[] {@link BaseArrayAdapter} diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java index 8d5c74a2..0235b533 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java @@ -13,8 +13,11 @@ import io.syslogic.github.R; import io.syslogic.github.activity.NavHostActivity; +import io.syslogic.github.adapter.RepositoryTypeAdapter; +import io.syslogic.github.adapter.SortFieldListingAdapter; +import io.syslogic.github.adapter.SortOrderAdapter; import io.syslogic.github.adapter.StringArrayAdapter; -import io.syslogic.github.api.model.SpinnerItem; +import io.syslogic.github.model.SpinnerItem; import io.syslogic.github.api.model.User; import io.syslogic.github.databinding.FragmentRepositoriesBinding; import io.syslogic.github.model.PagerState; @@ -40,15 +43,6 @@ public class RepositoriesFragment extends BaseFragment implements TokenCallback /** Data-Binding */ private FragmentRepositoriesBinding mDataBinding; - /** Default: `owner`. */ - String[] repositoryTypes = new String[] {"all", "owner", "member"}; - - /** Default: `full_name`. */ - String[] sortFields = new String[] {"created", "updated", "pushed", "full_name"}; - - /** Default: `asc` when using `full_name`, otherwise `desc`. */ - String[] sortOrders = new String[] {"asc", "desc"}; - /** Constructor */ public RepositoriesFragment() {} @@ -66,24 +60,53 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c activity.setSupportActionBar(this.getDataBinding().toolbarRepositories.toolbarRepositories); this.mDataBinding.toolbarRepositories.home.setOnClickListener(view -> activity.onBackPressed()); - AppCompatSpinner spinner = this.getDataBinding().toolbarRepositories.spinnerRepositoryType; - spinner.setAdapter(new StringArrayAdapter(requireContext(), this.repositoryTypes)); - spinner.setSelection(1); + /* {@link AppCompatSpinner} spinner_repository_type */ + AppCompatSpinner spinnerRepositoryType = this.getDataBinding().toolbarRepositories.spinnerRepositoryType; + spinnerRepositoryType.setAdapter(new RepositoryTypeAdapter(requireContext())); + spinnerRepositoryType.setSelection(1); - spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + spinnerRepositoryType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { int count = 0; @Override public void onItemSelected(AdapterView parent, View view, int position, long resId) { if (count > 0) { SpinnerItem item = (SpinnerItem) view.getTag(); ScrollListener.setPageNumber(1); - String repositoryType = item.getValue(); + String value = item.getValue(); RepositoriesLinearView recyclerview = getDataBinding().recyclerviewRepositories; - recyclerview.setRepositoryType(repositoryType); + recyclerview.setRepositoryType(value); + PagerState pagerState = getDataBinding().getPagerState(); + if (pagerState != null) { + getDataBinding().setPagerState(pagerState); + } + if (recyclerview.getAdapter() != null) { + recyclerview.clearAdapter(); + ((RepositoriesAdapter) recyclerview.getAdapter()).fetchPage(1); + } + } + count++; + } + @Override + public void onNothingSelected(AdapterView parent) {} + }); + + /* {@link AppCompatSpinner} spinner_sort_field */ + AppCompatSpinner spinnerSortField = this.getDataBinding().toolbarRepositories.spinnerSortField; + spinnerSortField.setAdapter(new SortFieldListingAdapter(requireContext())); + spinnerSortField.setSelection(3); + spinnerSortField.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + int count = 0; + @Override + public void onItemSelected(AdapterView parent, View view, int position, long resId) { + if (count > 0) { + SpinnerItem item = (SpinnerItem) view.getTag(); + ScrollListener.setPageNumber(1); + String value = item.getValue(); + RepositoriesLinearView recyclerview = getDataBinding().recyclerviewRepositories; + recyclerview.setSortField(value); PagerState pagerState = getDataBinding().getPagerState(); if (pagerState != null) { - pagerState.setQueryString(repositoryType); getDataBinding().setPagerState(pagerState); } if (recyclerview.getAdapter() != null) { @@ -97,6 +120,35 @@ public void onItemSelected(AdapterView parent, View view, int position, long public void onNothingSelected(AdapterView parent) {} }); + /* {@link AppCompatSpinner} spinner_sort_order */ + AppCompatSpinner spinnerSortOrder = this.getDataBinding().toolbarRepositories.spinnerSortOrder; + spinnerSortOrder.setAdapter(new SortOrderAdapter(requireContext())); + spinnerSortOrder.setSelection(0); + + spinnerSortOrder.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + int count = 0; + @Override + public void onItemSelected(AdapterView parent, View view, int position, long resId) { + if (count > 0) { + SpinnerItem item = (SpinnerItem) view.getTag(); + ScrollListener.setPageNumber(1); + String value = item.getValue(); + RepositoriesLinearView recyclerview = getDataBinding().recyclerviewRepositories; + recyclerview.setSortOrder(value); + PagerState pagerState = getDataBinding().getPagerState(); + if (pagerState != null) { + getDataBinding().setPagerState(pagerState); + } + if (recyclerview.getAdapter() != null) { + recyclerview.clearAdapter(); + ((RepositoriesAdapter) recyclerview.getAdapter()).fetchPage(1); + } + } + count++; + } + @Override + public void onNothingSelected(AdapterView parent) {} + }); if (! isNetworkAvailable(this.requireContext())) { this.onNetworkLost(); diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java index a85adec9..a73f167e 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositorySearchFragment.java @@ -19,7 +19,7 @@ import io.syslogic.github.activity.NavHostActivity; import io.syslogic.github.adapter.QueryStringAdapter; import io.syslogic.github.api.model.QueryString; -import io.syslogic.github.api.model.SpinnerItem; +import io.syslogic.github.model.SpinnerItem; import io.syslogic.github.api.model.User; import io.syslogic.github.api.room.Abstraction; import io.syslogic.github.api.room.QueryStringsDao; diff --git a/library/src/main/java/io/syslogic/github/api/model/SpinnerItem.java b/mobile/src/main/java/io/syslogic/github/model/SpinnerItem.java similarity index 96% rename from library/src/main/java/io/syslogic/github/api/model/SpinnerItem.java rename to mobile/src/main/java/io/syslogic/github/model/SpinnerItem.java index b93e4392..f3106dbf 100644 --- a/library/src/main/java/io/syslogic/github/api/model/SpinnerItem.java +++ b/mobile/src/main/java/io/syslogic/github/model/SpinnerItem.java @@ -1,4 +1,4 @@ -package io.syslogic.github.api.model; +package io.syslogic.github.model; import androidx.annotation.NonNull; import androidx.room.Ignore; diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index f1c9ad99..aaff3d8a 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -78,8 +78,8 @@ public class RepositoriesAdapter extends RecyclerView.Adapter(context); diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java index 2cedbe24..c1c0c532 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesLinearView.java @@ -26,6 +26,7 @@ public RepositoriesLinearView(@NonNull Context context) { /** Constructor */ public RepositoriesLinearView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); this.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL)); LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext()); @@ -59,11 +60,14 @@ public void setRepositoryType(@NonNull String value) { if (adapter != null) {adapter.setRepositoryType(value);} } - @Nullable - public String getRepositoryType() { + public void setSortField(String value) { + RepositoriesAdapter adapter = ((RepositoriesAdapter) getAdapter()); + if (adapter != null) {adapter.setSortField(value);} + } + + public void setSortOrder(String value) { RepositoriesAdapter adapter = ((RepositoriesAdapter) getAdapter()); - if (adapter == null) {return null;} - return adapter.getRepositoryType(); + if (adapter != null) {adapter.setSortOrder(value);} } @NonNull diff --git a/mobile/src/main/res/layout/spinner_dropdown_item.xml b/mobile/src/main/res/layout/spinner_dropdown_item.xml new file mode 100644 index 00000000..153654ac --- /dev/null +++ b/mobile/src/main/res/layout/spinner_dropdown_item.xml @@ -0,0 +1,11 @@ + + + diff --git a/mobile/src/main/res/layout/toolbar_repositories.xml b/mobile/src/main/res/layout/toolbar_repositories.xml index 7b9ada23..5e38ea8a 100644 --- a/mobile/src/main/res/layout/toolbar_repositories.xml +++ b/mobile/src/main/res/layout/toolbar_repositories.xml @@ -33,21 +33,67 @@ android:layout_marginEnd="8dp" android:background="?attr/selectableItemBackgroundBorderless" android:padding="15dp" - android:src="?attr/homeAsUpIndicator" /> + android:src="?attr/homeAsUpIndicator"/> - + android:layout_gravity="center_vertical|end" + android:orientation="vertical"> - + + + +
+ + + android:layout_gravity="center_vertical|end" + android:orientation="vertical"> + + + + + + + + + + + + + +
diff --git a/mobile/src/main/res/layout/toolbar_repository_search.xml b/mobile/src/main/res/layout/toolbar_repository_search.xml index 13866899..852e3b3c 100644 --- a/mobile/src/main/res/layout/toolbar_repository_search.xml +++ b/mobile/src/main/res/layout/toolbar_repository_search.xml @@ -33,7 +33,7 @@ android:layout_marginEnd="8dp" android:background="?attr/selectableItemBackgroundBorderless" android:padding="15dp" - android:src="?attr/homeAsUpIndicator" /> + android:src="?attr/homeAsUpIndicator"/> - - + app:contentInsetStart="0dp"> + android:layout_height="match_parent" + android:orientation="horizontal"> - + android:layout_height="wrap_content" + android:layout_gravity="center_vertical|start" + android:layout_marginEnd="8dp" + android:background="?attr/selectableItemBackgroundBorderless" + android:padding="15dp" + android:src="?attr/homeAsUpIndicator"/> + + + + + + diff --git a/mobile/src/main/res/values/arrays.xml b/mobile/src/main/res/values/arrays.xml index 867d5a3b..f67ddf69 100644 --- a/mobile/src/main/res/values/arrays.xml +++ b/mobile/src/main/res/values/arrays.xml @@ -16,7 +16,7 @@ <= - + Forks Stargazers Watchers @@ -24,7 +24,7 @@ Networks - + forks_count stargazers_count watchers_count @@ -32,12 +32,38 @@ network_count - + + all + owner + member + + + + all + owner + member + + + + created + updated + pushed + full_name + + + + Created + Updated + Pushed + Name + + + ASC DESC - + ASC DESC diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index 540da311..c8e61eeb 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -68,4 +68,8 @@ Browse Close + Type + Sort Field + Direction + From bff1a618b5b92255382ecf0caa8615b3ac32e619 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 03:51:44 +0200 Subject: [PATCH 046/163] passing the repository ID fixed. --- .../github/fragment/RepositoryFragment.java | 9 +-- .../github/fragment/WorkflowFragment.java | 79 ++++++++++++++++--- .../recyclerview/RepositoriesAdapter.java | 2 +- .../src/main/res/layout/fragment_workflow.xml | 6 +- .../src/main/res/layout/toolbar_workflow.xml | 6 +- 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java index 33b2c378..39415cd8 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoryFragment.java @@ -74,7 +74,7 @@ public class RepositoryFragment extends BaseFragment implements TokenCallback { /** Data-Binding */ FragmentRepositoryBinding mDataBinding; ProgressDialogFragment currentDialog; - Long itemId = 0L; + Long itemId = -1L; /** Constructor */ public RepositoryFragment() {} @@ -93,7 +93,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.registerBroadcastReceiver(); Bundle args = this.getArguments(); - if (itemId == 0 && args != null) { + if (args != null) { this.setItemId(args.getLong(Constants.ARGUMENT_ITEM_ID)); } } @@ -309,9 +309,7 @@ public void onResponse(@NonNull Call call, @NonNull Response api = GithubClient.getRepository(this.itemId); + if (mDebug) { + Log.w(LOG_TAG, api.request().url() + "");} + + api.enqueue(new Callback<>() { + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + switch (response.code()) { + case 200 -> { + if (response.body() != null) { + Repository item = response.body(); + mDataBinding.setRepository(item); + } + } + case 403 -> { + if (response.errorBody() != null) { + try { + String errors = response.errorBody().string(); + JsonObject jsonObject = JsonParser.parseString(errors).getAsJsonObject(); + String message = jsonObject.get("message").toString(); + if (mDebug) { + Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show(); + Log.e(LOG_TAG, message); + } + } catch (IOException e) { + if (mDebug) {Log.e(LOG_TAG, "" + e.getMessage());} + } + } + } + } + } + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + if (mDebug) { + Log.e(LOG_TAG, "" + t.getMessage()); + } + } + }); + } + } + @NonNull public Long getItemId() { return this.itemId; diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index aaff3d8a..1350b0f8 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -361,7 +361,7 @@ public void onClick(@NonNull View viewHolder) { Repository item = getDataBinding().getItem(); NavController controller = Navigation.findNavController(layout); Bundle args = new Bundle(); - args.putString(Constants.ARGUMENT_ITEM_NAME, item.getName()); + args.putLong(Constants.ARGUMENT_ITEM_ID, item.getId()); controller.navigate(R.id.action_repositoriesFragment_to_workflowFragment, args); } } diff --git a/mobile/src/main/res/layout/fragment_workflow.xml b/mobile/src/main/res/layout/fragment_workflow.xml index c7e644d4..e118cff0 100644 --- a/mobile/src/main/res/layout/fragment_workflow.xml +++ b/mobile/src/main/res/layout/fragment_workflow.xml @@ -6,7 +6,7 @@ tools:context=".activity.NavHostActivity"> - + + bind:repository="@{ repository }"/> - - diff --git a/mobile/src/main/res/layout/toolbar_workflow.xml b/mobile/src/main/res/layout/toolbar_workflow.xml index 6d339416..5dde061b 100644 --- a/mobile/src/main/res/layout/toolbar_workflow.xml +++ b/mobile/src/main/res/layout/toolbar_workflow.xml @@ -5,7 +5,7 @@ xmlns:tools="http://schemas.android.com/tools"> - + Date: Tue, 8 Aug 2023 03:54:02 +0200 Subject: [PATCH 047/163] annotation added. --- .../java/io/syslogic/github/fragment/WorkflowFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java index e70fb626..6316a89f 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java @@ -51,6 +51,7 @@ public class WorkflowFragment extends BaseFragment { public WorkflowFragment() {} @NonNull + @SuppressWarnings("unused") public static WorkflowFragment newInstance(long itemId) { WorkflowFragment fragment = new WorkflowFragment(); Bundle args = new Bundle(); @@ -96,8 +97,7 @@ private void setRepository() { if (this.itemId != 0) { Call api = GithubClient.getRepository(this.itemId); - if (mDebug) { - Log.w(LOG_TAG, api.request().url() + "");} + if (mDebug) {Log.w(LOG_TAG, api.request().url() + "");} api.enqueue(new Callback<>() { From dbd04b087bedd8c656236f26a8f7296e9cc15c2a Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 06:41:28 +0200 Subject: [PATCH 048/163] preview fixed. --- mobile/src/main/res/layout/toolbar_repositories.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mobile/src/main/res/layout/toolbar_repositories.xml b/mobile/src/main/res/layout/toolbar_repositories.xml index 5e38ea8a..fab8e195 100644 --- a/mobile/src/main/res/layout/toolbar_repositories.xml +++ b/mobile/src/main/res/layout/toolbar_repositories.xml @@ -51,7 +51,8 @@ + android:layout_height="wrap_content" + tools:listitem="@layout/spinner_dropdown_item"/>
@@ -71,7 +72,8 @@ + android:layout_height="wrap_content" + tools:listitem="@layout/spinner_dropdown_item"/>
@@ -91,7 +93,8 @@ + android:layout_height="wrap_content" + tools:listitem="@layout/spinner_dropdown_item"/> From 17d7363bc645212597744d29adf311b134685279 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 07:21:46 +0200 Subject: [PATCH 049/163] workflows are being assigned to repository model. --- .../syslogic/github/api/model/Repository.java | 20 ++++++++++++++ .../recyclerview/RepositoriesAdapter.java | 12 ++++++--- .../main/res/layout/cardview_repository.xml | 26 ++++++++++++++----- mobile/src/main/res/values/tools.xml | 5 +++- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/library/src/main/java/io/syslogic/github/api/model/Repository.java b/library/src/main/java/io/syslogic/github/api/model/Repository.java index 40fc25b5..8b00c970 100644 --- a/library/src/main/java/io/syslogic/github/api/model/Repository.java +++ b/library/src/main/java/io/syslogic/github/api/model/Repository.java @@ -13,6 +13,8 @@ import com.google.gson.annotations.SerializedName; +import java.util.ArrayList; + import io.syslogic.github.api.Constants; import io.syslogic.github.api.utils.StringArrayConverter; @@ -92,6 +94,10 @@ public class Repository extends BaseModel implements IContentProvider { @TypeConverters(StringArrayConverter.class) private String[] topics; + /** Being populated asynchronously. */ + @Ignore + private ArrayList workflows = new ArrayList<>(); + /** Constructor */ public Repository() {} @@ -172,6 +178,10 @@ public void setTopics(@NonNull String[] value) { this.topics = value; } + public void setWorkflows(@NonNull ArrayList value) { + this.workflows = value; + } + /* Getters */ @NonNull @Bindable @@ -273,6 +283,16 @@ public String[] getTopics() { return this.topics; } + @NonNull + public ArrayList getWorkflows() { + return this.workflows; + } + + @Bindable + public int getWorkflowCount() { + return this.workflows.size(); + } + @NonNull @Override public ContentValues toContentValues() { diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java index 1350b0f8..3367f40b 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/RepositoriesAdapter.java @@ -150,7 +150,7 @@ public void onResponse(@NonNull Call> call, @NonNull Respo /* Updating the pager data-binding */ setPagerState(pageNumber, false, (long) getItems().size()); - getWorkflows(); + getWorkflows(positionStart); } } else { /* "bad credentials" means that the provided access-token is invalid. */ @@ -170,10 +170,11 @@ public void onFailure(@NonNull Call> call, @NonNull Throwa } } - private void getWorkflows() { + private void getWorkflows(int positionStart) { + final int[] index = {0}; for (Repository item : this.getItems()) { - Call api2 = GithubClient.getWorkflows(accessToken, username,item.getName()); + Call api2 = GithubClient.getWorkflows(accessToken, username, item.getName()); // if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api2.request().url() + "");} api2.enqueue(new Callback<>() { @@ -184,6 +185,10 @@ public void onResponse(@NonNull Call call, @NonNull Response< WorkflowsResponse items = response.body(); if (BuildConfig.DEBUG) { if (items.getWorkflows() != null && items.getWorkflows().size() > 0) { + + mItems.get(index[0]).setWorkflows(items.getWorkflows()); + notifyItemChanged(positionStart + index[0]); + for (Workflow item2 : items.getWorkflows()) { Log.d(LOG_TAG, item.getName() + " has workflow: " + item2.getName()); } @@ -196,6 +201,7 @@ public void onResponse(@NonNull Call call, @NonNull Response< logError(response.errorBody()); } } + index[0]++; } @Override diff --git a/mobile/src/main/res/layout/cardview_repository.xml b/mobile/src/main/res/layout/cardview_repository.xml index 9142f84a..8b3f44e1 100644 --- a/mobile/src/main/res/layout/cardview_repository.xml +++ b/mobile/src/main/res/layout/cardview_repository.xml @@ -18,24 +18,36 @@ + + + tools:text="@string/tools_workflow_count"/> diff --git a/mobile/src/main/res/values/tools.xml b/mobile/src/main/res/values/tools.xml index 04b05358..a424f08d 100644 --- a/mobile/src/main/res/values/tools.xml +++ b/mobile/src/main/res/values/tools.xml @@ -18,10 +18,13 @@ Profile Preview token login + + 1 + android.yml - + remote: Enumerating objects 2056 / 5793 93% From 275b1214a4bab9f4e68d660f5839fbdd4ab48fed Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 8 Aug 2023 08:49:59 +0200 Subject: [PATCH 050/163] workflows are being added into an adapter. --- .../io/syslogic/github/api/Constants.java | 1 + .../syslogic/github/api/model/Workflow.java | 43 +++- .../syslogic/github/api/room/Abstraction.java | 9 +- .../github/api/room/WorkflowsDao.java | 53 +++++ .../github/fragment/RepositoriesFragment.java | 1 - ...owFragment.java => WorkflowFragments.java} | 50 +++-- ...ovider.java => WorkflowsMenuProvider.java} | 6 +- .../recyclerview/QueryStringsLinearView.java | 2 +- .../github/recyclerview/WorkflowsAdapter.java | 191 ++++++++++++++++++ .../recyclerview/WorkflowsLinearView.java | 43 ++++ .../src/main/res/layout/cardview_workflow.xml | 56 +++++ .../main/res/layout/fragment_repositories.xml | 12 +- ...nt_workflow.xml => fragment_workflows.xml} | 15 +- ...bar_workflow.xml => toolbar_workflows.xml} | 6 +- .../res/menu/{workflow.xml => workflows.xml} | 0 mobile/src/main/res/navigation/nav_graph.xml | 4 +- mobile/src/main/res/values/tools.xml | 8 +- 17 files changed, 456 insertions(+), 44 deletions(-) create mode 100644 library/src/main/java/io/syslogic/github/api/room/WorkflowsDao.java rename mobile/src/main/java/io/syslogic/github/fragment/{WorkflowFragment.java => WorkflowFragments.java} (73%) rename mobile/src/main/java/io/syslogic/github/provider/{WorkflowMenuProvider.java => WorkflowsMenuProvider.java} (86%) create mode 100644 mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowsAdapter.java create mode 100644 mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowsLinearView.java create mode 100644 mobile/src/main/res/layout/cardview_workflow.xml rename mobile/src/main/res/layout/{fragment_workflow.xml => fragment_workflows.xml} (69%) rename mobile/src/main/res/layout/{toolbar_workflow.xml => toolbar_workflows.xml} (94%) rename mobile/src/main/res/menu/{workflow.xml => workflows.xml} (100%) diff --git a/library/src/main/java/io/syslogic/github/api/Constants.java b/library/src/main/java/io/syslogic/github/api/Constants.java index bf567083..2d35601f 100644 --- a/library/src/main/java/io/syslogic/github/api/Constants.java +++ b/library/src/main/java/io/syslogic/github/api/Constants.java @@ -14,6 +14,7 @@ public final class Constants { /** Table Names */ @NonNull public static final String TABLE_QUERY_STRINGS = "query_strings"; @NonNull public static final String TABLE_REPOSITORIES = "repositories"; + @NonNull public static final String TABLE_WORKFLOWS = "workflows"; @NonNull public static final String TABLE_LICENSES = "licenses"; @NonNull public static final String TABLE_OWNERS = "owners"; } diff --git a/library/src/main/java/io/syslogic/github/api/model/Workflow.java b/library/src/main/java/io/syslogic/github/api/model/Workflow.java index 108c2937..6afdab8b 100644 --- a/library/src/main/java/io/syslogic/github/api/model/Workflow.java +++ b/library/src/main/java/io/syslogic/github/api/model/Workflow.java @@ -1,49 +1,75 @@ package io.syslogic.github.api.model; +import android.content.ContentValues; + import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; import com.google.gson.annotations.SerializedName; +import io.syslogic.github.api.Constants; + /** * Model: Workflow * * @author Martin Zeitler */ -public class Workflow { +@Entity(tableName = Constants.TABLE_WORKFLOWS) +public class Workflow extends BaseModel implements IContentProvider { + @PrimaryKey() + @ColumnInfo(name = "id") @SerializedName("id") private long id; + // foreign key + @ColumnInfo(name = "repo_id") + private long repositoryId; + + @ColumnInfo(name = "node_id") @SerializedName("node_id") private String nodeId; + @ColumnInfo(name = "name") @SerializedName("name") private String name; + @ColumnInfo(name = "path") @SerializedName("path") private String path; + @ColumnInfo(name = "state") @SerializedName("state") private String state; + @ColumnInfo(name = "created_at") @SerializedName("created_at") private String createdAt; + @ColumnInfo(name = "updated_at") @SerializedName("updated_at") private String updatedAt; + @ColumnInfo(name = "url") @SerializedName("url") private String url; + @ColumnInfo(name = "html_url") @SerializedName("html_url") private String htmlUrl; + @ColumnInfo(name = "badge_url") @SerializedName("badge_url") private String badgeUrl; public void setId(long value) { this.id = value; } + public void setRepositoryId(long value) { + this.repositoryId = value; + } public void setNodeId(@NonNull String value) { this.nodeId = value; } @@ -75,6 +101,9 @@ public void setBadgeUrl(@NonNull String value) { public long getId() { return this.id; } + public long getRepositoryId() { + return this.repositoryId; + } @NonNull public String getNodeId() { return this.nodeId; @@ -111,4 +140,16 @@ public String getHtmlUrl() { public String getBadgeUrl() { return this.badgeUrl; } + + @NonNull + @Override + public BaseModel fromContentValues(@NonNull ContentValues values) { + return null; + } + + @NonNull + @Override + public ContentValues toContentValues() { + return null; + } } diff --git a/library/src/main/java/io/syslogic/github/api/room/Abstraction.java b/library/src/main/java/io/syslogic/github/api/room/Abstraction.java index 9767fca4..a5bb4751 100644 --- a/library/src/main/java/io/syslogic/github/api/room/Abstraction.java +++ b/library/src/main/java/io/syslogic/github/api/room/Abstraction.java @@ -16,13 +16,14 @@ import io.syslogic.github.api.model.Owner; import io.syslogic.github.api.model.QueryString; import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.model.Workflow; /** * {@link RoomDatabase} Abstraction * * @author Martin Zeitler */ -@Database(version = 1, entities = {QueryString.class, Repository.class, License.class, Owner.class}) +@Database(version = 1, entities = {QueryString.class, Repository.class, Workflow.class, License.class, Owner.class}) public abstract class Abstraction extends RoomDatabase { /** The log tag. */ @@ -52,6 +53,12 @@ public abstract class Abstraction extends RoomDatabase { */ @Nullable public abstract RepositoriesDao repositoriesDao(); + /** + * Abstract {@link androidx.room.Dao} for {@link Workflow}. + * @return in instance of {@link WorkflowsDao}. + */ + @Nullable public abstract WorkflowsDao workflowsDao(); + /** * Abstract {@link androidx.room.Dao} for {@link License}. * @return in instance of {@link LicensesDao}. diff --git a/library/src/main/java/io/syslogic/github/api/room/WorkflowsDao.java b/library/src/main/java/io/syslogic/github/api/room/WorkflowsDao.java new file mode 100644 index 00000000..8dcd92dd --- /dev/null +++ b/library/src/main/java/io/syslogic/github/api/room/WorkflowsDao.java @@ -0,0 +1,53 @@ +package io.syslogic.github.api.room; + +import android.database.Cursor; + +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; +import androidx.room.Update; + +import java.util.List; + +import io.syslogic.github.api.Constants; +import io.syslogic.github.api.model.Workflow; + +/** + * {@link Workflow} {@link Dao} interface + * + * @author Martin Zeitler + */ +@Dao +public interface WorkflowsDao { + + // @Transaction + @Query("SELECT * FROM " + Constants.TABLE_WORKFLOWS) + List getItems(); + + /* For ContentProvider */ + @Query("SELECT * FROM " + Constants.TABLE_WORKFLOWS) + Cursor selectAll(); + + /* For ContentProvider */ + @Query("SELECT * FROM " + Constants.TABLE_WORKFLOWS + " WHERE id LIKE :itemId LIMIT 1") + Cursor getCursor(Long itemId); + + @Query("SELECT * FROM " + Constants.TABLE_WORKFLOWS + " WHERE id LIKE :itemId LIMIT 1") + Workflow getItem(Long itemId); + + @Insert() + Long insert(Workflow item); + + @Update() + int update(Workflow item); + + @Delete() + void delete(Workflow item); + + @Query("DELETE FROM " + Constants.TABLE_WORKFLOWS + " WHERE id = :itemId") + int deleteById(Long itemId); + + @Query("DELETE FROM " + Constants.TABLE_WORKFLOWS) + void clear(); +} diff --git a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java index 0235b533..b22eba0e 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/RepositoriesFragment.java @@ -16,7 +16,6 @@ import io.syslogic.github.adapter.RepositoryTypeAdapter; import io.syslogic.github.adapter.SortFieldListingAdapter; import io.syslogic.github.adapter.SortOrderAdapter; -import io.syslogic.github.adapter.StringArrayAdapter; import io.syslogic.github.model.SpinnerItem; import io.syslogic.github.api.model.User; import io.syslogic.github.databinding.FragmentRepositoriesBinding; diff --git a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragments.java similarity index 73% rename from mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java rename to mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragments.java index 6316a89f..84157a15 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragment.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragments.java @@ -23,37 +23,40 @@ import io.syslogic.github.activity.NavHostActivity; import io.syslogic.github.api.GithubClient; import io.syslogic.github.api.model.Repository; -import io.syslogic.github.databinding.FragmentWorkflowBinding; -import io.syslogic.github.provider.WorkflowMenuProvider; +import io.syslogic.github.databinding.FragmentWorkflowsBinding; +import io.syslogic.github.provider.WorkflowsMenuProvider; + +import io.syslogic.github.recyclerview.RepositoriesAdapter; +import io.syslogic.github.recyclerview.WorkflowsAdapter; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; /** - * Workflow {@link BaseFragment} + * Workflows {@link BaseFragment} * * @author Martin Zeitler */ -public class WorkflowFragment extends BaseFragment { +public class WorkflowFragments extends BaseFragment { /** Log Tag */ - @SuppressWarnings("unused") private static final String LOG_TAG = WorkflowFragment.class.getSimpleName(); + @SuppressWarnings("unused") private static final String LOG_TAG = WorkflowFragments.class.getSimpleName(); /** Layout resource ID kept for reference. */ - @SuppressWarnings("unused") private static final int resId = R.layout.fragment_workflow; + @SuppressWarnings("unused") private static final int resId = R.layout.fragment_workflows; /** Data-Binding */ - private FragmentWorkflowBinding mDataBinding; + private FragmentWorkflowsBinding mDataBinding; private Long itemId = -1L; /** Constructor */ - public WorkflowFragment() {} + public WorkflowFragments() {} @NonNull @SuppressWarnings("unused") - public static WorkflowFragment newInstance(long itemId) { - WorkflowFragment fragment = new WorkflowFragment(); + public static WorkflowFragments newInstance(long itemId) { + WorkflowFragments fragment = new WorkflowFragments(); Bundle args = new Bundle(); args.putLong(Constants.ARGUMENT_ITEM_ID, itemId); fragment.setArguments(args); @@ -75,32 +78,33 @@ public void onCreate(@Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { NavHostActivity activity = ((NavHostActivity) this.requireActivity()); - this.setDataBinding(FragmentWorkflowBinding.inflate(inflater, container, false)); + this.setDataBinding(FragmentWorkflowsBinding.inflate(inflater, container, false)); /* It removes & adds {@link BaseMenuProvider} */ - activity.setMenuProvider(new WorkflowMenuProvider(activity)); + activity.setMenuProvider(new WorkflowsMenuProvider(activity)); // the SpinnerItem has the same ID as the QueryString. - activity.setSupportActionBar(this.getDataBinding().toolbarWorkflow.toolbarWorkflow); - this.mDataBinding.toolbarWorkflow.home.setOnClickListener(view -> activity.onBackPressed()); + activity.setSupportActionBar(this.getDataBinding().toolbarWorkflows.toolbarWorkflows); + this.mDataBinding.toolbarWorkflows.home.setOnClickListener(view -> activity.onBackPressed()); if (! isNetworkAvailable(this.requireContext())) { this.onNetworkLost(); } else if (itemId != -1L) { - this.setRepository(); + WorkflowsAdapter adapter = new WorkflowsAdapter(requireContext()); + this.getDataBinding().recyclerviewWorkflows.setAdapter(adapter); + this.setRepository(itemId); } return this.getDataBinding().getRoot(); } - private void setRepository() { + private void setRepository(long repositoryId) { - if (this.itemId != 0) { + if (repositoryId != 0) { - Call api = GithubClient.getRepository(this.itemId); + Call api = GithubClient.getRepository(repositoryId); if (mDebug) {Log.w(LOG_TAG, api.request().url() + "");} api.enqueue(new Callback<>() { - @Override public void onResponse(@NonNull Call call, @NonNull Response response) { switch (response.code()) { @@ -108,6 +112,10 @@ public void onResponse(@NonNull Call call, @NonNull Response { @@ -147,13 +155,13 @@ private void setItemId(@NonNull Long value) { } @NonNull - public FragmentWorkflowBinding getDataBinding() { + public FragmentWorkflowsBinding getDataBinding() { return this.mDataBinding; } @Override protected void setDataBinding(@NonNull ViewDataBinding binding) { - this.mDataBinding = (FragmentWorkflowBinding) binding; + this.mDataBinding = (FragmentWorkflowsBinding) binding; } @Override diff --git a/mobile/src/main/java/io/syslogic/github/provider/WorkflowMenuProvider.java b/mobile/src/main/java/io/syslogic/github/provider/WorkflowsMenuProvider.java similarity index 86% rename from mobile/src/main/java/io/syslogic/github/provider/WorkflowMenuProvider.java rename to mobile/src/main/java/io/syslogic/github/provider/WorkflowsMenuProvider.java index fd5c66d4..2bdfa38d 100644 --- a/mobile/src/main/java/io/syslogic/github/provider/WorkflowMenuProvider.java +++ b/mobile/src/main/java/io/syslogic/github/provider/WorkflowsMenuProvider.java @@ -15,10 +15,10 @@ * * @author Martin Zeitler */ -public class WorkflowMenuProvider extends BaseMenuProvider { +public class WorkflowsMenuProvider extends BaseMenuProvider { /** Constructor */ - public WorkflowMenuProvider(@NonNull BaseActivity activity) { + public WorkflowsMenuProvider(@NonNull BaseActivity activity) { super(activity); } @@ -30,7 +30,7 @@ public WorkflowMenuProvider(@NonNull BaseActivity activity) { */ @Override public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - inflater.inflate(R.menu.workflow, menu); + inflater.inflate(R.menu.workflows, menu); } /** diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsLinearView.java b/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsLinearView.java index 8c0d24a7..3d80e3cf 100644 --- a/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsLinearView.java +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/QueryStringsLinearView.java @@ -11,7 +11,7 @@ import androidx.recyclerview.widget.RecyclerView; /** - * Topics {@link RecyclerView} + * Query-Strings {@link RecyclerView} * * @author Martin Zeitler */ diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowsAdapter.java b/mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowsAdapter.java new file mode 100644 index 00000000..d84dfdcf --- /dev/null +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowsAdapter.java @@ -0,0 +1,191 @@ +package io.syslogic.github.recyclerview; + +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.cardview.widget.CardView; +import androidx.databinding.DataBindingUtil; +import androidx.databinding.ViewDataBinding; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.recyclerview.widget.RecyclerView; + +import java.lang.ref.WeakReference; +import java.util.List; + +import io.syslogic.github.BuildConfig; +import io.syslogic.github.Constants; +import io.syslogic.github.R; +import io.syslogic.github.activity.BaseActivity; +import io.syslogic.github.api.GithubClient; +import io.syslogic.github.api.model.QueryString; +import io.syslogic.github.api.model.Repository; +import io.syslogic.github.api.model.Workflow; +import io.syslogic.github.api.model.WorkflowsResponse; +import io.syslogic.github.api.room.Abstraction; +import io.syslogic.github.databinding.CardviewWorkflowBinding; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Workflows {@link RecyclerView.Adapter} + * + * @author Martin Zeitler + */ +public class WorkflowsAdapter extends RecyclerView.Adapter { + + /** Log Tag */ + @NonNull + @SuppressWarnings("unused") + private static final String LOG_TAG = WorkflowsAdapter.class.getSimpleName(); + + /** Debug Output */ + static final boolean mDebug = BuildConfig.DEBUG; + + private WeakReference mContext; + private RecyclerView mRecyclerView; + private List mItems; + + public WorkflowsAdapter(@NonNull Context context) { + this.mContext = new WeakReference<>(context); + Abstraction.executorService.execute(() -> { + // mItems = Abstraction.getInstance(getContext()).workflowsDao().getItems() + }); + } + + @Override + public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { + super.onAttachedToRecyclerView(recyclerView); + this.mRecyclerView = recyclerView; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + CardviewWorkflowBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.cardview_workflow, parent, false); + binding.getRoot().setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return new ViewHolder(binding); + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int position) { + final Workflow item = getItem(position); + ((ViewHolder) viewHolder).getDataBinding().setItem(item); + ((ViewHolder) viewHolder).setId(item.getId()); + } + + private Workflow getItem(int index) { + return this.mItems.get(index); + } + + @Override + public int getItemCount() { + if (this.mItems == null) {return 0;} + return this.mItems.size(); + } + + List getItems() { + return this.mItems; + } + + void clearItems() { + this.mItems.clear(); + notifyItemRangeChanged(0, getItemCount()); + } + + @NonNull + protected Context getContext() { + return this.mContext.get(); + } + + public void getWorkflows(String accessToken, String username, String repositoryName) { + + Call api = GithubClient.getWorkflows(accessToken, username, repositoryName); + if (BuildConfig.DEBUG) {Log.w(LOG_TAG, api.request().url() + "");} + + api.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.code() == 200) { // OK + if (response.body() != null) { + WorkflowsResponse items = response.body(); + if (items.getWorkflows() != null && items.getWorkflows().size() > 0) { + mItems = items.getWorkflows(); + notifyItemRangeChanged(0, mItems.size()); + } + } + } else { + /* "bad credentials" means that the provided access-token is invalid. */ + if (response.errorBody() != null) { + // logError(response.errorBody()); + } + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + if (BuildConfig.DEBUG) {Log.e(LOG_TAG, "onFailure: " + t.getMessage());} + } + }); + } + + /** {@link RecyclerView.ViewHolder} for {@link CardView} of type {@link QueryString}. */ + private static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + + private final CardviewWorkflowBinding mDataBinding; + private WorkflowsLinearView mRecyclerView; + private CardView cardView; + private long itemId; + + /** + * ViewHolder Constructor + * @param binding the item's data-binding + **/ + ViewHolder(@NonNull CardviewWorkflowBinding binding) { + + super(binding.getRoot()); + this.mDataBinding = binding; + + View layout = binding.getRoot(); + this.setCardView(layout.findViewById(R.id.cardview)); + if (this.cardView != null) {this.cardView.setOnClickListener(this);} + } + + @Override + public void onClick(@NonNull View viewHolder) { + this.mRecyclerView = (WorkflowsLinearView) viewHolder.getParent(); + Workflow item = (Workflow) viewHolder.getTag(); + BaseActivity activity = (BaseActivity) this.mRecyclerView.getContext(); + ViewDataBinding databinding = activity.getFragmentDataBinding(); + if (databinding != null) { + Bundle args = new Bundle(); + args.putLong(Constants.ARGUMENT_ITEM_ID, item.getId()); + NavController controller = Navigation.findNavController(databinding.getRoot()); + // controller.navigate(R.id.action_workflowFragment_to_someFragment, args); + } + } + + /** Setters */ + public void setId(long value) { + this.itemId = value; + } + void setCardView(CardView view) { + this.cardView = view; + } + + /** Getters */ + public long getId() { + return this.itemId; + } + CardviewWorkflowBinding getDataBinding() { + return this.mDataBinding; + } + } +} diff --git a/mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowsLinearView.java b/mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowsLinearView.java new file mode 100644 index 00000000..198c5510 --- /dev/null +++ b/mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowsLinearView.java @@ -0,0 +1,43 @@ +package io.syslogic.github.recyclerview; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +/** + * Workflows {@link RecyclerView} + * + * @author Martin Zeitler + */ +public class WorkflowsLinearView extends RecyclerView { + + LinearLayoutManager mLinearLayoutManager; + + /** Constructor */ + public WorkflowsLinearView(@NonNull Context context) { + super(context); + } + + /** Constructor */ + public WorkflowsLinearView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + this.mLinearLayoutManager = new LinearLayoutManager(this.getContext()); + this.setLayoutManager(this.mLinearLayoutManager); + this.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL)); + } + + @SuppressLint("NotifyDataSetChanged") + public void clearAdapter() { + WorkflowsAdapter adapter = ((WorkflowsAdapter) getAdapter()); + if (adapter != null) { + adapter.clearItems(); + adapter.notifyDataSetChanged(); + } + } +} diff --git a/mobile/src/main/res/layout/cardview_workflow.xml b/mobile/src/main/res/layout/cardview_workflow.xml new file mode 100644 index 00000000..8e435b08 --- /dev/null +++ b/mobile/src/main/res/layout/cardview_workflow.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/src/main/res/layout/fragment_repositories.xml b/mobile/src/main/res/layout/fragment_repositories.xml index b506e46b..c390346c 100644 --- a/mobile/src/main/res/layout/fragment_repositories.xml +++ b/mobile/src/main/res/layout/fragment_repositories.xml @@ -48,12 +48,12 @@ android:layout_width="match_parent" android:layout_weight="1.00"/> - + diff --git a/mobile/src/main/res/layout/fragment_workflow.xml b/mobile/src/main/res/layout/fragment_workflows.xml similarity index 69% rename from mobile/src/main/res/layout/fragment_workflow.xml rename to mobile/src/main/res/layout/fragment_workflows.xml index e118cff0..612fb4eb 100644 --- a/mobile/src/main/res/layout/fragment_workflow.xml +++ b/mobile/src/main/res/layout/fragment_workflows.xml @@ -2,6 +2,7 @@ @@ -10,7 +11,7 @@ @@ -21,8 +22,8 @@ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> + + diff --git a/mobile/src/main/res/layout/toolbar_workflow.xml b/mobile/src/main/res/layout/toolbar_workflows.xml similarity index 94% rename from mobile/src/main/res/layout/toolbar_workflow.xml rename to mobile/src/main/res/layout/toolbar_workflows.xml index 5dde061b..5accb8c3 100644 --- a/mobile/src/main/res/layout/toolbar_workflow.xml +++ b/mobile/src/main/res/layout/toolbar_workflows.xml @@ -9,7 +9,7 @@ + tools:text="@string/tools_full_name"/> diff --git a/mobile/src/main/res/menu/workflow.xml b/mobile/src/main/res/menu/workflows.xml similarity index 100% rename from mobile/src/main/res/menu/workflow.xml rename to mobile/src/main/res/menu/workflows.xml diff --git a/mobile/src/main/res/navigation/nav_graph.xml b/mobile/src/main/res/navigation/nav_graph.xml index 4123310b..3a2fca62 100644 --- a/mobile/src/main/res/navigation/nav_graph.xml +++ b/mobile/src/main/res/navigation/nav_graph.xml @@ -109,9 +109,9 @@ + tools:layout="@layout/fragment_workflows"> diff --git a/mobile/src/main/res/values/tools.xml b/mobile/src/main/res/values/tools.xml index a424f08d..87509979 100644 --- a/mobile/src/main/res/values/tools.xml +++ b/mobile/src/main/res/values/tools.xml @@ -18,11 +18,15 @@ Profile Preview token login - + 1 - android.yml + android.yml + + + Gradle + Gradle remote: Enumerating objects From 1171cf93a6d121c4e220c26f29ddc48cf4c9f9d5 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Wed, 9 Aug 2023 02:16:02 +0200 Subject: [PATCH 051/163] method renamed. --- .../io/syslogic/github/fragment/WorkflowFragments.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragments.java b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragments.java index 84157a15..4246fbd8 100644 --- a/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragments.java +++ b/mobile/src/main/java/io/syslogic/github/fragment/WorkflowFragments.java @@ -25,9 +25,8 @@ import io.syslogic.github.api.model.Repository; import io.syslogic.github.databinding.FragmentWorkflowsBinding; import io.syslogic.github.provider.WorkflowsMenuProvider; - -import io.syslogic.github.recyclerview.RepositoriesAdapter; import io.syslogic.github.recyclerview.WorkflowsAdapter; + import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -92,12 +91,12 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } else if (itemId != -1L) { WorkflowsAdapter adapter = new WorkflowsAdapter(requireContext()); this.getDataBinding().recyclerviewWorkflows.setAdapter(adapter); - this.setRepository(itemId); + this.setRepositoryId(itemId); } return this.getDataBinding().getRoot(); } - private void setRepository(long repositoryId) { + private void setRepositoryId(long repositoryId) { if (repositoryId != 0) { From 5ee00e1efdf921f0865f42e4aa2aebac70c90236 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Wed, 9 Aug 2023 03:25:24 +0200 Subject: [PATCH 052/163] navigation updated; workflow-runs fragment added (yet untested). --- ...ery_strings.xml => github___bookmarks.xml} | 16 +- .../io/syslogic/github/api/Constants.java | 1 + .../io/syslogic/github/api/GithubClient.java | 13 ++ .../io/syslogic/github/api/GithubService.java | 11 +- .../syslogic/github/api/model/Workflow.java | 17 +- .../github/api/model/WorkflowRun.java | 56 ++++++ .../api/model/WorkflowRunsResponse.java | 36 ++++ .../github/api/utils/DateConverter.java | 24 +++ .../github/fragment/HomeScreenFragment.java | 2 +- .../github/fragment/WorkflowRunsFragment.java | 177 +++++++++++++++++ ...wFragments.java => WorkflowsFragment.java} | 11 +- .../recyclerview/WorkflowRunsAdapter.java | 178 ++++++++++++++++++ .../recyclerview/WorkflowRunsLinearView.java | 43 +++++ .../github/recyclerview/WorkflowsAdapter.java | 32 +--- .../main/res/layout/cardview_workflow_run.xml | 54 ++++++ .../res/layout/fragment_workflow_runs.xml | 48 +++++ .../main/res/layout/toolbar_workflow_runs.xml | 65 +++++++ mobile/src/main/res/navigation/nav_graph.xml | 63 ++++--- mobile/src/main/res/values/tools.xml | 2 +- 19 files changed, 780 insertions(+), 69 deletions(-) rename .idea/runConfigurations/{github___query_strings.xml => github___bookmarks.xml} (80%) create mode 100644 library/src/main/java/io/syslogic/github/api/model/WorkflowRun.java create mode 100644 library/src/main/java/io/syslogic/github/api/model/WorkflowRunsResponse.java create mode 100644 library/src/main/java/io/syslogic/github/api/utils/DateConverter.java create mode 100644 mobile/src/main/java/io/syslogic/github/fragment/WorkflowRunsFragment.java rename mobile/src/main/java/io/syslogic/github/fragment/{WorkflowFragments.java => WorkflowsFragment.java} (95%) create mode 100644 mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowRunsAdapter.java create mode 100644 mobile/src/main/java/io/syslogic/github/recyclerview/WorkflowRunsLinearView.java create mode 100644 mobile/src/main/res/layout/cardview_workflow_run.xml create mode 100644 mobile/src/main/res/layout/fragment_workflow_runs.xml create mode 100644 mobile/src/main/res/layout/toolbar_workflow_runs.xml diff --git a/.idea/runConfigurations/github___query_strings.xml b/.idea/runConfigurations/github___bookmarks.xml similarity index 80% rename from .idea/runConfigurations/github___query_strings.xml rename to .idea/runConfigurations/github___bookmarks.xml index b8e4155e..f2a39496 100644 --- a/.idea/runConfigurations/github___query_strings.xml +++ b/.idea/runConfigurations/github___bookmarks.xml @@ -1,5 +1,5 @@ - +