diff --git a/README.md b/README.md index ff446a02..bf5d5d3a8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![License](https://img.shields.io/badge/license-Apache_2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![Circle CI](https://circleci.com/gh/vase4kin/TeamCityApp/tree/master.svg?style=shield)](https://circleci.com/gh/vase4kin/TeamCityApp/tree/master) [![codecov](https://codecov.io/gh/vase4kin/TeamCityApp/branch/master/graph/badge.svg)](https://codecov.io/gh/vase4kin/TeamCityApp) - +[![Release](https://img.shields.io/badge/release-1.2.3-blue.svg)](https://github.com/vase4kin/TeamCityApp/releases/latest) ``` * ) ( ) ( diff --git a/app/build.gradle b/app/build.gradle index ce22239f..cf372593 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,8 +30,8 @@ android { applicationId "com.github.vase4kin.teamcityapp" minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion - versionCode 33 - versionName "1.2.3" + versionCode rootProject.versionCode + versionName rootProject.versionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } @@ -179,6 +179,7 @@ dependencies { compile('com.mikepenz:aboutlibraries:5.9.7@aar') { transitive = true } + compile 'com.github.daniel-stoneuk:material-about-library:2.2.1' // Onboarding compile 'uk.co.samuelwall:material-tap-target-prompt:2.0.0' // Dagger diff --git a/app/src/androidTest/java/com/github/vase4kin/teamcityapp/about/AboutActivityTest.java b/app/src/androidTest/java/com/github/vase4kin/teamcityapp/about/AboutLibrariesActivityTest.java similarity index 85% rename from app/src/androidTest/java/com/github/vase4kin/teamcityapp/about/AboutActivityTest.java rename to app/src/androidTest/java/com/github/vase4kin/teamcityapp/about/AboutLibrariesActivityTest.java index 30a66ba3..9e748708 100644 --- a/app/src/androidTest/java/com/github/vase4kin/teamcityapp/about/AboutActivityTest.java +++ b/app/src/androidTest/java/com/github/vase4kin/teamcityapp/about/AboutLibrariesActivityTest.java @@ -19,6 +19,7 @@ import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; +import com.github.vase4kin.teamcityapp.R; import com.github.vase4kin.teamcityapp.TeamCityApplication; import com.github.vase4kin.teamcityapp.dagger.components.AppComponent; import com.github.vase4kin.teamcityapp.dagger.components.RestApiComponent; @@ -35,10 +36,10 @@ import static com.github.vase4kin.teamcityapp.helper.TestUtils.matchToolbarTitle; /** - * Tests for {@link AboutActivity} + * Tests for {@link AboutLibrariesActivity} */ @RunWith(AndroidJUnit4.class) -public class AboutActivityTest { +public class AboutLibrariesActivityTest { private static final String URL = "http://teamcity.server.com"; @@ -54,11 +55,12 @@ public void setComponent(RestApiComponent restApiComponent) { }); @Rule - public CustomActivityTestRule mActivityTestRule = new CustomActivityTestRule<>(AboutActivity.class); + public CustomActivityTestRule mActivityTestRule = new CustomActivityTestRule<>(AboutLibrariesActivity.class); @Test public void testAboutActivity() throws Exception { mActivityTestRule.launchActivity(null); - matchToolbarTitle("About"); + String toolbarTitle = mActivityTestRule.getActivity().getString(R.string.about_app_text_libraries); + matchToolbarTitle(toolbarTitle); } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1c1553f9..52ffd895 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - @@ -26,8 +25,8 @@ android:allowBackup="true" android:fullBackupContent="true" android:icon="@mipmap/ic_launcher" - android:roundIcon="@mipmap/ic_launcher_round" android:label="@string/app_name" + android:roundIcon="@mipmap/ic_launcher_round" android:theme="@style/AppTheme"> + mDrawerPresenter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_about); + + // Injecting DrawerPresenterImpl to activity + DaggerAboutPageComponent.builder() + .drawerModule(new DrawerModule(this, true, DrawerView.ABOUT)) + .restApiComponent(((TeamCityApplication) getApplication()).getRestApiInjector()) + .build() + .inject(this); + + mDrawerPresenter.onCreate(); + + // About library fragment + Fragment aboutLibrary = new LibsBuilder() + .supportFragment(); + + // Commit fragment to container + getSupportFragmentManager() + .beginTransaction() + .add(R.id.about_library_container, aboutLibrary) + .addToBackStack(null) + .commit(); + } + + @Override + public void onBackPressed() { + mDrawerPresenter.onBackButtonPressed(); + } + + /** + * Start About activity with Flag {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} + */ + public static void start(Activity activity) { + Intent launchIntent = new Intent(activity, AboutLibrariesActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + DrawerActivityStartUtils.startActivity(launchIntent, activity); + } +} diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/about/dagger/AboutPageComponent.java b/app/src/main/java/com/github/vase4kin/teamcityapp/about/dagger/AboutPageComponent.java index ef28113c..c7e12951 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/about/dagger/AboutPageComponent.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/about/dagger/AboutPageComponent.java @@ -17,6 +17,7 @@ package com.github.vase4kin.teamcityapp.about.dagger; import com.github.vase4kin.teamcityapp.about.AboutActivity; +import com.github.vase4kin.teamcityapp.about.AboutLibrariesActivity; import com.github.vase4kin.teamcityapp.dagger.components.RestApiComponent; import com.github.vase4kin.teamcityapp.dagger.scopes.PresenterScope; import com.github.vase4kin.teamcityapp.drawer.dagger.DrawerModule; @@ -27,5 +28,7 @@ @Component(dependencies = RestApiComponent.class, modules = DrawerModule.class) public interface AboutPageComponent { + void inject(AboutLibrariesActivity aboutLibrariesActivity); + void inject(AboutActivity aboutActivity); } diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/account/manage/data/AccountsDataManagerImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/account/manage/data/AccountsDataManagerImpl.java index 655ea78d..13c42b02 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/account/manage/data/AccountsDataManagerImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/account/manage/data/AccountsDataManagerImpl.java @@ -26,6 +26,8 @@ import java.util.List; import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; /** * Impl of {@link BaseListRxDataManagerImpl} for {@link com.github.vase4kin.teamcityapp.account.manage.presenter.AccountsPresenterImpl} @@ -42,7 +44,15 @@ public AccountsDataManagerImpl(SharedUserStorage sharedUserStorage) { * {@inheritDoc} */ @Override - public void load(@NonNull Observable call, @NonNull OnLoadingListener> loadingListener) { - loadingListener.onSuccess(mSharedUserStorage.getObjects()); + public void load(@NonNull Observable call, @NonNull final OnLoadingListener> loadingListener) { + Observable.from(mSharedUserStorage.getObjects()) + .toList() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1>() { + @Override + public void call(List userAccounts) { + loadingListener.onSuccess(userAccounts); + } + }); } } diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/account/manage/view/AccountsViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/account/manage/view/AccountsViewImpl.java index 30e9542b..cb971014 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/account/manage/view/AccountsViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/account/manage/view/AccountsViewImpl.java @@ -23,7 +23,6 @@ import android.support.annotation.StringRes; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.view.ActionMode; import android.view.Menu; import android.view.MenuItem; @@ -51,7 +50,6 @@ import butterknife.BindString; import butterknife.BindView; import butterknife.OnClick; -import tr.xip.errorview.ErrorView; /** * View impl for account @@ -227,9 +225,8 @@ public void setOnAccountRemoveListener(OnAccountRemoveListener onAccountRemoveLi * {@inheritDoc} */ @Override - public void initViews(@NonNull ErrorView.RetryListener retryListener, - @NonNull SwipeRefreshLayout.OnRefreshListener refreshListener) { - super.initViews(retryListener, refreshListener); + public void initViews(@NonNull ViewListener listener) { + super.initViews(listener); //Setting float button icon mButtonFloat.setImageDrawable(new IconDrawable(mActivity, MaterialIcons.md_add).color(Color.WHITE)); diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/agents/presenter/AgentPresenterImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/agents/presenter/AgentPresenterImpl.java index 6008538e..16b5aa10 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/agents/presenter/AgentPresenterImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/agents/presenter/AgentPresenterImpl.java @@ -52,6 +52,12 @@ public class AgentPresenterImpl extends BaseListPresenterImpl< super(view, dataManager, tracker, valueExtractor); } + @Override + protected void initViews() { + super.initViews(); + mView.replaceSkeletonViewContent(); + } + /** * {@inheritDoc} */ diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/agents/view/AgentViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/agents/view/AgentViewImpl.java index 2d96fa04..6f3a8e88 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/agents/view/AgentViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/agents/view/AgentViewImpl.java @@ -51,6 +51,14 @@ public void showData(AgentDataModel dataModel) { mRecyclerView.getAdapter().notifyDataSetChanged(); } + /** + * {@inheritDoc} + */ + @Override + public void replaceSkeletonViewContent() { + replaceSkeletonViewContent(R.layout.layout_skeleton_agent_list); + } + /** * {@inheritDoc} */ diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/artifact/view/ArtifactViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/artifact/view/ArtifactViewImpl.java index 774008b5..c5988071 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/artifact/view/ArtifactViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/artifact/view/ArtifactViewImpl.java @@ -20,7 +20,6 @@ import android.graphics.Color; import android.support.annotation.NonNull; import android.support.annotation.StringRes; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.view.View; @@ -33,8 +32,6 @@ import com.github.vase4kin.teamcityapp.bottomsheet_dialog.BottomSheetDialog; import com.github.vase4kin.teamcityapp.bottomsheet_dialog.menu_items.MenuItemsFactory; -import tr.xip.errorview.ErrorView; - /** * Impl of {@link ArtifactView} */ @@ -64,8 +61,8 @@ public void setOnArtifactPresenterListener(OnArtifactPresenterListener listener) * {@inheritDoc} */ @Override - public void initViews(@NonNull ErrorView.RetryListener retryListener, @NonNull SwipeRefreshLayout.OnRefreshListener refreshListener) { - super.initViews(retryListener, refreshListener); + public void initViews(@NonNull ViewListener listener) { + super.initViews(listener); mProgressDialog = new MaterialDialog.Builder(mActivity) .title(R.string.download_artifact_dialog_title) .content(R.string.progress_dialog_content) diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/presenter/BaseListPresenterImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/presenter/BaseListPresenterImpl.java index 48c1beaa..ac432305 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/presenter/BaseListPresenterImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/presenter/BaseListPresenterImpl.java @@ -17,7 +17,6 @@ package com.github.vase4kin.teamcityapp.base.list.presenter; import android.support.annotation.NonNull; -import android.support.v4.widget.SwipeRefreshLayout; import com.github.vase4kin.teamcityapp.account.create.data.OnLoadingListener; import com.github.vase4kin.teamcityapp.base.api.Jsonable; @@ -30,8 +29,6 @@ import java.util.Collections; import java.util.List; -import tr.xip.errorview.ErrorView; - /** * Base impl of {@link BaseListPresenter} */ @@ -84,7 +81,7 @@ public BaseListPresenterImpl( @Override public void onViewsCreated() { initViews(); - mView.showProgressWheel(); + mView.showSkeletonView(); mView.disableSwipeToRefresh(); loadData(loadingListener, false); } @@ -101,22 +98,19 @@ public void onViewsCreated() { * Init views, register listeners */ protected void initViews() { - ErrorView.RetryListener retryListener = new ErrorView.RetryListener() { + BaseListView.ViewListener listener = new BaseListView.ViewListener() { @Override - public void onRetry() { - mView.showProgressWheel(); - mView.hideErrorView(); - mView.hideEmpty(); - loadData(loadingListener, true); + public void onRefresh() { + onSwipeToRefresh(); } - }; - SwipeRefreshLayout.OnRefreshListener refreshListener = new SwipeRefreshLayout.OnRefreshListener() { + @Override - public void onRefresh() { + public void onRetry() { + mView.showRefreshAnimation(); onSwipeToRefresh(); } }; - mView.initViews(retryListener, refreshListener); + mView.initViews(listener); } /** @@ -181,8 +175,8 @@ protected void onFailCallBack(String errorMessage) { * Base views interaction on server request completion */ private void onCompleteLoading() { - if (mView.isProgressWheelShown()) { - mView.hideProgressWheel(); + if (mView.isSkeletonViewVisible()) { + mView.hideSkeletonView(); } mView.enableSwipeToRefresh(); diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/view/BaseListView.java b/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/view/BaseListView.java index a26f2c69..132ad5c7 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/view/BaseListView.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/view/BaseListView.java @@ -36,23 +36,7 @@ public interface BaseListView { */ int TYPE_LOAD_MORE = 1; - void initViews(@NonNull ErrorView.RetryListener retryListener, - @NonNull SwipeRefreshLayout.OnRefreshListener refreshListener); - - /** - * Show progress loading wheel - */ - void showProgressWheel(); - - /** - * Hide progress loading wheel - */ - void hideProgressWheel(); - - /** - * @return Is progress loading or not - */ - boolean isProgressWheelShown(); + void initViews(@NonNull ViewListener listener); /** * Enable swipe to refresh layout @@ -115,4 +99,27 @@ void initViews(@NonNull ErrorView.RetryListener retryListener, * @param dataModel - Model data */ void showData(T dataModel); + + /** + * Show skeleton view + */ + void showSkeletonView(); + + /** + * Hide skeleton view + */ + void hideSkeletonView(); + + /** + * @return the visibility flag of skeleton view + */ + boolean isSkeletonViewVisible(); + + /** + * Replace skeletonView content + */ + void replaceSkeletonViewContent(); + + interface ViewListener extends ErrorView.RetryListener, SwipeRefreshLayout.OnRefreshListener { + } } diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/view/BaseListViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/view/BaseListViewImpl.java index 21443ce5..a0879059 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/view/BaseListViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/base/list/view/BaseListViewImpl.java @@ -18,16 +18,18 @@ import android.app.Activity; import android.graphics.Color; +import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; import android.support.annotation.StringRes; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.TextView; import com.github.vase4kin.teamcityapp.R; -import com.pnikosis.materialishprogress.ProgressWheel; import butterknife.BindView; import butterknife.ButterKnife; @@ -47,8 +49,8 @@ public abstract class BaseListViewImpl! mRecyclerView.setId(recyclerViewId()); // ! mErrorView.setImageTint(Color.LTGRAY); - mErrorView.setRetryListener(retryListener); + mErrorView.setRetryListener(listener); mEmpty.setText(mEmptyMessage); - mSwipeRefreshLayout.setOnRefreshListener(refreshListener); + mSwipeRefreshLayout.setOnRefreshListener(listener); mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity)); } - /** - * {@inheritDoc} - */ - @Override - public void showProgressWheel() { - mProgressWheel.setVisibility(View.VISIBLE); - } - - /** - * {@inheritDoc} - */ - @Override - public void hideProgressWheel() { - mProgressWheel.setVisibility(View.GONE); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isProgressWheelShown() { - return mProgressWheel.getVisibility() == View.VISIBLE; - } - /** * {@inheritDoc} */ @@ -196,6 +173,46 @@ public void disableRecyclerView() { mRecyclerView.setEnabled(false); } + /** + * {@inheritDoc} + */ + @Override + public void showSkeletonView() { + skeletonView.setVisibility(View.VISIBLE); + } + + /** + * {@inheritDoc} + */ + @Override + public void hideSkeletonView() { + skeletonView.setVisibility(View.GONE); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isSkeletonViewVisible() { + return skeletonView.getVisibility() == View.VISIBLE; + } + + /** + * {@inheritDoc} + */ + @Override + public void replaceSkeletonViewContent() { + + } + + /** + * {@inheritDoc} + */ + protected void replaceSkeletonViewContent(@LayoutRes int layout) { + skeletonView.removeAllViewsInLayout(); + LayoutInflater.from(mActivity).inflate(layout, skeletonView); + } + /** * Provide recycler view id for each view impl to easy determine them by Espresso */ diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/buildlist/presenter/BuildListPresenterImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/buildlist/presenter/BuildListPresenterImpl.java index 35c34c05..1878aa39 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/buildlist/presenter/BuildListPresenterImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/buildlist/presenter/BuildListPresenterImpl.java @@ -190,7 +190,7 @@ public void onFilterBuildsOptionMenuClick() { @Override public void onResetFiltersSnackBarActionClick() { mView.disableSwipeToRefresh(); - mView.showProgressWheel(); + mView.showRefreshAnimation(); mView.hideErrorView(); mView.hideEmpty(); mView.showData(new BuildListDataModelImpl(Collections.emptyList())); @@ -281,7 +281,7 @@ public void onRunBuildActivityResult(String queuedBuildHref) { public void onFilterBuildsActivityResult(BuildListFilter filter) { mView.showBuildFilterAppliedSnackBar(); mView.disableSwipeToRefresh(); - mView.showProgressWheel(); + mView.showRefreshAnimation(); mView.hideErrorView(); mView.hideEmpty(); mView.showData(new BuildListDataModelImpl(Collections.emptyList())); diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/buildlist/view/BuildListViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/buildlist/view/BuildListViewImpl.java index 984f36b2..168ccbbb 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/buildlist/view/BuildListViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/buildlist/view/BuildListViewImpl.java @@ -26,7 +26,6 @@ import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.view.animation.FastOutSlowInInterpolator; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.view.Menu; @@ -51,7 +50,6 @@ import butterknife.BindString; import butterknife.BindView; -import tr.xip.errorview.ErrorView; import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt; /** @@ -88,9 +86,8 @@ public void setOnBuildListPresenterListener(OnBuildListPresenterListener onBuild * {@inheritDoc} */ @Override - public void initViews(@NonNull ErrorView.RetryListener retryListener, - @NonNull SwipeRefreshLayout.OnRefreshListener refreshListener) { - super.initViews(retryListener, refreshListener); + public void initViews(@NonNull ViewListener listener) { + super.initViews(listener); mFloatingActionButton.setImageDrawable(new IconDrawable(mActivity, MaterialIcons.md_directions_run).color(Color.WHITE)); mFloatingActionButton.hide(); mFloatingActionButton.setOnClickListener(new View.OnClickListener() { diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/changes/presenter/ChangesPresenterImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/changes/presenter/ChangesPresenterImpl.java index 6d96aaf9..721405bc 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/changes/presenter/ChangesPresenterImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/changes/presenter/ChangesPresenterImpl.java @@ -94,6 +94,7 @@ public boolean hasLoadedAllItems() { return !mDataManager.canLoadMore(); } }); + mView.replaceSkeletonViewContent(); } /** diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/changes/view/ChangesViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/changes/view/ChangesViewImpl.java index 8cd49853..62e3f30a 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/changes/view/ChangesViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/changes/view/ChangesViewImpl.java @@ -135,6 +135,14 @@ public void onClick(Changes.Change change) { dialog.show(); } + /** + * {@inheritDoc} + */ + @Override + public void replaceSkeletonViewContent() { + replaceSkeletonViewContent(R.layout.layout_skeleton_changes_list); + } + /** * {@inheritDoc} */ diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/drawer/router/DrawerRouter.java b/app/src/main/java/com/github/vase4kin/teamcityapp/drawer/router/DrawerRouter.java index 76d184ca..febea9e8 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/drawer/router/DrawerRouter.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/drawer/router/DrawerRouter.java @@ -16,6 +16,8 @@ package com.github.vase4kin.teamcityapp.drawer.router; +import com.github.vase4kin.teamcityapp.about.AboutLibrariesActivity; + /** * Drawer router */ @@ -52,7 +54,7 @@ public interface DrawerRouter { void startQueuedBuildsActivity(); /** - * Start {@link com.github.vase4kin.teamcityapp.about.AboutActivity} + * Start {@link AboutLibrariesActivity} */ void startAboutActivity(); } diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/drawer/view/DrawerViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/drawer/view/DrawerViewImpl.java index b696bfd4..6e9f0b50 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/drawer/view/DrawerViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/drawer/view/DrawerViewImpl.java @@ -26,7 +26,7 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.github.vase4kin.teamcityapp.R; -import com.github.vase4kin.teamcityapp.about.AboutActivity; +import com.github.vase4kin.teamcityapp.about.AboutLibrariesActivity; import com.github.vase4kin.teamcityapp.agenttabs.view.AgentTabsActivity; import com.github.vase4kin.teamcityapp.drawer.data.DrawerDataModel; import com.github.vase4kin.teamcityapp.queue.view.BuildQueueActivity; @@ -280,7 +280,7 @@ public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { mOnDrawerPresenterListener.startQueuedBuildsActivity(); break; case ABOUT: - if (mActivity instanceof AboutActivity) { + if (mActivity instanceof AboutLibrariesActivity) { break; } mOnDrawerPresenterListener.startAboutActivity(); diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/overview/presenter/OverviewPresenterImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/overview/presenter/OverviewPresenterImpl.java index 3abe48f9..c161fdf7 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/overview/presenter/OverviewPresenterImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/overview/presenter/OverviewPresenterImpl.java @@ -60,7 +60,7 @@ public class OverviewPresenterImpl implements OverviewPresenter, public void onCreate() { mView.initViews(this); mInteractor.setListener(this); - mView.showProgressWheel(); + mView.showSkeletonView(); BuildDetails buildDetails = mInteractor.getBuildDetails(); loadBuildDetails(buildDetails.isRunning()); } @@ -261,7 +261,7 @@ public void onRetry() { @Override public void onSuccess(BuildDetails buildDetails) { mView.hideCards(); - mView.hideProgressWheel(); + mView.hideSkeletonView(); mView.hideRefreshingProgress(); // Status String statusIcon = buildDetails.getStatusIcon(); @@ -344,7 +344,7 @@ public void onSuccess(BuildDetails buildDetails) { @Override public void onFail(String errorMessage) { mView.hideCards(); - mView.hideProgressWheel(); + mView.hideSkeletonView(); mView.hideRefreshingProgress(); mView.showErrorView(); } diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/overview/view/OverviewView.java b/app/src/main/java/com/github/vase4kin/teamcityapp/overview/view/OverviewView.java index b0903842..8d2f9a9e 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/overview/view/OverviewView.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/overview/view/OverviewView.java @@ -35,14 +35,14 @@ public interface OverviewView { void initViews(ViewListener listener); /** - * Show progress loading wheel + * Show skeleton view */ - void showProgressWheel(); + void showSkeletonView(); /** - * Hide progress loading wheel + * Hide skeleton view */ - void hideProgressWheel(); + void hideSkeletonView(); /** * Show refreshing progress diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/overview/view/OverviewViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/overview/view/OverviewViewImpl.java index 27abb6bd..d313d304 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/overview/view/OverviewViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/overview/view/OverviewViewImpl.java @@ -29,10 +29,12 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.view.ViewGroup; import com.github.vase4kin.teamcityapp.R; import com.github.vase4kin.teamcityapp.bottomsheet_dialog.BottomSheetDialog; @@ -40,7 +42,6 @@ import com.github.vase4kin.teamcityapp.navigation.api.BuildElement; import com.github.vase4kin.teamcityapp.onboarding.OnboardingManager; import com.github.vase4kin.teamcityapp.overview.data.OverviewDataModelImpl; -import com.pnikosis.materialishprogress.ProgressWheel; import java.util.ArrayList; import java.util.List; @@ -71,8 +72,8 @@ public class OverviewViewImpl implements OverviewView { RecyclerView mRecyclerView; @BindView(R.id.error_view) ErrorView mErrorView; - @BindView(R.id.progress_wheel) - ProgressWheel mProgressWheel; + @BindView(R.id.skeleton_view) + ViewGroup skeletonView; private Unbinder mUnbinder; @@ -105,6 +106,8 @@ public void initViews(ViewListener listener) { mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity)); // For testing purposes mRecyclerView.setId(R.id.overview_recycler_view); + skeletonView.removeAllViewsInLayout(); + LayoutInflater.from(mActivity).inflate(R.layout.layout_skeleton_overview_list, skeletonView); } /** @@ -132,16 +135,16 @@ public void hideCards() { * {@inheritDoc} */ @Override - public void showProgressWheel() { - mProgressWheel.setVisibility(View.VISIBLE); + public void showSkeletonView() { + skeletonView.setVisibility(View.VISIBLE); } /** * {@inheritDoc} */ @Override - public void hideProgressWheel() { - mProgressWheel.setVisibility(View.GONE); + public void hideSkeletonView() { + skeletonView.setVisibility(View.GONE); } /** diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/properties/data/PropertiesDataManagerImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/properties/data/PropertiesDataManagerImpl.java index dcb5b0db..ce72d5ed 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/properties/data/PropertiesDataManagerImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/properties/data/PropertiesDataManagerImpl.java @@ -26,6 +26,11 @@ import java.util.Collections; import java.util.List; +import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; +import rx.functions.Func1; + /** * Impl of {@link PropertiesDataManager} */ @@ -35,20 +40,31 @@ public class PropertiesDataManagerImpl extends BaseListRxDataManagerImpl> loadingListener) { + public void load(@NonNull final BuildDetails buildDetails, final OnLoadingListener> loadingListener) { // Getting properties from the build Properties properties = buildDetails.getProperties(); - if (properties == null) { - // Return empty collections if properties are empty - Properties emptyProperties = new Properties() { - @Override - public List getObjects() { - return Collections.emptyList(); - } - }; - loadingListener.onSuccess(emptyProperties.getObjects()); - } else { - loadingListener.onSuccess(buildDetails.getProperties().getObjects()); - } + Observable.just(properties) + .flatMap(new Func1>() { + @Override + public Observable call(Properties properties) { + return properties == null + ? Observable.empty() + : Observable.just(properties); + } + }) + .defaultIfEmpty(new Properties(Collections.emptyList())) + .flatMap(new Func1>>() { + @Override + public Observable> call(Properties properties) { + return Observable.from(properties.getObjects()).toList(); + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1>() { + @Override + public void call(List objects) { + loadingListener.onSuccess(objects); + } + }); } } diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/tests/presenter/TestsPresenterImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/tests/presenter/TestsPresenterImpl.java index 6242582c..3b168722 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/tests/presenter/TestsPresenterImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/tests/presenter/TestsPresenterImpl.java @@ -120,6 +120,7 @@ public boolean hasLoadedAllItems() { return !mDataManager.canLoadMore(); } }); + mView.replaceSkeletonViewContent(); } /** @@ -162,7 +163,7 @@ public void onPrepareOptionsMenu(Menu menu) { */ @Override public boolean onOptionsItemSelected(MenuItem item) { - mView.showProgressWheel(); + mView.showRefreshAnimation(); mView.hideErrorView(); mView.hideEmpty(); mView.showData(new TestsDataModelImpl(Collections.emptyList())); diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/tests/view/TestsViewImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/tests/view/TestsViewImpl.java index 76c3d786..076fe71e 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/tests/view/TestsViewImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/tests/view/TestsViewImpl.java @@ -279,6 +279,14 @@ public void onClick(View v) { snackBar.show(); } + /** + * {@inheritDoc} + */ + @Override + public void replaceSkeletonViewContent() { + replaceSkeletonViewContent(R.layout.layout_skeleton_agent_list); + } + /** * {@inheritDoc} */ diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 38b413cf..53467e5d 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -14,18 +14,31 @@ ~ limitations under the License. --> - + tools:context=".about.AboutLibrariesActivity"> - + + + + + + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> - + diff --git a/app/src/main/res/layout/activity_account_list.xml b/app/src/main/res/layout/activity_account_list.xml index ea41949e..a21bb3cb 100644 --- a/app/src/main/res/layout/activity_account_list.xml +++ b/app/src/main/res/layout/activity_account_list.xml @@ -15,20 +15,55 @@ --> - + + + + + + + android:layout_height="wrap_content" + android:background="@color/md_white_1000" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + + + + + + + + + - + - + - + diff --git a/app/src/main/res/layout/activity_agent_tabs.xml b/app/src/main/res/layout/activity_agent_tabs.xml index ef42adc8..9c57473d 100644 --- a/app/src/main/res/layout/activity_agent_tabs.xml +++ b/app/src/main/res/layout/activity_agent_tabs.xml @@ -14,15 +14,42 @@ ~ limitations under the License. --> - - + - + - + + + + + + + + diff --git a/app/src/main/res/layout/activity_build.xml b/app/src/main/res/layout/activity_build.xml index 5d441ac5..506fff5c 100644 --- a/app/src/main/res/layout/activity_build.xml +++ b/app/src/main/res/layout/activity_build.xml @@ -16,22 +16,40 @@ - + android:layout_height="wrap_content"> + + - + - + - + - + + + + + + + android:layout_height="wrap_content" + android:background="@color/md_white_1000" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + + + + + + + + + - + - + - + - + android:animateLayoutChanges="true"> - + - + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_root_projects_list.xml b/app/src/main/res/layout/activity_root_projects_list.xml index 7086846d..51e4b9f0 100644 --- a/app/src/main/res/layout/activity_root_projects_list.xml +++ b/app/src/main/res/layout/activity_root_projects_list.xml @@ -14,18 +14,31 @@ ~ limitations under the License. --> - + android:animateLayoutChanges="true"> - + + + + + + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_list.xml b/app/src/main/res/layout/fragment_list.xml index 9aa0477a..de56d056 100644 --- a/app/src/main/res/layout/fragment_list.xml +++ b/app/src/main/res/layout/fragment_list.xml @@ -36,16 +36,20 @@ - + + + + + android:layout_height="wrap_content" + android:visibility="gone"> - + - + diff --git a/app/src/main/res/layout/layout_empty.xml b/app/src/main/res/layout/layout_empty.xml new file mode 100644 index 00000000..d31bb117 --- /dev/null +++ b/app/src/main/res/layout/layout_empty.xml @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_agent_item.xml b/app/src/main/res/layout/layout_skeleton_agent_item.xml new file mode 100644 index 00000000..5719b741 --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_agent_item.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_agent_list.xml b/app/src/main/res/layout/layout_skeleton_agent_list.xml new file mode 100644 index 00000000..682214f9 --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_agent_list.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_build_list.xml b/app/src/main/res/layout/layout_skeleton_build_list.xml new file mode 100644 index 00000000..de37bcb3 --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_build_list.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_build_list_item.xml b/app/src/main/res/layout/layout_skeleton_build_list_item.xml new file mode 100644 index 00000000..74f81f13 --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_build_list_item.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_change_list_item.xml b/app/src/main/res/layout/layout_skeleton_change_list_item.xml new file mode 100644 index 00000000..6ff56430 --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_change_list_item.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_changes_list.xml b/app/src/main/res/layout/layout_skeleton_changes_list.xml new file mode 100644 index 00000000..f73f8b56 --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_changes_list.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_navigation_list.xml b/app/src/main/res/layout/layout_skeleton_navigation_list.xml new file mode 100644 index 00000000..89481acc --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_navigation_list.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_overview_item.xml b/app/src/main/res/layout/layout_skeleton_overview_item.xml new file mode 100644 index 00000000..a3a7f27b --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_overview_item.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_overview_list.xml b/app/src/main/res/layout/layout_skeleton_overview_list.xml new file mode 100644 index 00000000..764fbc6b --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_overview_list.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_skeleton_project_item.xml b/app/src/main/res/layout/layout_skeleton_project_item.xml new file mode 100644 index 00000000..b23caaae --- /dev/null +++ b/app/src/main/res/layout/layout_skeleton_project_item.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c56a8381..88e3e13d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,6 +43,7 @@ @string/running_builds_drawer_item @string/build_queue_drawer_item @string/about_drawer_item + Libraries Overview @@ -178,15 +179,21 @@ Navigate up - - TeamCity in your pocket
- Source Code
- Contacts:
- Email
- Telegram
- ]]> -
+ Rate the app + Found an issue? + Or want to suggest an improvement? + https://github.com/vase4kin/TeamCityApp/issues + Source code + https://github.com/vase4kin/TeamCityApp + Libraries + Contacts + Github + https://github.com/vase4kin + Telegram + https://telegram.me/vase4kin + Email + andrey.tolpeev@gmail.com + Questions about TeamCityApp In order to view build log please login diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 9c97602b..db4a1308 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -23,6 +23,12 @@ @drawable/splash_background + +